xref: /petsc/src/dm/dt/interface/dtds.c (revision a8f51744601f91dc30d5f98153b1ecd91eebb0e5)
1af0996ceSBarry Smith #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/
22764a2aaSMatthew G. Knepley 
32764a2aaSMatthew G. Knepley PetscClassId PETSCDS_CLASSID = 0;
42764a2aaSMatthew G. Knepley 
52764a2aaSMatthew G. Knepley PetscFunctionList PetscDSList              = NULL;
62764a2aaSMatthew G. Knepley PetscBool         PetscDSRegisterAllCalled = PETSC_FALSE;
72764a2aaSMatthew G. Knepley 
894dcdc3fSMatthew G. Knepley /* A PetscDS (Discrete System) encodes a set of equations posed in a discrete space, which represents a set of
994dcdc3fSMatthew G. Knepley    nonlinear continuum equations. The equations can have multiple fields, each field having a different
1094dcdc3fSMatthew G. Knepley    discretization. In addition, different pieces of the domain can have different field combinations and equations.
1194dcdc3fSMatthew G. Knepley 
1294dcdc3fSMatthew G. Knepley    The DS provides the user a description of the approximation space on any given cell. It also gives pointwise
1394dcdc3fSMatthew G. Knepley    functions representing the equations.
1494dcdc3fSMatthew G. Knepley 
1594dcdc3fSMatthew G. Knepley    Each field is associated with a label, marking the cells on which it is supported. Note that a field can be
1694dcdc3fSMatthew G. Knepley    supported on the closure of a cell not in the label due to overlap of the boundary of neighboring cells. The DM
1794dcdc3fSMatthew G. Knepley    then creates a DS for each set of cells with identical approximation spaces. When assembling, the user asks for
1894dcdc3fSMatthew G. Knepley    the space associated with a given cell. DMPlex uses the labels associated with each DS in the default integration loop.
1994dcdc3fSMatthew G. Knepley */
2094dcdc3fSMatthew G. Knepley 
212764a2aaSMatthew G. Knepley /*@C
22dce8aebaSBarry Smith   PetscDSRegister - Adds a new `PetscDS` implementation
232764a2aaSMatthew G. Knepley 
2420f4b53cSBarry Smith   Not Collective; No Fortran Support
252764a2aaSMatthew G. Knepley 
262764a2aaSMatthew G. Knepley   Input Parameters:
2720f4b53cSBarry Smith + sname    - The name of a new user-defined creation routine
2820f4b53cSBarry Smith - function - The creation routine itself
292764a2aaSMatthew G. Knepley 
3060225df5SJacob Faibussowitsch   Example Usage:
312764a2aaSMatthew G. Knepley .vb
322764a2aaSMatthew G. Knepley     PetscDSRegister("my_ds", MyPetscDSCreate);
332764a2aaSMatthew G. Knepley .ve
342764a2aaSMatthew G. Knepley 
352764a2aaSMatthew G. Knepley   Then, your PetscDS type can be chosen with the procedural interface via
362764a2aaSMatthew G. Knepley .vb
372764a2aaSMatthew G. Knepley     PetscDSCreate(MPI_Comm, PetscDS *);
382764a2aaSMatthew G. Knepley     PetscDSSetType(PetscDS, "my_ds");
392764a2aaSMatthew G. Knepley .ve
402764a2aaSMatthew G. Knepley   or at runtime via the option
412764a2aaSMatthew G. Knepley .vb
422764a2aaSMatthew G. Knepley     -petscds_type my_ds
432764a2aaSMatthew G. Knepley .ve
442764a2aaSMatthew G. Knepley 
452764a2aaSMatthew G. Knepley   Level: advanced
462764a2aaSMatthew G. Knepley 
47dce8aebaSBarry Smith   Note:
48dce8aebaSBarry Smith   `PetscDSRegister()` may be called multiple times to add several user-defined `PetscDSs`
49dce8aebaSBarry Smith 
50dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSRegisterAll()`, `PetscDSRegisterDestroy()`
512764a2aaSMatthew G. Knepley @*/
52d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
53d71ae5a4SJacob Faibussowitsch {
542764a2aaSMatthew G. Knepley   PetscFunctionBegin;
559566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscDSList, sname, function));
563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
572764a2aaSMatthew G. Knepley }
582764a2aaSMatthew G. Knepley 
592764a2aaSMatthew G. Knepley /*@C
60dce8aebaSBarry Smith   PetscDSSetType - Builds a particular `PetscDS`
612764a2aaSMatthew G. Knepley 
6220f4b53cSBarry Smith   Collective; No Fortran Support
632764a2aaSMatthew G. Knepley 
642764a2aaSMatthew G. Knepley   Input Parameters:
65dce8aebaSBarry Smith + prob - The `PetscDS` object
66dce8aebaSBarry Smith - name - The `PetscDSType`
672764a2aaSMatthew G. Knepley 
682764a2aaSMatthew G. Knepley   Options Database Key:
692764a2aaSMatthew G. Knepley . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
702764a2aaSMatthew G. Knepley 
712764a2aaSMatthew G. Knepley   Level: intermediate
722764a2aaSMatthew G. Knepley 
73dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSGetType()`, `PetscDSCreate()`
742764a2aaSMatthew G. Knepley @*/
75d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
76d71ae5a4SJacob Faibussowitsch {
772764a2aaSMatthew G. Knepley   PetscErrorCode (*r)(PetscDS);
782764a2aaSMatthew G. Knepley   PetscBool match;
792764a2aaSMatthew G. Knepley 
802764a2aaSMatthew G. Knepley   PetscFunctionBegin;
812764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)prob, name, &match));
833ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
842764a2aaSMatthew G. Knepley 
859566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
869566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscDSList, name, &r));
8728b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
882764a2aaSMatthew G. Knepley 
89dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, destroy);
902764a2aaSMatthew G. Knepley   prob->ops->destroy = NULL;
91dbbe0bcdSBarry Smith 
929566063dSJacob Faibussowitsch   PetscCall((*r)(prob));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)prob, name));
943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
952764a2aaSMatthew G. Knepley }
962764a2aaSMatthew G. Knepley 
972764a2aaSMatthew G. Knepley /*@C
98dce8aebaSBarry Smith   PetscDSGetType - Gets the `PetscDSType` name (as a string) from the `PetscDS`
992764a2aaSMatthew G. Knepley 
10020f4b53cSBarry Smith   Not Collective; No Fortran Support
1012764a2aaSMatthew G. Knepley 
1022764a2aaSMatthew G. Knepley   Input Parameter:
103dce8aebaSBarry Smith . prob - The `PetscDS`
1042764a2aaSMatthew G. Knepley 
1052764a2aaSMatthew G. Knepley   Output Parameter:
106dce8aebaSBarry Smith . name - The `PetscDSType` name
1072764a2aaSMatthew G. Knepley 
1082764a2aaSMatthew G. Knepley   Level: intermediate
1092764a2aaSMatthew G. Knepley 
110dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSSetType()`, `PetscDSCreate()`
1112764a2aaSMatthew G. Knepley @*/
112d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
113d71ae5a4SJacob Faibussowitsch {
1142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
1152764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
116c959eef4SJed Brown   PetscValidPointer(name, 2);
1179566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
1182764a2aaSMatthew G. Knepley   *name = ((PetscObject)prob)->type_name;
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1202764a2aaSMatthew G. Knepley }
1212764a2aaSMatthew G. Knepley 
122d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
123d71ae5a4SJacob Faibussowitsch {
1247d8a60eaSMatthew G. Knepley   PetscViewerFormat  format;
12597b6e6e8SMatthew G. Knepley   const PetscScalar *constants;
1265fedec97SMatthew G. Knepley   PetscInt           Nf, numConstants, f;
1277d8a60eaSMatthew G. Knepley 
1287d8a60eaSMatthew G. Knepley   PetscFunctionBegin;
1299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
1309566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Discrete System with %" PetscInt_FMT " fields\n", Nf));
1329566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
13363a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  cell total dim %" PetscInt_FMT " total comp %" PetscInt_FMT "\n", ds->totDim, ds->totComp));
1349566063dSJacob Faibussowitsch   if (ds->isCohesive) PetscCall(PetscViewerASCIIPrintf(viewer, "  cohesive cell\n"));
1355fedec97SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
13640967b3bSMatthew G. Knepley     DSBoundary      b;
1377d8a60eaSMatthew G. Knepley     PetscObject     obj;
1387d8a60eaSMatthew G. Knepley     PetscClassId    id;
139f35450b9SMatthew G. Knepley     PetscQuadrature q;
1407d8a60eaSMatthew G. Knepley     const char     *name;
141f35450b9SMatthew G. Knepley     PetscInt        Nc, Nq, Nqc;
1427d8a60eaSMatthew G. Knepley 
1439566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(ds, f, &obj));
1449566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
1459566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName(obj, &name));
1469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>"));
1479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1487d8a60eaSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
1499566063dSJacob Faibussowitsch       PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc));
1509566063dSJacob Faibussowitsch       PetscCall(PetscFEGetQuadrature((PetscFE)obj, &q));
1519566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FEM"));
1527d8a60eaSMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
1539566063dSJacob Faibussowitsch       PetscCall(PetscFVGetNumComponents((PetscFV)obj, &Nc));
1549566063dSJacob Faibussowitsch       PetscCall(PetscFVGetQuadrature((PetscFV)obj, &q));
1559566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FVM"));
1569371c9d4SSatish Balay     } else SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
15763a3b9bcSJacob Faibussowitsch     if (Nc > 1) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " components", Nc));
15863a3b9bcSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " component ", Nc));
1599566063dSJacob Faibussowitsch     if (ds->implicit[f]) PetscCall(PetscViewerASCIIPrintf(viewer, " (implicit)"));
1609566063dSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " (explicit)"));
1613e60c2a6SMatthew G. Knepley     if (q) {
1629566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL));
16363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " (Nq %" PetscInt_FMT " Nqc %" PetscInt_FMT ")", Nq, Nqc));
1643e60c2a6SMatthew G. Knepley     }
16563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "-jet", ds->jetDegree[f]));
1669566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1679566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1689566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
1699566063dSJacob Faibussowitsch     if (id == PETSCFE_CLASSID) PetscCall(PetscFEView((PetscFE)obj, viewer));
1709566063dSJacob Faibussowitsch     else if (id == PETSCFV_CLASSID) PetscCall(PetscFVView((PetscFV)obj, viewer));
1719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
17240967b3bSMatthew G. Knepley 
1735fedec97SMatthew G. Knepley     for (b = ds->boundary; b; b = b->next) {
17406ad1575SMatthew G. Knepley       char    *name;
17540967b3bSMatthew G. Knepley       PetscInt c, i;
17640967b3bSMatthew G. Knepley 
17740967b3bSMatthew G. Knepley       if (b->field != f) continue;
1789566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]));
18045480ffeSMatthew G. Knepley       if (!b->Nc) {
1819566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  all components\n"));
18240967b3bSMatthew G. Knepley       } else {
1839566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  components: "));
1849566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
18545480ffeSMatthew G. Knepley         for (c = 0; c < b->Nc; ++c) {
1869566063dSJacob Faibussowitsch           if (c > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
18763a3b9bcSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->comps[c]));
18840967b3bSMatthew G. Knepley         }
1899566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1909566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
19140967b3bSMatthew G. Knepley       }
1929566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  values: "));
1939566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
19445480ffeSMatthew G. Knepley       for (i = 0; i < b->Nv; ++i) {
1959566063dSJacob Faibussowitsch         if (i > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
19663a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->values[i]));
19740967b3bSMatthew G. Knepley       }
1989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20015943bb8SPierre Jolivet #if defined(__clang__)
201*a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic")
20215943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
203*a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat")
20415943bb8SPierre Jolivet #endif
2058e0d8d9cSMatthew G. Knepley       if (b->func) {
2069566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func, &name));
2079566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %s\n", name));
2089566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func));
2099566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2108e0d8d9cSMatthew G. Knepley       }
2118e0d8d9cSMatthew G. Knepley       if (b->func_t) {
2129566063dSJacob Faibussowitsch         PetscCall(PetscDLAddr(b->func_t, &name));
2139566063dSJacob Faibussowitsch         if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name));
2149566063dSJacob Faibussowitsch         else PetscCall(PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t));
2159566063dSJacob Faibussowitsch         PetscCall(PetscFree(name));
2168e0d8d9cSMatthew G. Knepley       }
217*a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END()
2189566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2199566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
22040967b3bSMatthew G. Knepley     }
2217d8a60eaSMatthew G. Knepley   }
2229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
22397b6e6e8SMatthew G. Knepley   if (numConstants) {
22463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2269566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
22897b6e6e8SMatthew G. Knepley   }
2299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2327d8a60eaSMatthew G. Knepley }
2337d8a60eaSMatthew G. Knepley 
2342764a2aaSMatthew G. Knepley /*@C
235dce8aebaSBarry Smith   PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
236fe2efc57SMark 
23720f4b53cSBarry Smith   Collective
238fe2efc57SMark 
239fe2efc57SMark   Input Parameters:
240dce8aebaSBarry Smith + A    - the `PetscDS` object
24120f4b53cSBarry Smith . obj  - Optional object that provides the options prefix used in the search
242736c3998SJose E. Roman - name - command line option
243fe2efc57SMark 
244fe2efc57SMark   Level: intermediate
245dce8aebaSBarry Smith 
246dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
247fe2efc57SMark @*/
248d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
249d71ae5a4SJacob Faibussowitsch {
250fe2efc57SMark   PetscFunctionBegin;
251fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2529566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
254fe2efc57SMark }
255fe2efc57SMark 
256fe2efc57SMark /*@C
257dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2582764a2aaSMatthew G. Knepley 
25920f4b53cSBarry Smith   Collective
2602764a2aaSMatthew G. Knepley 
261d8d19677SJose E. Roman   Input Parameters:
262dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2632764a2aaSMatthew G. Knepley - v    - the viewer
2642764a2aaSMatthew G. Knepley 
2652764a2aaSMatthew G. Knepley   Level: developer
2662764a2aaSMatthew G. Knepley 
26720f4b53cSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`, `PetscDSViewFromOptions()`
2682764a2aaSMatthew G. Knepley @*/
269d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
270d71ae5a4SJacob Faibussowitsch {
2717d8a60eaSMatthew G. Knepley   PetscBool iascii;
2722764a2aaSMatthew G. Knepley 
2732764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2742764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2759566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
276ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2789566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
279dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2812764a2aaSMatthew G. Knepley }
2822764a2aaSMatthew G. Knepley 
2832764a2aaSMatthew G. Knepley /*@
284dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2852764a2aaSMatthew G. Knepley 
28620f4b53cSBarry Smith   Collective
2872764a2aaSMatthew G. Knepley 
2882764a2aaSMatthew G. Knepley   Input Parameter:
289dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2902764a2aaSMatthew G. Knepley 
291dce8aebaSBarry Smith   Options Database Keys:
292dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
293dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
294147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
295147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
296147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
2972764a2aaSMatthew G. Knepley 
298dce8aebaSBarry Smith   Level: intermediate
2992764a2aaSMatthew G. Knepley 
300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3012764a2aaSMatthew G. Knepley @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
303d71ae5a4SJacob Faibussowitsch {
304f1fd5e65SToby Isaac   DSBoundary  b;
3052764a2aaSMatthew G. Knepley   const char *defaultType;
3062764a2aaSMatthew G. Knepley   char        name[256];
3072764a2aaSMatthew G. Knepley   PetscBool   flg;
3082764a2aaSMatthew G. Knepley 
3092764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3102764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3112764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3122764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3132764a2aaSMatthew G. Knepley   } else {
3142764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3152764a2aaSMatthew G. Knepley   }
3169566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3172764a2aaSMatthew G. Knepley 
318d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
319f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
320f1fd5e65SToby Isaac     char      optname[1024];
321f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
322f1fd5e65SToby Isaac     PetscBool flg;
323f1fd5e65SToby Isaac 
3249566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3259566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
327f1fd5e65SToby Isaac     if (flg) {
32845480ffeSMatthew G. Knepley       b->Nv = len;
3299566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3309566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3319566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3329566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
333f1fd5e65SToby Isaac     }
334e7b0402cSSander Arens     len = 1024;
3359566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3369566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
338f1fd5e65SToby Isaac     if (flg) {
33945480ffeSMatthew G. Knepley       b->Nc = len;
3409566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3419566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3429566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
343f1fd5e65SToby Isaac     }
344f1fd5e65SToby Isaac   }
3459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3462764a2aaSMatthew G. Knepley   if (flg) {
3479566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3482764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3499566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3502764a2aaSMatthew G. Knepley   }
3519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
35212fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
353dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3542764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
355dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
356d0609cedSBarry Smith   PetscOptionsEnd();
3579566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3592764a2aaSMatthew G. Knepley }
3602764a2aaSMatthew G. Knepley 
3612764a2aaSMatthew G. Knepley /*@C
362dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3632764a2aaSMatthew G. Knepley 
36420f4b53cSBarry Smith   Collective
3652764a2aaSMatthew G. Knepley 
3662764a2aaSMatthew G. Knepley   Input Parameter:
367dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3682764a2aaSMatthew G. Knepley 
3692764a2aaSMatthew G. Knepley   Level: developer
3702764a2aaSMatthew G. Knepley 
371dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3722764a2aaSMatthew G. Knepley @*/
373d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
374d71ae5a4SJacob Faibussowitsch {
3752764a2aaSMatthew G. Knepley   const PetscInt Nf          = prob->Nf;
376f9244615SMatthew G. Knepley   PetscBool      hasH        = PETSC_FALSE;
37707218a29SMatthew G. Knepley   PetscInt       maxOrder[4] = {-1, -1, -1, -1};
3784bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3792764a2aaSMatthew G. Knepley 
3802764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3812764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3823ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3832764a2aaSMatthew G. Knepley   /* Calculate sizes */
3849566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3859566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
386f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3879566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3889566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3899566063dSJacob 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]));
3909566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
39112fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
39207218a29SMatthew G. Knepley     // Note: This assumes we have one kind of cell at each dimension.
39307218a29SMatthew G. Knepley     //       We can fix this by having quadrature hold the celltype
39407218a29SMatthew G. Knepley     PetscQuadrature maxQuad[4] = {NULL, NULL, NULL, NULL};
39512fc5b22SMatthew G. Knepley 
39612fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
39712fc5b22SMatthew G. Knepley       PetscObject     obj;
39812fc5b22SMatthew G. Knepley       PetscClassId    id;
39912fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
40007218a29SMatthew G. Knepley       PetscInt        dim = -1, order = -1, forder = -1;
40112fc5b22SMatthew G. Knepley 
40212fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40312fc5b22SMatthew G. Knepley       if (!obj) continue;
40412fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
40512fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
40612fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
40712fc5b22SMatthew G. Knepley 
40812fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
40912fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
41012fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
41112fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
41212fc5b22SMatthew G. Knepley 
41312fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
41412fc5b22SMatthew G. Knepley       }
41507218a29SMatthew G. Knepley       if (q) {
41607218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
41707218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(q, &order));
41807218a29SMatthew G. Knepley         if (order > maxOrder[dim]) {
41907218a29SMatthew G. Knepley           maxOrder[dim] = order;
42007218a29SMatthew G. Knepley           maxQuad[dim]  = q;
42112fc5b22SMatthew G. Knepley         }
42207218a29SMatthew G. Knepley       }
42307218a29SMatthew G. Knepley       if (fq) {
42407218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
42507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(fq, &forder));
42607218a29SMatthew G. Knepley         if (forder > maxOrder[dim]) {
42707218a29SMatthew G. Knepley           maxOrder[dim] = forder;
42807218a29SMatthew G. Knepley           maxQuad[dim]  = fq;
42907218a29SMatthew G. Knepley         }
43012fc5b22SMatthew G. Knepley       }
43112fc5b22SMatthew G. Knepley     }
43212fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
43312fc5b22SMatthew G. Knepley       PetscObject     obj;
43412fc5b22SMatthew G. Knepley       PetscClassId    id;
43507218a29SMatthew G. Knepley       PetscQuadrature q;
43607218a29SMatthew G. Knepley       PetscInt        dim;
43712fc5b22SMatthew G. Knepley 
43812fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
43912fc5b22SMatthew G. Knepley       if (!obj) continue;
44012fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
44112fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
44212fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
44312fc5b22SMatthew G. Knepley 
44407218a29SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
44507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
44607218a29SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, maxQuad[dim]));
447aa9788aaSMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, dim ? maxQuad[dim - 1] : NULL));
44812fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
44912fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
45012fc5b22SMatthew G. Knepley 
45107218a29SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
45207218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
45307218a29SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, maxQuad[dim]));
45412fc5b22SMatthew G. Knepley       }
45512fc5b22SMatthew G. Knepley     }
45612fc5b22SMatthew G. Knepley   }
4572764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4589de99aefSMatthew G. Knepley     PetscObject     obj;
4599de99aefSMatthew G. Knepley     PetscClassId    id;
460665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4619de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4622764a2aaSMatthew G. Knepley 
4639566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
464f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
465665f567fSMatthew G. Knepley     if (!obj) {
466665f567fSMatthew G. Knepley       /* Empty mesh */
467665f567fSMatthew G. Knepley       Nb = Nc    = 0;
468665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
469665f567fSMatthew G. Knepley     } else {
4709566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4719de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4729de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4739de99aefSMatthew G. Knepley 
4749566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
47549ae0b56SMatthew G. Knepley         {
47649ae0b56SMatthew G. Knepley           PetscQuadrature fq;
47707218a29SMatthew G. Knepley           PetscInt        dim, order;
47849ae0b56SMatthew G. Knepley 
47907218a29SMatthew G. Knepley           PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
48049ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
48107218a29SMatthew G. Knepley           if (maxOrder[dim] < 0) maxOrder[dim] = order;
48207218a29SMatthew 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]);
48349ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
48449ae0b56SMatthew G. Knepley           if (fq) {
48507218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
48607218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &order));
48707218a29SMatthew G. Knepley             if (maxOrder[dim] < 0) maxOrder[dim] = order;
48807218a29SMatthew 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]);
48949ae0b56SMatthew G. Knepley           }
49049ae0b56SMatthew G. Knepley         }
4919566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4929566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4939566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4949566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4959de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4969de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4979de99aefSMatthew G. Knepley 
4989566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4999566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
5009c3cf19fSMatthew G. Knepley         Nb = Nc;
5019566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
5024d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
50363a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
504665f567fSMatthew G. Knepley     }
50547e57110SSander Arens     prob->Nc[f]                    = Nc;
50647e57110SSander Arens     prob->Nb[f]                    = Nb;
507194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
508194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
5099ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
5109ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
5119ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5129ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5139ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5149ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5159566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5162764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5174bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5182764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5199c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5202764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5215fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5225fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5232764a2aaSMatthew G. Knepley   }
5249ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5259ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5262764a2aaSMatthew G. Knepley   /* Allocate works space */
5275fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(NsMax * prob->totComp, &prob->u, NsMax * prob->totComp, &prob->u_t, NsMax * prob->totComp * dimEmbed + (hasH ? NsMax * prob->totComp * dimEmbed * dimEmbed : 0), &prob->u_x));
5299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5309371c9d4SSatish Balay   PetscCall(PetscMalloc6(NsMax * NqMax * NcMax, &prob->f0, NsMax * NqMax * NcMax * dimEmbed, &prob->f1, NsMax * NsMax * NqMax * NcMax * NcMax, &prob->g0, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed, &prob->g1, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed,
5319371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
532dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5332764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5352764a2aaSMatthew G. Knepley }
5362764a2aaSMatthew G. Knepley 
537d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
538d71ae5a4SJacob Faibussowitsch {
5392764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5409566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5419566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5429566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5439566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5449566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5459566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5469566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5482764a2aaSMatthew G. Knepley }
5492764a2aaSMatthew G. Knepley 
550d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
551d71ae5a4SJacob Faibussowitsch {
552f744cafaSSander Arens   PetscObject          *tmpd;
55334aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
554f9244615SMatthew G. Knepley   PetscInt             *tmpk;
5555fedec97SMatthew G. Knepley   PetscBool            *tmpc;
5566528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
557f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
558f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
5590c2f2876SMatthew G. Knepley   void                **tmpctx;
56034aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
5612764a2aaSMatthew G. Knepley 
5622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5633ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5642764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5659566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5669566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5679371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5689371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5699371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5709371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5719371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5729371c9d4SSatish Balay   }
5739371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5749371c9d4SSatish Balay     tmpd[f] = NULL;
5759371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5769371c9d4SSatish Balay     tmpk[f] = 1;
5779371c9d4SSatish Balay   }
5789566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5802764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5812764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
582249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5835fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
584f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5859566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58632d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5870c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58832d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5890c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5909566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
59132d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5920c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5939566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
594c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59595cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
596f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
597f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
598c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
59995cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
600f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
601f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
6029566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
603c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
60495cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
605f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
606f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
6073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6082764a2aaSMatthew G. Knepley }
6092764a2aaSMatthew G. Knepley 
6102764a2aaSMatthew G. Knepley /*@
61120f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6122764a2aaSMatthew G. Knepley 
61320f4b53cSBarry Smith   Collective
6142764a2aaSMatthew G. Knepley 
6152764a2aaSMatthew G. Knepley   Input Parameter:
61660225df5SJacob Faibussowitsch . ds - the `PetscDS` object to destroy
6172764a2aaSMatthew G. Knepley 
6182764a2aaSMatthew G. Knepley   Level: developer
6192764a2aaSMatthew G. Knepley 
620dce8aebaSBarry Smith .seealso: `PetscDSView()`
6212764a2aaSMatthew G. Knepley @*/
622d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
623d71ae5a4SJacob Faibussowitsch {
6242764a2aaSMatthew G. Knepley   PetscInt f;
6252764a2aaSMatthew G. Knepley 
6262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6273ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
6286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
6292764a2aaSMatthew G. Knepley 
6309371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
6319371c9d4SSatish Balay     *ds = NULL;
6323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6339371c9d4SSatish Balay   }
6346528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
6356528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
636df3a45bdSMatthew G. Knepley     PetscInt dim, d;
637df3a45bdSMatthew G. Knepley 
6389566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6399566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
640df3a45bdSMatthew G. Knepley   }
6419566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6429566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
64348a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6449566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6469566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6479566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
648dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
6499566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6509566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6514366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
6524366bac7SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangments((DMPolytopeType)c);
6534366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6544366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6554366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6564366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6574366bac7SMatthew G. Knepley   }
6589566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6602764a2aaSMatthew G. Knepley }
6612764a2aaSMatthew G. Knepley 
6622764a2aaSMatthew G. Knepley /*@
663dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6642764a2aaSMatthew G. Knepley 
665d083f849SBarry Smith   Collective
6662764a2aaSMatthew G. Knepley 
6672764a2aaSMatthew G. Knepley   Input Parameter:
668dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6692764a2aaSMatthew G. Knepley 
6702764a2aaSMatthew G. Knepley   Output Parameter:
671dce8aebaSBarry Smith . ds - The `PetscDS` object
6722764a2aaSMatthew G. Knepley 
6732764a2aaSMatthew G. Knepley   Level: beginner
6742764a2aaSMatthew G. Knepley 
675dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6762764a2aaSMatthew G. Knepley @*/
677d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
678d71ae5a4SJacob Faibussowitsch {
6792764a2aaSMatthew G. Knepley   PetscDS p;
6802764a2aaSMatthew G. Knepley 
6812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6826528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
6836528b96dSMatthew G. Knepley   *ds = NULL;
6849566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6852764a2aaSMatthew G. Knepley 
6869566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6872764a2aaSMatthew G. Knepley 
6882764a2aaSMatthew G. Knepley   p->Nf           = 0;
6892764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
69097b6e6e8SMatthew G. Knepley   p->numConstants = 0;
69197b6e6e8SMatthew G. Knepley   p->constants    = NULL;
692a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
69355c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
69412fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6964366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
6972764a2aaSMatthew G. Knepley 
6986528b96dSMatthew G. Knepley   *ds = p;
6993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7002764a2aaSMatthew G. Knepley }
7012764a2aaSMatthew G. Knepley 
702bc4ae4beSMatthew G. Knepley /*@
703dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
704bc4ae4beSMatthew G. Knepley 
70520f4b53cSBarry Smith   Not Collective
706bc4ae4beSMatthew G. Knepley 
707bc4ae4beSMatthew G. Knepley   Input Parameter:
70820f4b53cSBarry Smith . prob - The `PetscDS` object
709bc4ae4beSMatthew G. Knepley 
710bc4ae4beSMatthew G. Knepley   Output Parameter:
711bc4ae4beSMatthew G. Knepley . Nf - The number of fields
712bc4ae4beSMatthew G. Knepley 
713bc4ae4beSMatthew G. Knepley   Level: beginner
714bc4ae4beSMatthew G. Knepley 
715dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
716bc4ae4beSMatthew G. Knepley @*/
717d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
718d71ae5a4SJacob Faibussowitsch {
7192764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7202764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
721dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
7222764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7242764a2aaSMatthew G. Knepley }
7252764a2aaSMatthew G. Knepley 
726bc4ae4beSMatthew G. Knepley /*@
727dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
728bc4ae4beSMatthew G. Knepley 
72920f4b53cSBarry Smith   Not Collective
730bc4ae4beSMatthew G. Knepley 
731bc4ae4beSMatthew G. Knepley   Input Parameter:
732dce8aebaSBarry Smith . prob - The `PetscDS` object
733bc4ae4beSMatthew G. Knepley 
734bc4ae4beSMatthew G. Knepley   Output Parameter:
735bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
736bc4ae4beSMatthew G. Knepley 
737bc4ae4beSMatthew G. Knepley   Level: beginner
738bc4ae4beSMatthew G. Knepley 
739dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
740bc4ae4beSMatthew G. Knepley @*/
741d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
742d71ae5a4SJacob Faibussowitsch {
7432764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7442764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
745dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
7462764a2aaSMatthew G. Knepley   *dim = 0;
7479de99aefSMatthew G. Knepley   if (prob->Nf) {
7489de99aefSMatthew G. Knepley     PetscObject  obj;
7499de99aefSMatthew G. Knepley     PetscClassId id;
7509de99aefSMatthew G. Knepley 
7519566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
752665f567fSMatthew G. Knepley     if (obj) {
7539566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7549566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7559566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
75698921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7579de99aefSMatthew G. Knepley     }
758665f567fSMatthew G. Knepley   }
7593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7602764a2aaSMatthew G. Knepley }
7612764a2aaSMatthew G. Knepley 
762bc4ae4beSMatthew G. Knepley /*@
763dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
764a859676bSMatthew G. Knepley 
76520f4b53cSBarry Smith   Not Collective
766a859676bSMatthew G. Knepley 
767a859676bSMatthew G. Knepley   Input Parameter:
768dce8aebaSBarry Smith . prob - The `PetscDS` object
769a859676bSMatthew G. Knepley 
770a859676bSMatthew G. Knepley   Output Parameter:
771a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
772a859676bSMatthew G. Knepley 
773a859676bSMatthew G. Knepley   Level: beginner
774a859676bSMatthew G. Knepley 
775dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
776a859676bSMatthew G. Knepley @*/
777d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
778d71ae5a4SJacob Faibussowitsch {
779a859676bSMatthew G. Knepley   PetscFunctionBegin;
780a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
781dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
78208401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
783a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785a859676bSMatthew G. Knepley }
786a859676bSMatthew G. Knepley 
787a859676bSMatthew G. Knepley /*@
788dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
789a859676bSMatthew G. Knepley 
79020f4b53cSBarry Smith   Logically Collective
791a859676bSMatthew G. Knepley 
792a859676bSMatthew G. Knepley   Input Parameters:
793dce8aebaSBarry Smith + prob     - The `PetscDS` object
794a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
795a859676bSMatthew G. Knepley 
796a859676bSMatthew G. Knepley   Level: beginner
797a859676bSMatthew G. Knepley 
798dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
799a859676bSMatthew G. Knepley @*/
800d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
801d71ae5a4SJacob Faibussowitsch {
802a859676bSMatthew G. Knepley   PetscFunctionBegin;
803a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
80463a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
805a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
807a859676bSMatthew G. Knepley }
808a859676bSMatthew G. Knepley 
809a859676bSMatthew G. Knepley /*@
81012fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
81112fc5b22SMatthew G. Knepley 
81212fc5b22SMatthew G. Knepley   Not collective
81312fc5b22SMatthew G. Knepley 
81412fc5b22SMatthew G. Knepley   Input Parameter:
81560225df5SJacob Faibussowitsch . ds - The `PetscDS` object
81612fc5b22SMatthew G. Knepley 
81712fc5b22SMatthew G. Knepley   Output Parameter:
81812fc5b22SMatthew G. Knepley . forceQuad - The flag
81912fc5b22SMatthew G. Knepley 
82012fc5b22SMatthew G. Knepley   Level: intermediate
82112fc5b22SMatthew G. Knepley 
82212fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
82312fc5b22SMatthew G. Knepley @*/
82412fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
82512fc5b22SMatthew G. Knepley {
82612fc5b22SMatthew G. Knepley   PetscFunctionBegin;
82712fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
828f87a0b54SStefano Zampini   PetscValidBoolPointer(forceQuad, 2);
82912fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
83012fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
83112fc5b22SMatthew G. Knepley }
83212fc5b22SMatthew G. Knepley 
83312fc5b22SMatthew G. Knepley /*@
83412fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
83512fc5b22SMatthew G. Knepley 
83612fc5b22SMatthew G. Knepley   Logically collective on ds
83712fc5b22SMatthew G. Knepley 
83812fc5b22SMatthew G. Knepley   Input Parameters:
83912fc5b22SMatthew G. Knepley + ds        - The `PetscDS` object
84012fc5b22SMatthew G. Knepley - forceQuad - The flag
84112fc5b22SMatthew G. Knepley 
84212fc5b22SMatthew G. Knepley   Level: intermediate
84312fc5b22SMatthew G. Knepley 
84412fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
84512fc5b22SMatthew G. Knepley @*/
84612fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
84712fc5b22SMatthew G. Knepley {
84812fc5b22SMatthew G. Knepley   PetscFunctionBegin;
84912fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
85012fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
85112fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
85212fc5b22SMatthew G. Knepley }
85312fc5b22SMatthew G. Knepley 
85412fc5b22SMatthew G. Knepley /*@
855dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8568edf6225SMatthew G. Knepley 
85720f4b53cSBarry Smith   Not Collective
8588edf6225SMatthew G. Knepley 
8598edf6225SMatthew G. Knepley   Input Parameter:
860dce8aebaSBarry Smith . ds - The `PetscDS` object
8618edf6225SMatthew G. Knepley 
8628edf6225SMatthew G. Knepley   Output Parameter:
8635fedec97SMatthew G. Knepley . isCohesive - The flag
8648edf6225SMatthew G. Knepley 
8658edf6225SMatthew G. Knepley   Level: developer
8668edf6225SMatthew G. Knepley 
867dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8688edf6225SMatthew G. Knepley @*/
869d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
870d71ae5a4SJacob Faibussowitsch {
8718edf6225SMatthew G. Knepley   PetscFunctionBegin;
8725fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
873dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
8745fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8768edf6225SMatthew G. Knepley }
8778edf6225SMatthew G. Knepley 
8788edf6225SMatthew G. Knepley /*@
879be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8805fedec97SMatthew G. Knepley 
88120f4b53cSBarry Smith   Not Collective
8825fedec97SMatthew G. Knepley 
8835fedec97SMatthew G. Knepley   Input Parameter:
884dce8aebaSBarry Smith . ds - The `PetscDS` object
8855fedec97SMatthew G. Knepley 
8865fedec97SMatthew G. Knepley   Output Parameter:
8875fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8885fedec97SMatthew G. Knepley 
8895fedec97SMatthew G. Knepley   Level: developer
8905fedec97SMatthew G. Knepley 
891dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8925fedec97SMatthew G. Knepley @*/
893d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
894d71ae5a4SJacob Faibussowitsch {
8955fedec97SMatthew G. Knepley   PetscInt f;
8965fedec97SMatthew G. Knepley 
8975fedec97SMatthew G. Knepley   PetscFunctionBegin;
8985fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
899dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
9005fedec97SMatthew G. Knepley   *numCohesive = 0;
9015fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9035fedec97SMatthew G. Knepley }
9045fedec97SMatthew G. Knepley 
9055fedec97SMatthew G. Knepley /*@
9065fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9075fedec97SMatthew G. Knepley 
90820f4b53cSBarry Smith   Not Collective
9095fedec97SMatthew G. Knepley 
910f1a722f8SMatthew G. Knepley   Input Parameters:
911dce8aebaSBarry Smith + ds - The `PetscDS` object
9125fedec97SMatthew G. Knepley - f  - The field index
9135fedec97SMatthew G. Knepley 
9145fedec97SMatthew G. Knepley   Output Parameter:
9155fedec97SMatthew G. Knepley . isCohesive - The flag
9165fedec97SMatthew G. Knepley 
9175fedec97SMatthew G. Knepley   Level: developer
9185fedec97SMatthew G. Knepley 
919dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9205fedec97SMatthew G. Knepley @*/
921d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
922d71ae5a4SJacob Faibussowitsch {
9235fedec97SMatthew G. Knepley   PetscFunctionBegin;
9245fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
925dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
92663a3b9bcSJacob 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);
9275fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9295fedec97SMatthew G. Knepley }
9305fedec97SMatthew G. Knepley 
9315fedec97SMatthew G. Knepley /*@
9325fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9338edf6225SMatthew G. Knepley 
93420f4b53cSBarry Smith   Not Collective
9358edf6225SMatthew G. Knepley 
9368edf6225SMatthew G. Knepley   Input Parameters:
937dce8aebaSBarry Smith + ds         - The `PetscDS` object
9385fedec97SMatthew G. Knepley . f          - The field index
9395fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9408edf6225SMatthew G. Knepley 
9418edf6225SMatthew G. Knepley   Level: developer
9428edf6225SMatthew G. Knepley 
943dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9448edf6225SMatthew G. Knepley @*/
945d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
946d71ae5a4SJacob Faibussowitsch {
9475fedec97SMatthew G. Knepley   PetscInt i;
9485fedec97SMatthew G. Knepley 
9498edf6225SMatthew G. Knepley   PetscFunctionBegin;
9505fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
95163a3b9bcSJacob 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);
9525fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9535fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9545fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9568edf6225SMatthew G. Knepley }
9578edf6225SMatthew G. Knepley 
9588edf6225SMatthew G. Knepley /*@
959bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
960bc4ae4beSMatthew G. Knepley 
96120f4b53cSBarry Smith   Not Collective
962bc4ae4beSMatthew G. Knepley 
963bc4ae4beSMatthew G. Knepley   Input Parameter:
964dce8aebaSBarry Smith . prob - The `PetscDS` object
965bc4ae4beSMatthew G. Knepley 
966bc4ae4beSMatthew G. Knepley   Output Parameter:
967bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
968bc4ae4beSMatthew G. Knepley 
969bc4ae4beSMatthew G. Knepley   Level: beginner
970bc4ae4beSMatthew G. Knepley 
971dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
972bc4ae4beSMatthew G. Knepley @*/
973d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
974d71ae5a4SJacob Faibussowitsch {
9752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9762764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9779566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
978dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
9792764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9812764a2aaSMatthew G. Knepley }
9822764a2aaSMatthew G. Knepley 
983bc4ae4beSMatthew G. Knepley /*@
984bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
985bc4ae4beSMatthew G. Knepley 
98620f4b53cSBarry Smith   Not Collective
987bc4ae4beSMatthew G. Knepley 
988bc4ae4beSMatthew G. Knepley   Input Parameter:
989dce8aebaSBarry Smith . prob - The `PetscDS` object
990bc4ae4beSMatthew G. Knepley 
991bc4ae4beSMatthew G. Knepley   Output Parameter:
99260225df5SJacob Faibussowitsch . Nc - The total number of components
993bc4ae4beSMatthew G. Knepley 
994bc4ae4beSMatthew G. Knepley   Level: beginner
995bc4ae4beSMatthew G. Knepley 
996dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
997bc4ae4beSMatthew G. Knepley @*/
998d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
999d71ae5a4SJacob Faibussowitsch {
10002764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10012764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10029566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
1003dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
10042764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10062764a2aaSMatthew G. Knepley }
10072764a2aaSMatthew G. Knepley 
1008bc4ae4beSMatthew G. Knepley /*@
1009bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1010bc4ae4beSMatthew G. Knepley 
101120f4b53cSBarry Smith   Not Collective
1012bc4ae4beSMatthew G. Knepley 
1013bc4ae4beSMatthew G. Knepley   Input Parameters:
1014dce8aebaSBarry Smith + prob - The `PetscDS` object
1015bc4ae4beSMatthew G. Knepley - f    - The field number
1016bc4ae4beSMatthew G. Knepley 
1017bc4ae4beSMatthew G. Knepley   Output Parameter:
1018bc4ae4beSMatthew G. Knepley . disc - The discretization object
1019bc4ae4beSMatthew G. Knepley 
1020bc4ae4beSMatthew G. Knepley   Level: beginner
1021bc4ae4beSMatthew G. Knepley 
1022dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1023bc4ae4beSMatthew G. Knepley @*/
1024d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1025d71ae5a4SJacob Faibussowitsch {
10266528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10272764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10282764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
102963a3b9bcSJacob 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);
10302764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10322764a2aaSMatthew G. Knepley }
10332764a2aaSMatthew G. Knepley 
1034bc4ae4beSMatthew G. Knepley /*@
1035bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1036bc4ae4beSMatthew G. Knepley 
103720f4b53cSBarry Smith   Not Collective
1038bc4ae4beSMatthew G. Knepley 
1039bc4ae4beSMatthew G. Knepley   Input Parameters:
1040dce8aebaSBarry Smith + prob - The `PetscDS` object
1041bc4ae4beSMatthew G. Knepley . f    - The field number
1042bc4ae4beSMatthew G. Knepley - disc - The discretization object
1043bc4ae4beSMatthew G. Knepley 
1044bc4ae4beSMatthew G. Knepley   Level: beginner
1045bc4ae4beSMatthew G. Knepley 
1046dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1047bc4ae4beSMatthew G. Knepley @*/
1048d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1049d71ae5a4SJacob Faibussowitsch {
10502764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10512764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1052665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
105363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10549566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10559566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10562764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10579566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1058665f567fSMatthew G. Knepley   if (disc) {
1059249df284SMatthew G. Knepley     PetscClassId id;
1060249df284SMatthew G. Knepley 
10619566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10621cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10639566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10641cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10659566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1066a6cbbb48SMatthew G. Knepley     }
10679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1068249df284SMatthew G. Knepley   }
10693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10702764a2aaSMatthew G. Knepley }
10712764a2aaSMatthew G. Knepley 
1072bc4ae4beSMatthew G. Knepley /*@
10736528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10746528b96dSMatthew G. Knepley 
107520f4b53cSBarry Smith   Not Collective
10766528b96dSMatthew G. Knepley 
10776528b96dSMatthew G. Knepley   Input Parameter:
1078dce8aebaSBarry Smith . ds - The `PetscDS` object
10796528b96dSMatthew G. Knepley 
10806528b96dSMatthew G. Knepley   Output Parameter:
10816528b96dSMatthew G. Knepley . wf - The weak form object
10826528b96dSMatthew G. Knepley 
10836528b96dSMatthew G. Knepley   Level: beginner
10846528b96dSMatthew G. Knepley 
1085dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10866528b96dSMatthew G. Knepley @*/
1087d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1088d71ae5a4SJacob Faibussowitsch {
10896528b96dSMatthew G. Knepley   PetscFunctionBegin;
10906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10916528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
10926528b96dSMatthew G. Knepley   *wf = ds->wf;
10933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10946528b96dSMatthew G. Knepley }
10956528b96dSMatthew G. Knepley 
10966528b96dSMatthew G. Knepley /*@
10976528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10986528b96dSMatthew G. Knepley 
109920f4b53cSBarry Smith   Not Collective
11006528b96dSMatthew G. Knepley 
11016528b96dSMatthew G. Knepley   Input Parameters:
1102dce8aebaSBarry Smith + ds - The `PetscDS` object
11036528b96dSMatthew G. Knepley - wf - The weak form object
11046528b96dSMatthew G. Knepley 
11056528b96dSMatthew G. Knepley   Level: beginner
11066528b96dSMatthew G. Knepley 
1107dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11086528b96dSMatthew G. Knepley @*/
1109d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1110d71ae5a4SJacob Faibussowitsch {
11116528b96dSMatthew G. Knepley   PetscFunctionBegin;
11126528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11149566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11156528b96dSMatthew G. Knepley   ds->wf = wf;
11169566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11196528b96dSMatthew G. Knepley }
11206528b96dSMatthew G. Knepley 
11216528b96dSMatthew G. Knepley /*@
1122bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1123bc4ae4beSMatthew G. Knepley 
112420f4b53cSBarry Smith   Not Collective
1125bc4ae4beSMatthew G. Knepley 
1126bc4ae4beSMatthew G. Knepley   Input Parameters:
1127dce8aebaSBarry Smith + prob - The `PetscDS` object
1128bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1129bc4ae4beSMatthew G. Knepley 
1130bc4ae4beSMatthew G. Knepley   Level: beginner
1131bc4ae4beSMatthew G. Knepley 
1132dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1133bc4ae4beSMatthew G. Knepley @*/
1134d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1135d71ae5a4SJacob Faibussowitsch {
11362764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11379566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11392764a2aaSMatthew G. Knepley }
11402764a2aaSMatthew G. Knepley 
1141249df284SMatthew G. Knepley /*@
1142dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1143083401c6SMatthew G. Knepley 
114420f4b53cSBarry Smith   Not Collective
1145083401c6SMatthew G. Knepley 
1146083401c6SMatthew G. Knepley   Input Parameter:
1147dce8aebaSBarry Smith . prob - The `PetscDS` object
1148083401c6SMatthew G. Knepley 
1149083401c6SMatthew G. Knepley   Output Parameter:
1150083401c6SMatthew G. Knepley . q - The quadrature object
1151083401c6SMatthew G. Knepley 
1152083401c6SMatthew G. Knepley   Level: intermediate
1153083401c6SMatthew G. Knepley 
1154dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1155083401c6SMatthew G. Knepley @*/
1156d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1157d71ae5a4SJacob Faibussowitsch {
1158083401c6SMatthew G. Knepley   PetscObject  obj;
1159083401c6SMatthew G. Knepley   PetscClassId id;
1160083401c6SMatthew G. Knepley 
1161083401c6SMatthew G. Knepley   PetscFunctionBegin;
1162083401c6SMatthew G. Knepley   *q = NULL;
11633ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11659566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11669566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11679566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
116898921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1170083401c6SMatthew G. Knepley }
1171083401c6SMatthew G. Knepley 
1172083401c6SMatthew G. Knepley /*@
1173dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1174249df284SMatthew G. Knepley 
117520f4b53cSBarry Smith   Not Collective
1176249df284SMatthew G. Knepley 
1177249df284SMatthew G. Knepley   Input Parameters:
1178dce8aebaSBarry Smith + prob - The `PetscDS` object
1179249df284SMatthew G. Knepley - f    - The field number
1180249df284SMatthew G. Knepley 
1181249df284SMatthew G. Knepley   Output Parameter:
1182249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1183249df284SMatthew G. Knepley 
1184249df284SMatthew G. Knepley   Level: developer
1185249df284SMatthew G. Knepley 
1186dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1187249df284SMatthew G. Knepley @*/
1188d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1189d71ae5a4SJacob Faibussowitsch {
1190249df284SMatthew G. Knepley   PetscFunctionBegin;
1191249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1192dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
119363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1194249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1196249df284SMatthew G. Knepley }
1197249df284SMatthew G. Knepley 
1198249df284SMatthew G. Knepley /*@
1199dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1200249df284SMatthew G. Knepley 
120120f4b53cSBarry Smith   Not Collective
1202249df284SMatthew G. Knepley 
1203249df284SMatthew G. Knepley   Input Parameters:
1204dce8aebaSBarry Smith + prob     - The `PetscDS` object
1205249df284SMatthew G. Knepley . f        - The field number
1206249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1207249df284SMatthew G. Knepley 
1208249df284SMatthew G. Knepley   Level: developer
1209249df284SMatthew G. Knepley 
1210dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1211249df284SMatthew G. Knepley @*/
1212d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1213d71ae5a4SJacob Faibussowitsch {
1214249df284SMatthew G. Knepley   PetscFunctionBegin;
1215249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
121663a3b9bcSJacob 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);
1217249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1219249df284SMatthew G. Knepley }
1220249df284SMatthew G. Knepley 
1221f9244615SMatthew G. Knepley /*@
1222f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1223f9244615SMatthew G. Knepley 
122420f4b53cSBarry Smith   Not Collective
1225f9244615SMatthew G. Knepley 
1226f9244615SMatthew G. Knepley   Input Parameters:
1227dce8aebaSBarry Smith + ds - The `PetscDS` object
1228f9244615SMatthew G. Knepley - f  - The field number
1229f9244615SMatthew G. Knepley 
1230f9244615SMatthew G. Knepley   Output Parameter:
1231f9244615SMatthew G. Knepley . k - The highest derivative we need to tabulate
1232f9244615SMatthew G. Knepley 
1233f9244615SMatthew G. Knepley   Level: developer
1234f9244615SMatthew G. Knepley 
1235dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1236f9244615SMatthew G. Knepley @*/
1237d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1238d71ae5a4SJacob Faibussowitsch {
1239f9244615SMatthew G. Knepley   PetscFunctionBegin;
1240f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1241dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
124263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1243f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1245f9244615SMatthew G. Knepley }
1246f9244615SMatthew G. Knepley 
1247f9244615SMatthew G. Knepley /*@
1248f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1249f9244615SMatthew G. Knepley 
125020f4b53cSBarry Smith   Not Collective
1251f9244615SMatthew G. Knepley 
1252f9244615SMatthew G. Knepley   Input Parameters:
1253dce8aebaSBarry Smith + ds - The `PetscDS` object
1254f9244615SMatthew G. Knepley . f  - The field number
1255f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1256f9244615SMatthew G. Knepley 
1257f9244615SMatthew G. Knepley   Level: developer
1258f9244615SMatthew G. Knepley 
125960225df5SJacob Faibussowitsch .seealso: ``PetscDS`, `PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1260f9244615SMatthew G. Knepley @*/
1261d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1262d71ae5a4SJacob Faibussowitsch {
1263f9244615SMatthew G. Knepley   PetscFunctionBegin;
1264f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
126563a3b9bcSJacob 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);
1266f9244615SMatthew G. Knepley   ds->jetDegree[f] = k;
12673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1268f9244615SMatthew G. Knepley }
1269f9244615SMatthew G. Knepley 
1270c8943706SMatthew G. Knepley /*@C
1271c8943706SMatthew G. Knepley   PetscDSGetObjective - Get the pointwise objective function for a given test field
1272c8943706SMatthew G. Knepley 
1273c8943706SMatthew G. Knepley   Not Collective
1274c8943706SMatthew G. Knepley 
1275c8943706SMatthew G. Knepley   Input Parameters:
1276c8943706SMatthew G. Knepley + ds - The `PetscDS`
1277c8943706SMatthew G. Knepley - f  - The test field number
1278c8943706SMatthew G. Knepley 
1279c8943706SMatthew G. Knepley   Output Parameters:
1280c8943706SMatthew G. Knepley . obj - integrand for the test function term
1281c8943706SMatthew G. Knepley 
1282c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1283c8943706SMatthew G. Knepley .vb
1284c8943706SMatthew G. Knepley   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1285c8943706SMatthew G. Knepley           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1286c8943706SMatthew G. Knepley           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1287c8943706SMatthew G. Knepley           PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[])
1288c8943706SMatthew G. Knepley .ve
1289c8943706SMatthew G. Knepley + dim - the spatial dimension
1290c8943706SMatthew G. Knepley . Nf - the number of fields
1291c8943706SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1292c8943706SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1293c8943706SMatthew G. Knepley . u - each field evaluated at the current point
1294c8943706SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1295c8943706SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1296c8943706SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1297c8943706SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1298c8943706SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1299c8943706SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1300c8943706SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1301c8943706SMatthew G. Knepley . t - current time
1302c8943706SMatthew G. Knepley . x - coordinates of the current point
1303c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1304c8943706SMatthew G. Knepley . constants - constant parameters
1305c8943706SMatthew G. Knepley - obj - output values at the current point
1306c8943706SMatthew G. Knepley 
1307c8943706SMatthew G. Knepley   Level: intermediate
1308c8943706SMatthew G. Knepley 
1309c8943706SMatthew G. Knepley   Note:
1310c8943706SMatthew G. Knepley   We are using a first order FEM model for the weak form:  \int_\Omega \phi obj(u, u_t, \nabla u, x, t)
1311c8943706SMatthew G. Knepley 
1312c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1313c8943706SMatthew G. Knepley @*/
1314d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f, void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1315d71ae5a4SJacob Faibussowitsch {
13166528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
13176528b96dSMatthew G. Knepley   PetscInt        n;
13186528b96dSMatthew G. Knepley 
13192764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13206528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13216528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
132263a3b9bcSJacob 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);
13239566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13246528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13262764a2aaSMatthew G. Knepley }
13272764a2aaSMatthew G. Knepley 
1328c8943706SMatthew G. Knepley /*@C
1329c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1330c8943706SMatthew G. Knepley 
1331c8943706SMatthew G. Knepley   Not Collective
1332c8943706SMatthew G. Knepley 
1333c8943706SMatthew G. Knepley   Input Parameters:
1334c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1335c8943706SMatthew G. Knepley . f   - The test field number
1336c8943706SMatthew G. Knepley - obj - integrand for the test function term
1337c8943706SMatthew G. Knepley 
1338c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1339c8943706SMatthew G. Knepley .vb
1340c8943706SMatthew G. Knepley   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1341c8943706SMatthew G. Knepley           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1342c8943706SMatthew G. Knepley           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1343c8943706SMatthew G. Knepley           PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[])
1344c8943706SMatthew G. Knepley .ve
1345c8943706SMatthew G. Knepley + dim          - the spatial dimension
1346c8943706SMatthew G. Knepley . Nf           - the number of fields
1347c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1348c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1349c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1350c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1351c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1352c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1353c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1354c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1355c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1356c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1357c8943706SMatthew G. Knepley . t            - current time
1358c8943706SMatthew G. Knepley . x            - coordinates of the current point
1359c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1360c8943706SMatthew G. Knepley . constants    - constant parameters
1361c8943706SMatthew G. Knepley - obj          - output values at the current point
1362c8943706SMatthew G. Knepley 
1363c8943706SMatthew G. Knepley   Level: intermediate
1364c8943706SMatthew G. Knepley 
1365c8943706SMatthew G. Knepley   Note:
1366c8943706SMatthew G. Knepley   We are using a first order FEM model for the weak form:  \int_\Omega \phi obj(u, u_t, \nabla u, x, t)
1367c8943706SMatthew G. Knepley 
1368c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1369c8943706SMatthew G. Knepley @*/
1370d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f, void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1371d71ae5a4SJacob Faibussowitsch {
13722764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13736528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13746528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
137563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13769566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13782764a2aaSMatthew G. Knepley }
13792764a2aaSMatthew G. Knepley 
1380194d53e6SMatthew G. Knepley /*@C
1381194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1382194d53e6SMatthew G. Knepley 
138320f4b53cSBarry Smith   Not Collective
1384194d53e6SMatthew G. Knepley 
1385194d53e6SMatthew G. Knepley   Input Parameters:
1386dce8aebaSBarry Smith + ds - The `PetscDS`
1387194d53e6SMatthew G. Knepley - f  - The test field number
1388194d53e6SMatthew G. Knepley 
1389194d53e6SMatthew G. Knepley   Output Parameters:
1390194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1391194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1392194d53e6SMatthew G. Knepley 
139320f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1394dce8aebaSBarry Smith .vb
139520f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1396dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1397dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1398c8943706SMatthew G. Knepley           PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[])
1399dce8aebaSBarry Smith .ve
1400194d53e6SMatthew G. Knepley + dim - the spatial dimension
1401194d53e6SMatthew G. Knepley . Nf - the number of fields
1402194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1403194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1404194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1405194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1406194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1407194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1408194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1409194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1410194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1411194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1412194d53e6SMatthew G. Knepley . t - current time
1413194d53e6SMatthew G. Knepley . x - coordinates of the current point
141497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
141597b6e6e8SMatthew G. Knepley . constants - constant parameters
1416194d53e6SMatthew G. Knepley - f0 - output values at the current point
1417194d53e6SMatthew G. Knepley 
1418194d53e6SMatthew G. Knepley   Level: intermediate
1419194d53e6SMatthew G. Knepley 
1420dce8aebaSBarry Smith   Note:
1421dce8aebaSBarry 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)
1422dce8aebaSBarry Smith 
1423dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1424194d53e6SMatthew G. Knepley @*/
1425d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1426d71ae5a4SJacob Faibussowitsch {
14276528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
14286528b96dSMatthew G. Knepley   PetscInt        n0, n1;
14296528b96dSMatthew G. Knepley 
14302764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14316528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
143263a3b9bcSJacob 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);
14339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
14346528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
14356528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14372764a2aaSMatthew G. Knepley }
14382764a2aaSMatthew G. Knepley 
1439194d53e6SMatthew G. Knepley /*@C
1440194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1441194d53e6SMatthew G. Knepley 
144220f4b53cSBarry Smith   Not Collective
1443194d53e6SMatthew G. Knepley 
1444194d53e6SMatthew G. Knepley   Input Parameters:
1445dce8aebaSBarry Smith + ds - The `PetscDS`
1446194d53e6SMatthew G. Knepley . f  - The test field number
1447194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1448194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1449194d53e6SMatthew G. Knepley 
145020f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1451dce8aebaSBarry Smith .vb
145220f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1453dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1454dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1455dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1456dce8aebaSBarry Smith .ve
1457194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1458194d53e6SMatthew G. Knepley . Nf           - the number of fields
1459194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1460194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1461194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1462194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1463194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1464194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1465194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1466194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1467194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1468194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1469194d53e6SMatthew G. Knepley . t            - current time
1470194d53e6SMatthew G. Knepley . x            - coordinates of the current point
147197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
147297b6e6e8SMatthew G. Knepley . constants    - constant parameters
1473194d53e6SMatthew G. Knepley - f0           - output values at the current point
1474194d53e6SMatthew G. Knepley 
1475194d53e6SMatthew G. Knepley   Level: intermediate
1476194d53e6SMatthew G. Knepley 
1477dce8aebaSBarry Smith   Note:
1478dce8aebaSBarry 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)
1479dce8aebaSBarry Smith 
1480dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1481194d53e6SMatthew G. Knepley @*/
1482d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1483d71ae5a4SJacob Faibussowitsch {
14842764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14856528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1486f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1487f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
148863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14912764a2aaSMatthew G. Knepley }
14922764a2aaSMatthew G. Knepley 
14933e75805dSMatthew G. Knepley /*@C
1494cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1495cb36c0f9SMatthew G. Knepley 
149620f4b53cSBarry Smith   Not Collective
1497cb36c0f9SMatthew G. Knepley 
1498cb36c0f9SMatthew G. Knepley   Input Parameters:
1499dce8aebaSBarry Smith + ds - The `PetscDS`
1500cb36c0f9SMatthew G. Knepley - f  - The test field number
1501cb36c0f9SMatthew G. Knepley 
1502cb36c0f9SMatthew G. Knepley   Output Parameters:
1503cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1504cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1505cb36c0f9SMatthew G. Knepley 
150620f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1507dce8aebaSBarry Smith .vb
150820f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1509dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1510dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1511dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1512dce8aebaSBarry Smith .ve
1513cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1514cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1515cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1516cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1517cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1518cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1519cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1520cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1521cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1522cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1523cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1524cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1525cb36c0f9SMatthew G. Knepley . t - current time
1526cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1527cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1528cb36c0f9SMatthew G. Knepley . constants - constant parameters
1529cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1530cb36c0f9SMatthew G. Knepley 
1531cb36c0f9SMatthew G. Knepley   Level: intermediate
1532cb36c0f9SMatthew G. Knepley 
1533dce8aebaSBarry Smith   Note:
1534dce8aebaSBarry 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)
1535dce8aebaSBarry Smith 
1536dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1537cb36c0f9SMatthew G. Knepley @*/
1538d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1539d71ae5a4SJacob Faibussowitsch {
1540cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1541cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1542cb36c0f9SMatthew G. Knepley 
1543cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1544cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
154563a3b9bcSJacob 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);
15469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1547cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1548cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
15493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1550cb36c0f9SMatthew G. Knepley }
1551cb36c0f9SMatthew G. Knepley 
1552cb36c0f9SMatthew G. Knepley /*@C
1553cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1554cb36c0f9SMatthew G. Knepley 
155520f4b53cSBarry Smith   Not Collective
1556cb36c0f9SMatthew G. Knepley 
1557cb36c0f9SMatthew G. Knepley   Input Parameters:
1558dce8aebaSBarry Smith + ds - The `PetscDS`
1559cb36c0f9SMatthew G. Knepley . f  - The test field number
1560cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1561cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1562cb36c0f9SMatthew G. Knepley 
1563dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1564dce8aebaSBarry Smith .vb
1565dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1566dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1567dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1568dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1569dce8aebaSBarry Smith .ve
1570cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1571cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1572cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1573cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1574cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1575cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1576cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1577cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1578cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1579cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1580cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1581cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1582cb36c0f9SMatthew G. Knepley . t - current time
1583cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1584cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1585cb36c0f9SMatthew G. Knepley . constants - constant parameters
1586cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1587cb36c0f9SMatthew G. Knepley 
1588cb36c0f9SMatthew G. Knepley   Level: intermediate
1589cb36c0f9SMatthew G. Knepley 
1590dce8aebaSBarry Smith   Note:
1591dce8aebaSBarry 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)
1592dce8aebaSBarry Smith 
1593dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1594cb36c0f9SMatthew G. Knepley @*/
1595d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1596d71ae5a4SJacob Faibussowitsch {
1597cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1598cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1599cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1600cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
160163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
16029566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
16033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1604cb36c0f9SMatthew G. Knepley }
1605cb36c0f9SMatthew G. Knepley 
1606cb36c0f9SMatthew G. Knepley /*@C
1607dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
16083e75805dSMatthew G. Knepley 
160920f4b53cSBarry Smith   Not Collective
16103e75805dSMatthew G. Knepley 
16113e75805dSMatthew G. Knepley   Input Parameter:
161260225df5SJacob Faibussowitsch . ds - The `PetscDS`
16133e75805dSMatthew G. Knepley 
16143e75805dSMatthew G. Knepley   Output Parameter:
16153e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
16163e75805dSMatthew G. Knepley 
16173e75805dSMatthew G. Knepley   Level: intermediate
16183e75805dSMatthew G. Knepley 
1619dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
16203e75805dSMatthew G. Knepley @*/
1621d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1622d71ae5a4SJacob Faibussowitsch {
16233e75805dSMatthew G. Knepley   PetscFunctionBegin;
16246528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
16263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16273e75805dSMatthew G. Knepley }
16283e75805dSMatthew G. Knepley 
1629194d53e6SMatthew G. Knepley /*@C
1630194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1631194d53e6SMatthew G. Knepley 
163220f4b53cSBarry Smith   Not Collective
1633194d53e6SMatthew G. Knepley 
1634194d53e6SMatthew G. Knepley   Input Parameters:
1635dce8aebaSBarry Smith + ds - The `PetscDS`
1636194d53e6SMatthew G. Knepley . f  - The test field number
1637194d53e6SMatthew G. Knepley - g  - The field number
1638194d53e6SMatthew G. Knepley 
1639194d53e6SMatthew G. Knepley   Output Parameters:
1640194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1641194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1642194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1643194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1644194d53e6SMatthew G. Knepley 
164520f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1646dce8aebaSBarry Smith .vb
164720f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1648dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1649dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1650dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1651dce8aebaSBarry Smith .ve
1652194d53e6SMatthew G. Knepley + dim - the spatial dimension
1653194d53e6SMatthew G. Knepley . Nf - the number of fields
1654194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1655194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1656194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1657194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1658194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1659194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1660194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1661194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1662194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1663194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1664194d53e6SMatthew G. Knepley . t - current time
16652aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1666194d53e6SMatthew G. Knepley . x - coordinates of the current point
166797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
166897b6e6e8SMatthew G. Knepley . constants - constant parameters
1669194d53e6SMatthew G. Knepley - g0 - output values at the current point
1670194d53e6SMatthew G. Knepley 
1671194d53e6SMatthew G. Knepley   Level: intermediate
1672194d53e6SMatthew G. Knepley 
1673dce8aebaSBarry Smith   Note:
167460225df5SJacob Faibussowitsch 
1675dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1676dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1677dce8aebaSBarry Smith 
1678dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1679194d53e6SMatthew G. Knepley @*/
1680d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1681d71ae5a4SJacob Faibussowitsch {
16826528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16836528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16846528b96dSMatthew G. Knepley 
16852764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16866528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
168763a3b9bcSJacob 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);
168863a3b9bcSJacob 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);
16899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16906528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16916528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16926528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16936528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16952764a2aaSMatthew G. Knepley }
16962764a2aaSMatthew G. Knepley 
1697194d53e6SMatthew G. Knepley /*@C
1698194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1699194d53e6SMatthew G. Knepley 
170020f4b53cSBarry Smith   Not Collective
1701194d53e6SMatthew G. Knepley 
1702194d53e6SMatthew G. Knepley   Input Parameters:
1703dce8aebaSBarry Smith + ds - The `PetscDS`
1704194d53e6SMatthew G. Knepley . f  - The test field number
1705194d53e6SMatthew G. Knepley . g  - The field number
1706194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1707194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1708194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1709194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1710194d53e6SMatthew G. Knepley 
171120f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1712dce8aebaSBarry Smith .vb
171320f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1714dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1715dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1716dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar g0[])
1717dce8aebaSBarry Smith .ve
1718194d53e6SMatthew G. Knepley + dim - the spatial dimension
1719194d53e6SMatthew G. Knepley . Nf - the number of fields
1720194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1721194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1722194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1723194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1724194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1725194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1726194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1727194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1728194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1729194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1730194d53e6SMatthew G. Knepley . t - current time
17312aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1732194d53e6SMatthew G. Knepley . x - coordinates of the current point
173397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
173497b6e6e8SMatthew G. Knepley . constants - constant parameters
1735194d53e6SMatthew G. Knepley - g0 - output values at the current point
1736194d53e6SMatthew G. Knepley 
1737194d53e6SMatthew G. Knepley   Level: intermediate
1738194d53e6SMatthew G. Knepley 
1739dce8aebaSBarry Smith   Note:
174060225df5SJacob Faibussowitsch 
1741dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1742dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1743dce8aebaSBarry Smith 
1744dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1745194d53e6SMatthew G. Knepley @*/
1746d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1747d71ae5a4SJacob Faibussowitsch {
17482764a2aaSMatthew G. Knepley   PetscFunctionBegin;
17496528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17502764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
17512764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
17522764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
17532764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
175463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
175563a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17569566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17582764a2aaSMatthew G. Knepley }
17592764a2aaSMatthew G. Knepley 
1760475e0ac9SMatthew G. Knepley /*@C
1761dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
176255c1f793SMatthew G. Knepley 
176320f4b53cSBarry Smith   Not Collective
176455c1f793SMatthew G. Knepley 
176555c1f793SMatthew G. Knepley   Input Parameters:
1766dce8aebaSBarry Smith + prob      - The `PetscDS`
176755c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
176855c1f793SMatthew G. Knepley 
176955c1f793SMatthew G. Knepley   Level: intermediate
177055c1f793SMatthew G. Knepley 
1771dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
177255c1f793SMatthew G. Knepley @*/
1773d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1774d71ae5a4SJacob Faibussowitsch {
177555c1f793SMatthew G. Knepley   PetscFunctionBegin;
177655c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
177755c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
177955c1f793SMatthew G. Knepley }
178055c1f793SMatthew G. Knepley 
178155c1f793SMatthew G. Knepley /*@C
1782dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1783475e0ac9SMatthew G. Knepley 
178420f4b53cSBarry Smith   Not Collective
1785475e0ac9SMatthew G. Knepley 
1786475e0ac9SMatthew G. Knepley   Input Parameter:
178760225df5SJacob Faibussowitsch . ds - The `PetscDS`
1788475e0ac9SMatthew G. Knepley 
1789475e0ac9SMatthew G. Knepley   Output Parameter:
1790475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1791475e0ac9SMatthew G. Knepley 
1792475e0ac9SMatthew G. Knepley   Level: intermediate
1793475e0ac9SMatthew G. Knepley 
1794dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1795475e0ac9SMatthew G. Knepley @*/
1796d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1797d71ae5a4SJacob Faibussowitsch {
1798475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17996528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1800475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
18013ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
18029566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
18033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1804475e0ac9SMatthew G. Knepley }
1805475e0ac9SMatthew G. Knepley 
1806475e0ac9SMatthew G. Knepley /*@C
1807dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1808dce8aebaSBarry Smith   the system matrix is used to build the preconditioner.
1809475e0ac9SMatthew G. Knepley 
181020f4b53cSBarry Smith   Not Collective
1811475e0ac9SMatthew G. Knepley 
1812475e0ac9SMatthew G. Knepley   Input Parameters:
1813dce8aebaSBarry Smith + ds - The `PetscDS`
1814475e0ac9SMatthew G. Knepley . f  - The test field number
1815475e0ac9SMatthew G. Knepley - g  - The field number
1816475e0ac9SMatthew G. Knepley 
1817475e0ac9SMatthew G. Knepley   Output Parameters:
1818475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1819475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1820475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1821475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1822475e0ac9SMatthew G. Knepley 
182320f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1824dce8aebaSBarry Smith .vb
182520f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1826dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1827dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1828dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1829dce8aebaSBarry Smith .ve
1830475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1831475e0ac9SMatthew G. Knepley . Nf - the number of fields
1832475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1833475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1834475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1835475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1836475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1837475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1838475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1839475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1840475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1841475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1842475e0ac9SMatthew G. Knepley . t - current time
1843475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1844475e0ac9SMatthew G. Knepley . x - coordinates of the current point
184597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
184697b6e6e8SMatthew G. Knepley . constants - constant parameters
1847475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1848475e0ac9SMatthew G. Knepley 
1849475e0ac9SMatthew G. Knepley   Level: intermediate
1850475e0ac9SMatthew G. Knepley 
1851dce8aebaSBarry Smith   Note:
185260225df5SJacob Faibussowitsch 
1853dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1854dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1855dce8aebaSBarry Smith 
1856dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1857475e0ac9SMatthew G. Knepley @*/
1858d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1859d71ae5a4SJacob Faibussowitsch {
18606528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18616528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18626528b96dSMatthew G. Knepley 
1863475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
186563a3b9bcSJacob 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);
186663a3b9bcSJacob 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);
18679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18686528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18696528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18706528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18716528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1873475e0ac9SMatthew G. Knepley }
1874475e0ac9SMatthew G. Knepley 
1875475e0ac9SMatthew G. Knepley /*@C
1876dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1877dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1878475e0ac9SMatthew G. Knepley 
187920f4b53cSBarry Smith   Not Collective
1880475e0ac9SMatthew G. Knepley 
1881475e0ac9SMatthew G. Knepley   Input Parameters:
1882dce8aebaSBarry Smith + ds - The `PetscDS`
1883475e0ac9SMatthew G. Knepley . f  - The test field number
1884475e0ac9SMatthew G. Knepley . g  - The field number
1885475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1886475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1887475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1888475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1889475e0ac9SMatthew G. Knepley 
189020f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1891dce8aebaSBarry Smith .vb
189220f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1893dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1894dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1895dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar g0[])
1896dce8aebaSBarry Smith .ve
1897475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1898475e0ac9SMatthew G. Knepley . Nf - the number of fields
1899475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1900475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1901475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1902475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1903475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1904475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1905475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1906475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1907475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1908475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1909475e0ac9SMatthew G. Knepley . t - current time
1910475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1911475e0ac9SMatthew G. Knepley . x - coordinates of the current point
191297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
191397b6e6e8SMatthew G. Knepley . constants - constant parameters
1914475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1915475e0ac9SMatthew G. Knepley 
1916475e0ac9SMatthew G. Knepley   Level: intermediate
1917475e0ac9SMatthew G. Knepley 
1918dce8aebaSBarry Smith   Note:
191960225df5SJacob Faibussowitsch 
1920dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1921dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1922dce8aebaSBarry Smith 
1923dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1924475e0ac9SMatthew G. Knepley @*/
1925d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1926d71ae5a4SJacob Faibussowitsch {
1927475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
19286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1929475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1930475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1931475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1932475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
193363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
193463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1937475e0ac9SMatthew G. Knepley }
1938475e0ac9SMatthew G. Knepley 
1939b7e05686SMatthew G. Knepley /*@C
1940b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1941b7e05686SMatthew G. Knepley 
194220f4b53cSBarry Smith   Not Collective
1943b7e05686SMatthew G. Knepley 
1944b7e05686SMatthew G. Knepley   Input Parameter:
1945dce8aebaSBarry Smith . ds - The `PetscDS`
1946b7e05686SMatthew G. Knepley 
1947b7e05686SMatthew G. Knepley   Output Parameter:
1948b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1949b7e05686SMatthew G. Knepley 
1950b7e05686SMatthew G. Knepley   Level: intermediate
1951b7e05686SMatthew G. Knepley 
1952dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1953b7e05686SMatthew G. Knepley @*/
1954d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1955d71ae5a4SJacob Faibussowitsch {
1956b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19576528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19589566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1960b7e05686SMatthew G. Knepley }
1961b7e05686SMatthew G. Knepley 
1962b7e05686SMatthew G. Knepley /*@C
1963b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1964b7e05686SMatthew G. Knepley 
196520f4b53cSBarry Smith   Not Collective
1966b7e05686SMatthew G. Knepley 
1967b7e05686SMatthew G. Knepley   Input Parameters:
1968dce8aebaSBarry Smith + ds - The `PetscDS`
1969b7e05686SMatthew G. Knepley . f  - The test field number
1970b7e05686SMatthew G. Knepley - g  - The field number
1971b7e05686SMatthew G. Knepley 
1972b7e05686SMatthew G. Knepley   Output Parameters:
1973b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1974b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1975b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1976b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1977b7e05686SMatthew G. Knepley 
197820f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1979dce8aebaSBarry Smith .vb
198020f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1981dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1982dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1983dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1984dce8aebaSBarry Smith .ve
1985b7e05686SMatthew G. Knepley + dim - the spatial dimension
1986b7e05686SMatthew G. Knepley . Nf - the number of fields
1987b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1988b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1989b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1990b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1991b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1992b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1993b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1994b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1995b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1996b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1997b7e05686SMatthew G. Knepley . t - current time
1998b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1999b7e05686SMatthew G. Knepley . x - coordinates of the current point
200097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
200197b6e6e8SMatthew G. Knepley . constants - constant parameters
2002b7e05686SMatthew G. Knepley - g0 - output values at the current point
2003b7e05686SMatthew G. Knepley 
2004b7e05686SMatthew G. Knepley   Level: intermediate
2005b7e05686SMatthew G. Knepley 
2006dce8aebaSBarry Smith   Note:
200760225df5SJacob Faibussowitsch 
2008dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2009dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
2010dce8aebaSBarry Smith 
2011dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
2012b7e05686SMatthew G. Knepley @*/
2013d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2014d71ae5a4SJacob Faibussowitsch {
20156528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
20166528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
20176528b96dSMatthew G. Knepley 
2018b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20196528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
202063a3b9bcSJacob 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);
202163a3b9bcSJacob 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);
20229566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
20236528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
20246528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
20256528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
20266528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
20273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2028b7e05686SMatthew G. Knepley }
2029b7e05686SMatthew G. Knepley 
2030b7e05686SMatthew G. Knepley /*@C
2031b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
2032b7e05686SMatthew G. Knepley 
203320f4b53cSBarry Smith   Not Collective
2034b7e05686SMatthew G. Knepley 
2035b7e05686SMatthew G. Knepley   Input Parameters:
2036dce8aebaSBarry Smith + ds - The `PetscDS`
2037b7e05686SMatthew G. Knepley . f  - The test field number
2038b7e05686SMatthew G. Knepley . g  - The field number
2039b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2040b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2041b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2042b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2043b7e05686SMatthew G. Knepley 
204420f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2045dce8aebaSBarry Smith .vb
204620f4b53cSBarry Smith    void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2047dce8aebaSBarry Smith            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2048dce8aebaSBarry Smith            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2049dce8aebaSBarry Smith            PetscReal t, const PetscReal x[], PetscScalar g0[])
2050dce8aebaSBarry Smith .ve
2051b7e05686SMatthew G. Knepley + dim - the spatial dimension
2052b7e05686SMatthew G. Knepley . Nf - the number of fields
2053b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2054b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2055b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
2056b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2057b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2058b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2059b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2060b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2061b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2062b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2063b7e05686SMatthew G. Knepley . t - current time
2064b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2065b7e05686SMatthew G. Knepley . x - coordinates of the current point
206697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
206797b6e6e8SMatthew G. Knepley . constants - constant parameters
2068b7e05686SMatthew G. Knepley - g0 - output values at the current point
2069b7e05686SMatthew G. Knepley 
2070b7e05686SMatthew G. Knepley   Level: intermediate
2071b7e05686SMatthew G. Knepley 
2072dce8aebaSBarry Smith   Note:
207360225df5SJacob Faibussowitsch 
2074dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2075dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
2076dce8aebaSBarry Smith 
2077dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2078b7e05686SMatthew G. Knepley @*/
2079d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2080d71ae5a4SJacob Faibussowitsch {
2081b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20826528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2083b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2084b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2085b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2086b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
208763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
208863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2091b7e05686SMatthew G. Knepley }
2092b7e05686SMatthew G. Knepley 
20930c2f2876SMatthew G. Knepley /*@C
20940c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20950c2f2876SMatthew G. Knepley 
209620f4b53cSBarry Smith   Not Collective
20970c2f2876SMatthew G. Knepley 
20984165533cSJose E. Roman   Input Parameters:
2099dce8aebaSBarry Smith + ds - The `PetscDS` object
21000c2f2876SMatthew G. Knepley - f  - The field number
21010c2f2876SMatthew G. Knepley 
21024165533cSJose E. Roman   Output Parameter:
21030c2f2876SMatthew G. Knepley . r - Riemann solver
21040c2f2876SMatthew G. Knepley 
210520f4b53cSBarry Smith   Calling sequence of `r`:
2106dce8aebaSBarry Smith .vb
210720f4b53cSBarry Smith   void r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2108dce8aebaSBarry Smith .ve
21095db36cf9SMatthew G. Knepley + dim  - The spatial dimension
21105db36cf9SMatthew G. Knepley . Nf   - The number of fields
21115db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
21120c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
21130c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
21140c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
21150c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
211697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
211797b6e6e8SMatthew G. Knepley . constants - constant parameters
21180c2f2876SMatthew G. Knepley - ctx  - optional user context
21190c2f2876SMatthew G. Knepley 
21200c2f2876SMatthew G. Knepley   Level: intermediate
21210c2f2876SMatthew G. Knepley 
2122dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
21230c2f2876SMatthew G. Knepley @*/
2124d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f, void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2125d71ae5a4SJacob Faibussowitsch {
21266528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
21276528b96dSMatthew G. Knepley   PetscInt          n;
21286528b96dSMatthew G. Knepley 
21290c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21306528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
21310c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
213263a3b9bcSJacob 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);
21339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
21346528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
21353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21360c2f2876SMatthew G. Knepley }
21370c2f2876SMatthew G. Knepley 
21380c2f2876SMatthew G. Knepley /*@C
21390c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
21400c2f2876SMatthew G. Knepley 
214120f4b53cSBarry Smith   Not Collective
21420c2f2876SMatthew G. Knepley 
21434165533cSJose E. Roman   Input Parameters:
2144dce8aebaSBarry Smith + ds - The `PetscDS` object
21450c2f2876SMatthew G. Knepley . f  - The field number
21460c2f2876SMatthew G. Knepley - r  - Riemann solver
21470c2f2876SMatthew G. Knepley 
214820f4b53cSBarry Smith   Calling sequence of `r`:
2149dce8aebaSBarry Smith .vb
215020f4b53cSBarry Smith    void r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2151dce8aebaSBarry Smith .ve
21525db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21535db36cf9SMatthew G. Knepley . Nf           - The number of fields
21545db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21550c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21560c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21570c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21580c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
215997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
216097b6e6e8SMatthew G. Knepley . constants    - constant parameters
21610c2f2876SMatthew G. Knepley - ctx          - optional user context
21620c2f2876SMatthew G. Knepley 
21630c2f2876SMatthew G. Knepley   Level: intermediate
21640c2f2876SMatthew G. Knepley 
2165dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21660c2f2876SMatthew G. Knepley @*/
2167d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f, void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2168d71ae5a4SJacob Faibussowitsch {
21690c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21706528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2171de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
217263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21750c2f2876SMatthew G. Knepley }
21760c2f2876SMatthew G. Knepley 
217732d2bbc9SMatthew G. Knepley /*@C
217832d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
217932d2bbc9SMatthew G. Knepley 
218020f4b53cSBarry Smith   Not Collective
218132d2bbc9SMatthew G. Knepley 
218232d2bbc9SMatthew G. Knepley   Input Parameters:
2183dce8aebaSBarry Smith + ds - The `PetscDS`
218432d2bbc9SMatthew G. Knepley - f  - The field number
218532d2bbc9SMatthew G. Knepley 
2186f899ff85SJose E. Roman   Output Parameter:
2187a2b725a8SWilliam Gropp . update - update function
218832d2bbc9SMatthew G. Knepley 
218920f4b53cSBarry Smith   Calling sequence of `update`:
2190dce8aebaSBarry Smith .vb
219120f4b53cSBarry Smith   void update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2192dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2193dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2194dce8aebaSBarry Smith               PetscReal t, const PetscReal x[], PetscScalar uNew[])
2195dce8aebaSBarry Smith .ve
219632d2bbc9SMatthew G. Knepley + dim - the spatial dimension
219732d2bbc9SMatthew G. Knepley . Nf - the number of fields
219832d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
219932d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
220032d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
220132d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
220232d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
220332d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
220432d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
220532d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
220632d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
220732d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
220832d2bbc9SMatthew G. Knepley . t - current time
220932d2bbc9SMatthew G. Knepley . x - coordinates of the current point
221032d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
221132d2bbc9SMatthew G. Knepley 
221232d2bbc9SMatthew G. Knepley   Level: intermediate
221332d2bbc9SMatthew G. Knepley 
2214dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
221532d2bbc9SMatthew G. Knepley @*/
2216d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f, void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2217d71ae5a4SJacob Faibussowitsch {
221832d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22196528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
222063a3b9bcSJacob 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);
22219371c9d4SSatish Balay   if (update) {
22229371c9d4SSatish Balay     PetscValidPointer(update, 3);
22239371c9d4SSatish Balay     *update = ds->update[f];
22249371c9d4SSatish Balay   }
22253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
222632d2bbc9SMatthew G. Knepley }
222732d2bbc9SMatthew G. Knepley 
222832d2bbc9SMatthew G. Knepley /*@C
22293fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
223032d2bbc9SMatthew G. Knepley 
223120f4b53cSBarry Smith   Not Collective
223232d2bbc9SMatthew G. Knepley 
223332d2bbc9SMatthew G. Knepley   Input Parameters:
2234dce8aebaSBarry Smith + ds     - The `PetscDS`
223532d2bbc9SMatthew G. Knepley . f      - The field number
223632d2bbc9SMatthew G. Knepley - update - update function
223732d2bbc9SMatthew G. Knepley 
223820f4b53cSBarry Smith   Calling sequence of `update`:
2239dce8aebaSBarry Smith .vb
224020f4b53cSBarry Smith   void update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2241dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2242dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2243dce8aebaSBarry Smith               PetscReal t, const PetscReal x[], PetscScalar uNew[])
2244dce8aebaSBarry Smith .ve
224532d2bbc9SMatthew G. Knepley + dim    - the spatial dimension
224632d2bbc9SMatthew G. Knepley . Nf     - the number of fields
224732d2bbc9SMatthew G. Knepley . uOff   - the offset into u[] and u_t[] for each field
224832d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
224932d2bbc9SMatthew G. Knepley . u      - each field evaluated at the current point
225032d2bbc9SMatthew G. Knepley . u_t    - the time derivative of each field evaluated at the current point
225132d2bbc9SMatthew G. Knepley . u_x    - the gradient of each field evaluated at the current point
225232d2bbc9SMatthew G. Knepley . aOff   - the offset into a[] and a_t[] for each auxiliary field
225332d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
225432d2bbc9SMatthew G. Knepley . a      - each auxiliary field evaluated at the current point
225532d2bbc9SMatthew G. Knepley . a_t    - the time derivative of each auxiliary field evaluated at the current point
225632d2bbc9SMatthew G. Knepley . a_x    - the gradient of auxiliary each field evaluated at the current point
225732d2bbc9SMatthew G. Knepley . t      - current time
225832d2bbc9SMatthew G. Knepley . x      - coordinates of the current point
225932d2bbc9SMatthew G. Knepley - uNew   - new field values at the current point
226032d2bbc9SMatthew G. Knepley 
226132d2bbc9SMatthew G. Knepley   Level: intermediate
226232d2bbc9SMatthew G. Knepley 
2263dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
226432d2bbc9SMatthew G. Knepley @*/
2265d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f, void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2266d71ae5a4SJacob Faibussowitsch {
226732d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22686528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
226932d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
227063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22719566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22726528b96dSMatthew G. Knepley   ds->update[f] = update;
22733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
227432d2bbc9SMatthew G. Knepley }
227532d2bbc9SMatthew G. Knepley 
2276d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2277d71ae5a4SJacob Faibussowitsch {
22780c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22796528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
228063a3b9bcSJacob 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);
22810c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
22823ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22840c2f2876SMatthew G. Knepley }
22850c2f2876SMatthew G. Knepley 
2286d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2287d71ae5a4SJacob Faibussowitsch {
22880c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22896528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
229063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22919566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22926528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22940c2f2876SMatthew G. Knepley }
22950c2f2876SMatthew G. Knepley 
2296194d53e6SMatthew G. Knepley /*@C
2297194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2298194d53e6SMatthew G. Knepley 
229920f4b53cSBarry Smith   Not Collective
2300194d53e6SMatthew G. Knepley 
2301194d53e6SMatthew G. Knepley   Input Parameters:
23026528b96dSMatthew G. Knepley + ds - The PetscDS
2303194d53e6SMatthew G. Knepley - f  - The test field number
2304194d53e6SMatthew G. Knepley 
2305194d53e6SMatthew G. Knepley   Output Parameters:
2306194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2307194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2308194d53e6SMatthew G. Knepley 
230920f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
2310dce8aebaSBarry Smith .vb
231120f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2312dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2313dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2314dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2315dce8aebaSBarry Smith .ve
2316194d53e6SMatthew G. Knepley + dim - the spatial dimension
2317194d53e6SMatthew G. Knepley . Nf - the number of fields
2318194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2319194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2320194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2321194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2322194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2323194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2324194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2325194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2326194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2327194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2328194d53e6SMatthew G. Knepley . t - current time
2329194d53e6SMatthew G. Knepley . x - coordinates of the current point
2330194d53e6SMatthew G. Knepley . n - unit normal at the current point
233197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
233297b6e6e8SMatthew G. Knepley . constants - constant parameters
2333194d53e6SMatthew G. Knepley - f0 - output values at the current point
2334194d53e6SMatthew G. Knepley 
2335194d53e6SMatthew G. Knepley   Level: intermediate
2336194d53e6SMatthew G. Knepley 
2337dce8aebaSBarry Smith   Note:
233860225df5SJacob Faibussowitsch 
2339dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2340dce8aebaSBarry 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
2341dce8aebaSBarry Smith 
2342dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2343194d53e6SMatthew G. Knepley @*/
2344d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2345d71ae5a4SJacob Faibussowitsch {
23466528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
23476528b96dSMatthew G. Knepley   PetscInt          n0, n1;
23486528b96dSMatthew G. Knepley 
23492764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23506528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
235163a3b9bcSJacob 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);
23529566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
23536528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
23546528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
23553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23562764a2aaSMatthew G. Knepley }
23572764a2aaSMatthew G. Knepley 
2358194d53e6SMatthew G. Knepley /*@C
2359194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2360194d53e6SMatthew G. Knepley 
236120f4b53cSBarry Smith   Not Collective
2362194d53e6SMatthew G. Knepley 
2363194d53e6SMatthew G. Knepley   Input Parameters:
2364dce8aebaSBarry Smith + ds - The `PetscDS`
2365194d53e6SMatthew G. Knepley . f  - The test field number
2366194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2367194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2368194d53e6SMatthew G. Knepley 
236920f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
2370dce8aebaSBarry Smith .vb
237120f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2372dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2373dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2374dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2375dce8aebaSBarry Smith .ve
2376194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2377194d53e6SMatthew G. Knepley . Nf           - the number of fields
2378194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2379194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2380194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2381194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2382194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2383194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2384194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2385194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2386194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2387194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2388194d53e6SMatthew G. Knepley . t            - current time
2389194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2390194d53e6SMatthew G. Knepley . n            - unit normal at the current point
239197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
239297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2393194d53e6SMatthew G. Knepley - f0           - output values at the current point
2394194d53e6SMatthew G. Knepley 
2395194d53e6SMatthew G. Knepley   Level: intermediate
2396194d53e6SMatthew G. Knepley 
2397dce8aebaSBarry Smith   Note:
239860225df5SJacob Faibussowitsch 
2399dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2400dce8aebaSBarry 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
2401dce8aebaSBarry Smith 
2402dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2403194d53e6SMatthew G. Knepley @*/
2404d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2405d71ae5a4SJacob Faibussowitsch {
24062764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24076528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
240863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
24099566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
24103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24112764a2aaSMatthew G. Knepley }
24122764a2aaSMatthew G. Knepley 
241327f02ce8SMatthew G. Knepley /*@
2414dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
241527f02ce8SMatthew G. Knepley 
241620f4b53cSBarry Smith   Not Collective
241727f02ce8SMatthew G. Knepley 
241827f02ce8SMatthew G. Knepley   Input Parameter:
2419dce8aebaSBarry Smith . ds - The `PetscDS`
242027f02ce8SMatthew G. Knepley 
242127f02ce8SMatthew G. Knepley   Output Parameter:
242227f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
242327f02ce8SMatthew G. Knepley 
242427f02ce8SMatthew G. Knepley   Level: intermediate
242527f02ce8SMatthew G. Knepley 
2426dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
242727f02ce8SMatthew G. Knepley @*/
2428d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2429d71ae5a4SJacob Faibussowitsch {
243027f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24316528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24326528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
24339566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
24343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
243527f02ce8SMatthew G. Knepley }
243627f02ce8SMatthew G. Knepley 
2437194d53e6SMatthew G. Knepley /*@C
2438194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2439194d53e6SMatthew G. Knepley 
244020f4b53cSBarry Smith   Not Collective
2441194d53e6SMatthew G. Knepley 
2442194d53e6SMatthew G. Knepley   Input Parameters:
2443dce8aebaSBarry Smith + ds - The `PetscDS`
2444194d53e6SMatthew G. Knepley . f  - The test field number
2445194d53e6SMatthew G. Knepley - g  - The field number
2446194d53e6SMatthew G. Knepley 
2447194d53e6SMatthew G. Knepley   Output Parameters:
2448194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2449194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2450194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2451194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2452194d53e6SMatthew G. Knepley 
245320f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2454dce8aebaSBarry Smith .vb
245520f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2456dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2457dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2458dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2459dce8aebaSBarry Smith .ve
2460194d53e6SMatthew G. Knepley + dim - the spatial dimension
2461194d53e6SMatthew G. Knepley . Nf - the number of fields
2462194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2463194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2464194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2465194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2466194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2467194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2468194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2469194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2470194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2471194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2472194d53e6SMatthew G. Knepley . t - current time
24732aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2474194d53e6SMatthew G. Knepley . x - coordinates of the current point
2475194d53e6SMatthew G. Knepley . n - normal at the current point
247697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
247797b6e6e8SMatthew G. Knepley . constants - constant parameters
2478194d53e6SMatthew G. Knepley - g0 - output values at the current point
2479194d53e6SMatthew G. Knepley 
2480194d53e6SMatthew G. Knepley   Level: intermediate
2481194d53e6SMatthew G. Knepley 
2482dce8aebaSBarry Smith   Note:
248360225df5SJacob Faibussowitsch 
2484dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2485dce8aebaSBarry Smith   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
2486dce8aebaSBarry Smith 
2487dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2488194d53e6SMatthew G. Knepley @*/
2489d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2490d71ae5a4SJacob Faibussowitsch {
24916528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24926528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24936528b96dSMatthew G. Knepley 
24942764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24956528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
249663a3b9bcSJacob 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);
249763a3b9bcSJacob 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);
24989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24996528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25006528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25016528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25026528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25042764a2aaSMatthew G. Knepley }
25052764a2aaSMatthew G. Knepley 
2506194d53e6SMatthew G. Knepley /*@C
2507194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2508194d53e6SMatthew G. Knepley 
250920f4b53cSBarry Smith   Not Collective
2510194d53e6SMatthew G. Knepley 
2511194d53e6SMatthew G. Knepley   Input Parameters:
25126528b96dSMatthew G. Knepley + ds - The PetscDS
2513194d53e6SMatthew G. Knepley . f  - The test field number
2514194d53e6SMatthew G. Knepley . g  - The field number
2515194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2516194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2517194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2518194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2519194d53e6SMatthew G. Knepley 
252020f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2521dce8aebaSBarry Smith .vb
252220f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2523dce8aebaSBarry Smith        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2524dce8aebaSBarry Smith        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2525dce8aebaSBarry Smith        PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2526dce8aebaSBarry Smith .ve
2527194d53e6SMatthew G. Knepley + dim - the spatial dimension
2528194d53e6SMatthew G. Knepley . Nf - the number of fields
2529194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2530194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2531194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2532194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2533194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2534194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2535194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2536194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2537194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2538194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2539194d53e6SMatthew G. Knepley . t - current time
25402aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2541194d53e6SMatthew G. Knepley . x - coordinates of the current point
2542194d53e6SMatthew G. Knepley . n - normal at the current point
254397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
254497b6e6e8SMatthew G. Knepley . constants - constant parameters
2545194d53e6SMatthew G. Knepley - g0 - output values at the current point
2546194d53e6SMatthew G. Knepley 
2547194d53e6SMatthew G. Knepley   Level: intermediate
2548194d53e6SMatthew G. Knepley 
2549dce8aebaSBarry Smith   Note:
255060225df5SJacob Faibussowitsch 
2551dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2552dce8aebaSBarry Smith   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
2553dce8aebaSBarry Smith 
2554dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2555194d53e6SMatthew G. Knepley @*/
2556d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2557d71ae5a4SJacob Faibussowitsch {
25582764a2aaSMatthew G. Knepley   PetscFunctionBegin;
25596528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25602764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
25612764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
25622764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
25632764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
256463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
256563a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
25669566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
25673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25682764a2aaSMatthew G. Knepley }
25692764a2aaSMatthew G. Knepley 
257027f02ce8SMatthew G. Knepley /*@
257127f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
257227f02ce8SMatthew G. Knepley 
257320f4b53cSBarry Smith   Not Collective
257427f02ce8SMatthew G. Knepley 
257527f02ce8SMatthew G. Knepley   Input Parameter:
2576dce8aebaSBarry Smith . ds - The `PetscDS`
257727f02ce8SMatthew G. Knepley 
257827f02ce8SMatthew G. Knepley   Output Parameter:
257960225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
258027f02ce8SMatthew G. Knepley 
258127f02ce8SMatthew G. Knepley   Level: intermediate
258227f02ce8SMatthew G. Knepley 
2583dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
258427f02ce8SMatthew G. Knepley @*/
2585d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2586d71ae5a4SJacob Faibussowitsch {
258727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25886528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25896528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
25909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
259227f02ce8SMatthew G. Knepley }
259327f02ce8SMatthew G. Knepley 
259427f02ce8SMatthew G. Knepley /*@C
259527f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
259627f02ce8SMatthew G. Knepley 
259720f4b53cSBarry Smith   Not Collective; No Fortran Support
259827f02ce8SMatthew G. Knepley 
259927f02ce8SMatthew G. Knepley   Input Parameters:
2600dce8aebaSBarry Smith + ds - The `PetscDS`
260127f02ce8SMatthew G. Knepley . f  - The test field number
260227f02ce8SMatthew G. Knepley - g  - The field number
260327f02ce8SMatthew G. Knepley 
260427f02ce8SMatthew G. Knepley   Output Parameters:
260527f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
260627f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
260727f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
260827f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
260927f02ce8SMatthew G. Knepley 
261020f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2611dce8aebaSBarry Smith .vb
261220f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2613dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2614dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2615dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2616dce8aebaSBarry Smith .ve
261727f02ce8SMatthew G. Knepley + dim - the spatial dimension
261827f02ce8SMatthew G. Knepley . Nf - the number of fields
261927f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
262027f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
262127f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
262227f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
262327f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
262427f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
262527f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
262627f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
262727f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
262827f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
262927f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
263027f02ce8SMatthew G. Knepley . t - current time
263127f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
263227f02ce8SMatthew G. Knepley . x - coordinates of the current point
263327f02ce8SMatthew G. Knepley . n - normal at the current point
263427f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
263527f02ce8SMatthew G. Knepley . constants - constant parameters
263627f02ce8SMatthew G. Knepley - g0 - output values at the current point
263727f02ce8SMatthew G. Knepley 
263827f02ce8SMatthew G. Knepley   Level: intermediate
263927f02ce8SMatthew G. Knepley 
2640dce8aebaSBarry Smith   Note:
264160225df5SJacob Faibussowitsch 
2642dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2643dce8aebaSBarry Smith   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
2644dce8aebaSBarry Smith 
2645dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
264627f02ce8SMatthew G. Knepley @*/
2647d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2648d71ae5a4SJacob Faibussowitsch {
26496528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
26506528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
26516528b96dSMatthew G. Knepley 
265227f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
265463a3b9bcSJacob 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);
265563a3b9bcSJacob 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);
26569566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
26576528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
26586528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
26596528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
26606528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
26613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
266227f02ce8SMatthew G. Knepley }
266327f02ce8SMatthew G. Knepley 
266427f02ce8SMatthew G. Knepley /*@C
266527f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
266627f02ce8SMatthew G. Knepley 
266720f4b53cSBarry Smith   Not Collective; No Fortran Support
266827f02ce8SMatthew G. Knepley 
266927f02ce8SMatthew G. Knepley   Input Parameters:
2670dce8aebaSBarry Smith + ds - The `PetscDS`
267127f02ce8SMatthew G. Knepley . f  - The test field number
267227f02ce8SMatthew G. Knepley . g  - The field number
267327f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
267427f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
267527f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
267627f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
267727f02ce8SMatthew G. Knepley 
267820f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2679dce8aebaSBarry Smith .vb
268020f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2681dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2682dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2683dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2684dce8aebaSBarry Smith .ve
268527f02ce8SMatthew G. Knepley + dim - the spatial dimension
268627f02ce8SMatthew G. Knepley . Nf - the number of fields
268727f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
268827f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
268927f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
269027f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
269127f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
269227f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
269327f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
269427f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
269527f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
269627f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
269727f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
269827f02ce8SMatthew G. Knepley . t - current time
269927f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
270027f02ce8SMatthew G. Knepley . x - coordinates of the current point
270127f02ce8SMatthew G. Knepley . n - normal at the current point
270227f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
270327f02ce8SMatthew G. Knepley . constants - constant parameters
270427f02ce8SMatthew G. Knepley - g0 - output values at the current point
270527f02ce8SMatthew G. Knepley 
270627f02ce8SMatthew G. Knepley   Level: intermediate
270727f02ce8SMatthew G. Knepley 
2708dce8aebaSBarry Smith   Note:
270960225df5SJacob Faibussowitsch 
2710dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2711dce8aebaSBarry Smith   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi
2712dce8aebaSBarry Smith 
2713dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
271427f02ce8SMatthew G. Knepley @*/
2715d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2716d71ae5a4SJacob Faibussowitsch {
271727f02ce8SMatthew G. Knepley   PetscFunctionBegin;
27186528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
271927f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
272027f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
272127f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
272227f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
272363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
272463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
27259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
27263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
272727f02ce8SMatthew G. Knepley }
272827f02ce8SMatthew G. Knepley 
27290d3e9b51SMatthew G. Knepley /*@C
2730c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2731c371a6d1SMatthew G. Knepley 
273220f4b53cSBarry Smith   Not Collective
2733c371a6d1SMatthew G. Knepley 
2734c371a6d1SMatthew G. Knepley   Input Parameters:
2735c371a6d1SMatthew G. Knepley + prob - The PetscDS
2736c371a6d1SMatthew G. Knepley - f    - The test field number
2737c371a6d1SMatthew G. Knepley 
2738d8d19677SJose E. Roman   Output Parameters:
273995cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
274095cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2741c371a6d1SMatthew G. Knepley 
274220f4b53cSBarry Smith   Calling sequence of `exactSol`:
2743dce8aebaSBarry Smith .vb
274420f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2745dce8aebaSBarry Smith .ve
2746c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2747c371a6d1SMatthew G. Knepley . t - current time
2748c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2749c371a6d1SMatthew G. Knepley . Nc - the number of field components
275060225df5SJacob Faibussowitsch . sol - the solution field evaluated at the current point
2751c371a6d1SMatthew G. Knepley - ctx - a user context
2752c371a6d1SMatthew G. Knepley 
2753c371a6d1SMatthew G. Knepley   Level: intermediate
2754c371a6d1SMatthew G. Knepley 
2755dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2756c371a6d1SMatthew G. Knepley @*/
2757d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2758d71ae5a4SJacob Faibussowitsch {
2759c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2760c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
276163a3b9bcSJacob 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);
27629371c9d4SSatish Balay   if (sol) {
27639371c9d4SSatish Balay     PetscValidPointer(sol, 3);
27649371c9d4SSatish Balay     *sol = prob->exactSol[f];
27659371c9d4SSatish Balay   }
27669371c9d4SSatish Balay   if (ctx) {
27679371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
27689371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
27699371c9d4SSatish Balay   }
27703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2771c371a6d1SMatthew G. Knepley }
2772c371a6d1SMatthew G. Knepley 
2773c371a6d1SMatthew G. Knepley /*@C
2774578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2775c371a6d1SMatthew G. Knepley 
277620f4b53cSBarry Smith   Not Collective
2777c371a6d1SMatthew G. Knepley 
2778c371a6d1SMatthew G. Knepley   Input Parameters:
2779dce8aebaSBarry Smith + prob - The `PetscDS`
2780c371a6d1SMatthew G. Knepley . f    - The test field number
278195cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
278220f4b53cSBarry Smith - ctx  - solution context or `NULL`
2783c371a6d1SMatthew G. Knepley 
278420f4b53cSBarry Smith   Calling sequence of `sol`:
2785dce8aebaSBarry Smith .vb
278620f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2787dce8aebaSBarry Smith .ve
2788c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2789c371a6d1SMatthew G. Knepley . t   - current time
2790c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2791c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2792c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2793c371a6d1SMatthew G. Knepley - ctx - a user context
2794c371a6d1SMatthew G. Knepley 
2795c371a6d1SMatthew G. Knepley   Level: intermediate
2796c371a6d1SMatthew G. Knepley 
2797dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2798c371a6d1SMatthew G. Knepley @*/
2799d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2800d71ae5a4SJacob Faibussowitsch {
2801c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2802c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
280363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
28049566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
28059371c9d4SSatish Balay   if (sol) {
28069371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28079371c9d4SSatish Balay     prob->exactSol[f] = sol;
28089371c9d4SSatish Balay   }
28099371c9d4SSatish Balay   if (ctx) {
28109371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28119371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
28129371c9d4SSatish Balay   }
28133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2814c371a6d1SMatthew G. Knepley }
2815c371a6d1SMatthew G. Knepley 
28165638fd0eSMatthew G. Knepley /*@C
2817f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2818f2cacb80SMatthew G. Knepley 
281920f4b53cSBarry Smith   Not Collective
2820f2cacb80SMatthew G. Knepley 
2821f2cacb80SMatthew G. Knepley   Input Parameters:
2822dce8aebaSBarry Smith + prob - The `PetscDS`
2823f2cacb80SMatthew G. Knepley - f    - The test field number
2824f2cacb80SMatthew G. Knepley 
2825d8d19677SJose E. Roman   Output Parameters:
2826f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2827f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2828f2cacb80SMatthew G. Knepley 
282920f4b53cSBarry Smith   Calling sequence of `exactSol`:
2830dce8aebaSBarry Smith .vb
283120f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2832dce8aebaSBarry Smith .ve
2833f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2834f2cacb80SMatthew G. Knepley . t - current time
2835f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2836f2cacb80SMatthew G. Knepley . Nc - the number of field components
283760225df5SJacob Faibussowitsch . sol - the solution field evaluated at the current point
2838f2cacb80SMatthew G. Knepley - ctx - a user context
2839f2cacb80SMatthew G. Knepley 
2840f2cacb80SMatthew G. Knepley   Level: intermediate
2841f2cacb80SMatthew G. Knepley 
2842dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2843f2cacb80SMatthew G. Knepley @*/
2844d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2845d71ae5a4SJacob Faibussowitsch {
2846f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2847f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
284863a3b9bcSJacob 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);
28499371c9d4SSatish Balay   if (sol) {
28509371c9d4SSatish Balay     PetscValidPointer(sol, 3);
28519371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
28529371c9d4SSatish Balay   }
28539371c9d4SSatish Balay   if (ctx) {
28549371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
28559371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
28569371c9d4SSatish Balay   }
28573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2858f2cacb80SMatthew G. Knepley }
2859f2cacb80SMatthew G. Knepley 
2860f2cacb80SMatthew G. Knepley /*@C
2861f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2862f2cacb80SMatthew G. Knepley 
286320f4b53cSBarry Smith   Not Collective
2864f2cacb80SMatthew G. Knepley 
2865f2cacb80SMatthew G. Knepley   Input Parameters:
2866dce8aebaSBarry Smith + prob - The `PetscDS`
2867f2cacb80SMatthew G. Knepley . f    - The test field number
2868f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
286920f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2870f2cacb80SMatthew G. Knepley 
287120f4b53cSBarry Smith   Calling sequence of `sol`:
2872dce8aebaSBarry Smith .vb
287320f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2874dce8aebaSBarry Smith .ve
2875f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2876f2cacb80SMatthew G. Knepley . t   - current time
2877f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2878f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2879f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2880f2cacb80SMatthew G. Knepley - ctx - a user context
2881f2cacb80SMatthew G. Knepley 
2882f2cacb80SMatthew G. Knepley   Level: intermediate
2883f2cacb80SMatthew G. Knepley 
2884dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2885f2cacb80SMatthew G. Knepley @*/
2886d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2887d71ae5a4SJacob Faibussowitsch {
2888f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2889f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
289063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
28919566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
28929371c9d4SSatish Balay   if (sol) {
28939371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28949371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28959371c9d4SSatish Balay   }
28969371c9d4SSatish Balay   if (ctx) {
28979371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28989371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28999371c9d4SSatish Balay   }
29003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2901f2cacb80SMatthew G. Knepley }
2902f2cacb80SMatthew G. Knepley 
2903f2cacb80SMatthew G. Knepley /*@C
290497b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
290597b6e6e8SMatthew G. Knepley 
290620f4b53cSBarry Smith   Not Collective
290797b6e6e8SMatthew G. Knepley 
290897b6e6e8SMatthew G. Knepley   Input Parameter:
2909dce8aebaSBarry Smith . prob - The `PetscDS` object
291097b6e6e8SMatthew G. Knepley 
291197b6e6e8SMatthew G. Knepley   Output Parameters:
291297b6e6e8SMatthew G. Knepley + numConstants - The number of constants
291397b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
291497b6e6e8SMatthew G. Knepley 
291597b6e6e8SMatthew G. Knepley   Level: intermediate
291697b6e6e8SMatthew G. Knepley 
2917dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
291897b6e6e8SMatthew G. Knepley @*/
2919d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2920d71ae5a4SJacob Faibussowitsch {
292197b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
292297b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29239371c9d4SSatish Balay   if (numConstants) {
29249371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
29259371c9d4SSatish Balay     *numConstants = prob->numConstants;
29269371c9d4SSatish Balay   }
29279371c9d4SSatish Balay   if (constants) {
29289371c9d4SSatish Balay     PetscValidPointer(constants, 3);
29299371c9d4SSatish Balay     *constants = prob->constants;
29309371c9d4SSatish Balay   }
29313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
293297b6e6e8SMatthew G. Knepley }
293397b6e6e8SMatthew G. Knepley 
29340d3e9b51SMatthew G. Knepley /*@C
293597b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
293697b6e6e8SMatthew G. Knepley 
293720f4b53cSBarry Smith   Not Collective
293897b6e6e8SMatthew G. Knepley 
293997b6e6e8SMatthew G. Knepley   Input Parameters:
2940dce8aebaSBarry Smith + prob         - The `PetscDS` object
294197b6e6e8SMatthew G. Knepley . numConstants - The number of constants
294297b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
294397b6e6e8SMatthew G. Knepley 
294497b6e6e8SMatthew G. Knepley   Level: intermediate
294597b6e6e8SMatthew G. Knepley 
2946dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
294797b6e6e8SMatthew G. Knepley @*/
2948d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2949d71ae5a4SJacob Faibussowitsch {
295097b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
295197b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
295297b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
29539566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
295497b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
295597b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
29569566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
295720be0f5bSMatthew G. Knepley     } else {
295820be0f5bSMatthew G. Knepley       prob->constants = NULL;
295920be0f5bSMatthew G. Knepley     }
296020be0f5bSMatthew G. Knepley   }
296120be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2962dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
29639566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
296497b6e6e8SMatthew G. Knepley   }
29653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
296697b6e6e8SMatthew G. Knepley }
296797b6e6e8SMatthew G. Knepley 
29684cd1e086SMatthew G. Knepley /*@
29694cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
29704cd1e086SMatthew G. Knepley 
297120f4b53cSBarry Smith   Not Collective
29724cd1e086SMatthew G. Knepley 
29734cd1e086SMatthew G. Knepley   Input Parameters:
2974dce8aebaSBarry Smith + prob - The `PetscDS` object
29754cd1e086SMatthew G. Knepley - disc - The discretization object
29764cd1e086SMatthew G. Knepley 
29774cd1e086SMatthew G. Knepley   Output Parameter:
29784cd1e086SMatthew G. Knepley . f - The field number
29794cd1e086SMatthew G. Knepley 
29804cd1e086SMatthew G. Knepley   Level: beginner
29814cd1e086SMatthew G. Knepley 
2982dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29834cd1e086SMatthew G. Knepley @*/
2984d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2985d71ae5a4SJacob Faibussowitsch {
29864cd1e086SMatthew G. Knepley   PetscInt g;
29874cd1e086SMatthew G. Knepley 
29884cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29894cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2990dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
29914cd1e086SMatthew G. Knepley   *f = -1;
29929371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
29939371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
29949371c9d4SSatish Balay   }
299508401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
29964cd1e086SMatthew G. Knepley   *f = g;
29973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29984cd1e086SMatthew G. Knepley }
29994cd1e086SMatthew G. Knepley 
30004cd1e086SMatthew G. Knepley /*@
30014cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
30024cd1e086SMatthew G. Knepley 
300320f4b53cSBarry Smith   Not Collective
30044cd1e086SMatthew G. Knepley 
30054cd1e086SMatthew G. Knepley   Input Parameters:
3006dce8aebaSBarry Smith + prob - The `PetscDS` object
30074cd1e086SMatthew G. Knepley - f    - The field number
30084cd1e086SMatthew G. Knepley 
30094cd1e086SMatthew G. Knepley   Output Parameter:
30104cd1e086SMatthew G. Knepley . size - The size
30114cd1e086SMatthew G. Knepley 
30124cd1e086SMatthew G. Knepley   Level: beginner
30134cd1e086SMatthew G. Knepley 
3014dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30154cd1e086SMatthew G. Knepley @*/
3016d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
3017d71ae5a4SJacob Faibussowitsch {
30184cd1e086SMatthew G. Knepley   PetscFunctionBegin;
30194cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3020dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
302163a3b9bcSJacob 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);
30229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3023d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
30243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30254cd1e086SMatthew G. Knepley }
30264cd1e086SMatthew G. Knepley 
3027bc4ae4beSMatthew G. Knepley /*@
3028bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
3029bc4ae4beSMatthew G. Knepley 
303020f4b53cSBarry Smith   Not Collective
3031bc4ae4beSMatthew G. Knepley 
3032bc4ae4beSMatthew G. Knepley   Input Parameters:
3033dce8aebaSBarry Smith + prob - The `PetscDS` object
3034bc4ae4beSMatthew G. Knepley - f    - The field number
3035bc4ae4beSMatthew G. Knepley 
3036bc4ae4beSMatthew G. Knepley   Output Parameter:
3037bc4ae4beSMatthew G. Knepley . off - The offset
3038bc4ae4beSMatthew G. Knepley 
3039bc4ae4beSMatthew G. Knepley   Level: beginner
3040bc4ae4beSMatthew G. Knepley 
3041dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3042bc4ae4beSMatthew G. Knepley @*/
3043d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
3044d71ae5a4SJacob Faibussowitsch {
30454cd1e086SMatthew G. Knepley   PetscInt size, g;
30462764a2aaSMatthew G. Knepley 
30472764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30482764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3049dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
305063a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
30512764a2aaSMatthew G. Knepley   *off = 0;
30522764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
30539566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
30544cd1e086SMatthew G. Knepley     *off += size;
30552764a2aaSMatthew G. Knepley   }
30563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30572764a2aaSMatthew G. Knepley }
30582764a2aaSMatthew G. Knepley 
3059bc4ae4beSMatthew G. Knepley /*@
30605fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
30615fedec97SMatthew G. Knepley 
306220f4b53cSBarry Smith   Not Collective
30635fedec97SMatthew G. Knepley 
30645fedec97SMatthew G. Knepley   Input Parameters:
306560225df5SJacob Faibussowitsch + ds - The `PetscDS` object
30665fedec97SMatthew G. Knepley - f  - The field number
30675fedec97SMatthew G. Knepley 
30685fedec97SMatthew G. Knepley   Output Parameter:
30695fedec97SMatthew G. Knepley . off - The offset
30705fedec97SMatthew G. Knepley 
30715fedec97SMatthew G. Knepley   Level: beginner
30725fedec97SMatthew G. Knepley 
3073dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30745fedec97SMatthew G. Knepley @*/
3075d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
3076d71ae5a4SJacob Faibussowitsch {
30775fedec97SMatthew G. Knepley   PetscInt size, g;
30785fedec97SMatthew G. Knepley 
30795fedec97SMatthew G. Knepley   PetscFunctionBegin;
30805fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3081dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
308263a3b9bcSJacob 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);
30835fedec97SMatthew G. Knepley   *off = 0;
30845fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
30855fedec97SMatthew G. Knepley     PetscBool cohesive;
30865fedec97SMatthew G. Knepley 
30879566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
30889566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
30895fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
30905fedec97SMatthew G. Knepley   }
30913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30925fedec97SMatthew G. Knepley }
30935fedec97SMatthew G. Knepley 
30945fedec97SMatthew G. Knepley /*@
309547e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3096bc4ae4beSMatthew G. Knepley 
309720f4b53cSBarry Smith   Not Collective
3098bc4ae4beSMatthew G. Knepley 
309947e57110SSander Arens   Input Parameter:
3100dce8aebaSBarry Smith . prob - The `PetscDS` object
3101bc4ae4beSMatthew G. Knepley 
3102bc4ae4beSMatthew G. Knepley   Output Parameter:
310347e57110SSander Arens . dimensions - The number of dimensions
3104bc4ae4beSMatthew G. Knepley 
3105bc4ae4beSMatthew G. Knepley   Level: beginner
3106bc4ae4beSMatthew G. Knepley 
3107dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3108bc4ae4beSMatthew G. Knepley @*/
3109d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3110d71ae5a4SJacob Faibussowitsch {
31112764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31122764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31139566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
311447e57110SSander Arens   PetscValidPointer(dimensions, 2);
311547e57110SSander Arens   *dimensions = prob->Nb;
31163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31176ce16762SMatthew G. Knepley }
311847e57110SSander Arens 
311947e57110SSander Arens /*@
312047e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
312147e57110SSander Arens 
312220f4b53cSBarry Smith   Not Collective
312347e57110SSander Arens 
312447e57110SSander Arens   Input Parameter:
3125dce8aebaSBarry Smith . prob - The `PetscDS` object
312647e57110SSander Arens 
312747e57110SSander Arens   Output Parameter:
312847e57110SSander Arens . components - The number of components
312947e57110SSander Arens 
313047e57110SSander Arens   Level: beginner
313147e57110SSander Arens 
3132dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
313347e57110SSander Arens @*/
3134d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3135d71ae5a4SJacob Faibussowitsch {
313647e57110SSander Arens   PetscFunctionBegin;
313747e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
313947e57110SSander Arens   PetscValidPointer(components, 2);
314047e57110SSander Arens   *components = prob->Nc;
31413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31426ce16762SMatthew G. Knepley }
31436ce16762SMatthew G. Knepley 
31446ce16762SMatthew G. Knepley /*@
31456ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
31466ce16762SMatthew G. Knepley 
314720f4b53cSBarry Smith   Not Collective
31486ce16762SMatthew G. Knepley 
31496ce16762SMatthew G. Knepley   Input Parameters:
3150dce8aebaSBarry Smith + prob - The `PetscDS` object
31516ce16762SMatthew G. Knepley - f    - The field number
31526ce16762SMatthew G. Knepley 
31536ce16762SMatthew G. Knepley   Output Parameter:
31546ce16762SMatthew G. Knepley . off - The offset
31556ce16762SMatthew G. Knepley 
31566ce16762SMatthew G. Knepley   Level: beginner
31576ce16762SMatthew G. Knepley 
3158dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31596ce16762SMatthew G. Knepley @*/
3160d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3161d71ae5a4SJacob Faibussowitsch {
31626ce16762SMatthew G. Knepley   PetscFunctionBegin;
31636ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3164dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
316563a3b9bcSJacob 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);
31669566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
316747e57110SSander Arens   *off = prob->off[f];
31683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31692764a2aaSMatthew G. Knepley }
31702764a2aaSMatthew G. Knepley 
3171194d53e6SMatthew G. Knepley /*@
3172194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3173194d53e6SMatthew G. Knepley 
317420f4b53cSBarry Smith   Not Collective
3175194d53e6SMatthew G. Knepley 
3176194d53e6SMatthew G. Knepley   Input Parameter:
3177dce8aebaSBarry Smith . prob - The `PetscDS` object
3178194d53e6SMatthew G. Knepley 
3179194d53e6SMatthew G. Knepley   Output Parameter:
3180194d53e6SMatthew G. Knepley . offsets - The offsets
3181194d53e6SMatthew G. Knepley 
3182194d53e6SMatthew G. Knepley   Level: beginner
3183194d53e6SMatthew G. Knepley 
3184dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3185194d53e6SMatthew G. Knepley @*/
3186d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3187d71ae5a4SJacob Faibussowitsch {
3188194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3189194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3190194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
31919566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3192194d53e6SMatthew G. Knepley   *offsets = prob->off;
31933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3194194d53e6SMatthew G. Knepley }
3195194d53e6SMatthew G. Knepley 
3196194d53e6SMatthew G. Knepley /*@
3197194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3198194d53e6SMatthew G. Knepley 
319920f4b53cSBarry Smith   Not Collective
3200194d53e6SMatthew G. Knepley 
3201194d53e6SMatthew G. Knepley   Input Parameter:
3202dce8aebaSBarry Smith . prob - The `PetscDS` object
3203194d53e6SMatthew G. Knepley 
3204194d53e6SMatthew G. Knepley   Output Parameter:
3205194d53e6SMatthew G. Knepley . offsets - The offsets
3206194d53e6SMatthew G. Knepley 
3207194d53e6SMatthew G. Knepley   Level: beginner
3208194d53e6SMatthew G. Knepley 
3209dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3210194d53e6SMatthew G. Knepley @*/
3211d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3212d71ae5a4SJacob Faibussowitsch {
3213194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3214194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3215194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
32169566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3217194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
32183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3219194d53e6SMatthew G. Knepley }
3220194d53e6SMatthew G. Knepley 
32219ee2af8cSMatthew G. Knepley /*@
32229ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
32239ee2af8cSMatthew G. Knepley 
322420f4b53cSBarry Smith   Not Collective
32259ee2af8cSMatthew G. Knepley 
32269ee2af8cSMatthew G. Knepley   Input Parameters:
3227dce8aebaSBarry Smith + ds - The `PetscDS` object
32289ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
32299ee2af8cSMatthew G. Knepley 
32309ee2af8cSMatthew G. Knepley   Output Parameter:
32319ee2af8cSMatthew G. Knepley . offsets - The offsets
32329ee2af8cSMatthew G. Knepley 
32339ee2af8cSMatthew G. Knepley   Level: beginner
32349ee2af8cSMatthew G. Knepley 
3235dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
32369ee2af8cSMatthew G. Knepley @*/
3237d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3238d71ae5a4SJacob Faibussowitsch {
32399ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
32409ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
32419ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
324228b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
324363a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
32449566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
32459ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
32463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32479ee2af8cSMatthew G. Knepley }
32489ee2af8cSMatthew G. Knepley 
32499ee2af8cSMatthew G. Knepley /*@
32509ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
32519ee2af8cSMatthew G. Knepley 
325220f4b53cSBarry Smith   Not Collective
32539ee2af8cSMatthew G. Knepley 
32549ee2af8cSMatthew G. Knepley   Input Parameters:
3255dce8aebaSBarry Smith + ds - The `PetscDS` object
32569ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
32579ee2af8cSMatthew G. Knepley 
32589ee2af8cSMatthew G. Knepley   Output Parameter:
32599ee2af8cSMatthew G. Knepley . offsets - The offsets
32609ee2af8cSMatthew G. Knepley 
32619ee2af8cSMatthew G. Knepley   Level: beginner
32629ee2af8cSMatthew G. Knepley 
3263dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
32649ee2af8cSMatthew G. Knepley @*/
3265d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3266d71ae5a4SJacob Faibussowitsch {
32679ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
32689ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
32699ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
327028b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
327163a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
32729566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
32739ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
32743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32759ee2af8cSMatthew G. Knepley }
32769ee2af8cSMatthew G. Knepley 
327768c9edb9SMatthew G. Knepley /*@C
327868c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
327968c9edb9SMatthew G. Knepley 
328020f4b53cSBarry Smith   Not Collective
328168c9edb9SMatthew G. Knepley 
328268c9edb9SMatthew G. Knepley   Input Parameter:
3283dce8aebaSBarry Smith . prob - The `PetscDS` object
328468c9edb9SMatthew G. Knepley 
3285ef0bb6c7SMatthew G. Knepley   Output Parameter:
3286ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
328768c9edb9SMatthew G. Knepley 
328868c9edb9SMatthew G. Knepley   Level: intermediate
328968c9edb9SMatthew G. Knepley 
3290dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
329168c9edb9SMatthew G. Knepley @*/
3292d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3293d71ae5a4SJacob Faibussowitsch {
32942764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32952764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3296ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
32979566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3298ef0bb6c7SMatthew G. Knepley   *T = prob->T;
32993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33002764a2aaSMatthew G. Knepley }
33012764a2aaSMatthew G. Knepley 
330268c9edb9SMatthew G. Knepley /*@C
33034d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
330468c9edb9SMatthew G. Knepley 
330520f4b53cSBarry Smith   Not Collective
330668c9edb9SMatthew G. Knepley 
330768c9edb9SMatthew G. Knepley   Input Parameter:
3308dce8aebaSBarry Smith . prob - The `PetscDS` object
330968c9edb9SMatthew G. Knepley 
3310ef0bb6c7SMatthew G. Knepley   Output Parameter:
3311a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
331268c9edb9SMatthew G. Knepley 
331368c9edb9SMatthew G. Knepley   Level: intermediate
331468c9edb9SMatthew G. Knepley 
3315dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
331668c9edb9SMatthew G. Knepley @*/
3317d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3318d71ae5a4SJacob Faibussowitsch {
33192764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33202764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3321ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
33229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3323ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
33243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33252764a2aaSMatthew G. Knepley }
33262764a2aaSMatthew G. Knepley 
3327d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3328d71ae5a4SJacob Faibussowitsch {
33292764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33302764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33319566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33329371c9d4SSatish Balay   if (u) {
33339371c9d4SSatish Balay     PetscValidPointer(u, 2);
33349371c9d4SSatish Balay     *u = prob->u;
33359371c9d4SSatish Balay   }
33369371c9d4SSatish Balay   if (u_t) {
33379371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
33389371c9d4SSatish Balay     *u_t = prob->u_t;
33399371c9d4SSatish Balay   }
33409371c9d4SSatish Balay   if (u_x) {
33419371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
33429371c9d4SSatish Balay     *u_x = prob->u_x;
33439371c9d4SSatish Balay   }
33443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33452764a2aaSMatthew G. Knepley }
33462764a2aaSMatthew G. Knepley 
3347d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3348d71ae5a4SJacob Faibussowitsch {
33492764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33502764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33529371c9d4SSatish Balay   if (f0) {
33539371c9d4SSatish Balay     PetscValidPointer(f0, 2);
33549371c9d4SSatish Balay     *f0 = prob->f0;
33559371c9d4SSatish Balay   }
33569371c9d4SSatish Balay   if (f1) {
33579371c9d4SSatish Balay     PetscValidPointer(f1, 3);
33589371c9d4SSatish Balay     *f1 = prob->f1;
33599371c9d4SSatish Balay   }
33609371c9d4SSatish Balay   if (g0) {
33619371c9d4SSatish Balay     PetscValidPointer(g0, 4);
33629371c9d4SSatish Balay     *g0 = prob->g0;
33639371c9d4SSatish Balay   }
33649371c9d4SSatish Balay   if (g1) {
33659371c9d4SSatish Balay     PetscValidPointer(g1, 5);
33669371c9d4SSatish Balay     *g1 = prob->g1;
33679371c9d4SSatish Balay   }
33689371c9d4SSatish Balay   if (g2) {
33699371c9d4SSatish Balay     PetscValidPointer(g2, 6);
33709371c9d4SSatish Balay     *g2 = prob->g2;
33719371c9d4SSatish Balay   }
33729371c9d4SSatish Balay   if (g3) {
33739371c9d4SSatish Balay     PetscValidPointer(g3, 7);
33749371c9d4SSatish Balay     *g3 = prob->g3;
33759371c9d4SSatish Balay   }
33763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33772764a2aaSMatthew G. Knepley }
33782764a2aaSMatthew G. Knepley 
3379d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3380d71ae5a4SJacob Faibussowitsch {
33812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
33822764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
33839566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
33849371c9d4SSatish Balay   if (x) {
33859371c9d4SSatish Balay     PetscValidPointer(x, 2);
33869371c9d4SSatish Balay     *x = prob->x;
33879371c9d4SSatish Balay   }
33889371c9d4SSatish Balay   if (basisReal) {
33899371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
33909371c9d4SSatish Balay     *basisReal = prob->basisReal;
33919371c9d4SSatish Balay   }
33929371c9d4SSatish Balay   if (basisDerReal) {
33939371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
33949371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
33959371c9d4SSatish Balay   }
33969371c9d4SSatish Balay   if (testReal) {
33979371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
33989371c9d4SSatish Balay     *testReal = prob->testReal;
33999371c9d4SSatish Balay   }
34009371c9d4SSatish Balay   if (testDerReal) {
34019371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
34029371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
34039371c9d4SSatish Balay   }
34043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34052764a2aaSMatthew G. Knepley }
34062764a2aaSMatthew G. Knepley 
340758ebd649SToby Isaac /*@C
3408dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3409dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3410dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
341158ebd649SToby Isaac 
341220f4b53cSBarry Smith   Collective
3413783e2ec8SMatthew G. Knepley 
341458ebd649SToby Isaac   Input Parameters:
341558ebd649SToby Isaac + ds       - The PetscDS object
3416dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
341758ebd649SToby Isaac . name     - The BC name
341845480ffeSMatthew G. Knepley . label    - The label defining constrained points
3419dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
342045480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
342158ebd649SToby Isaac . field    - The field to constrain
342245480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
342358ebd649SToby Isaac . comps    - An array of constrained component numbers
342458ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3425a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
342658ebd649SToby Isaac - ctx      - An optional user context for bcFunc
342758ebd649SToby Isaac 
34282fe279fdSBarry Smith   Output Parameter:
342960225df5SJacob Faibussowitsch . bd - The boundary number
343045480ffeSMatthew G. Knepley 
343158ebd649SToby Isaac   Options Database Keys:
343258ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
343358ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
343458ebd649SToby Isaac 
3435dce8aebaSBarry Smith   Level: developer
3436dce8aebaSBarry Smith 
343756cf3b9cSMatthew G. Knepley   Note:
343860225df5SJacob Faibussowitsch 
343920f4b53cSBarry Smith   Both `bcFunc` and `bcFunc_t` will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, Then the calling sequence is:
344056cf3b9cSMatthew G. Knepley 
344120f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
344256cf3b9cSMatthew G. Knepley 
3443dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3444dce8aebaSBarry Smith .vb
344520f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3446dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3447dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3448dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3449dce8aebaSBarry Smith .ve
345056cf3b9cSMatthew G. Knepley + dim - the spatial dimension
345156cf3b9cSMatthew G. Knepley . Nf - the number of fields
345256cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
345356cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
345456cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
345556cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
345656cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
345756cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
345856cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
345956cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
346056cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
346156cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
346256cf3b9cSMatthew G. Knepley . t - current time
346356cf3b9cSMatthew G. Knepley . x - coordinates of the current point
346456cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
346556cf3b9cSMatthew G. Knepley . constants - constant parameters
346656cf3b9cSMatthew G. Knepley - bcval - output values at the current point
346756cf3b9cSMatthew G. Knepley 
3468dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
346958ebd649SToby Isaac @*/
3470d71ae5a4SJacob 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)
3471d71ae5a4SJacob Faibussowitsch {
347245480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
347345480ffeSMatthew G. Knepley   PetscInt    n    = 0;
347445480ffeSMatthew G. Knepley   const char *lname;
347558ebd649SToby Isaac 
347658ebd649SToby Isaac   PetscFunctionBegin;
347758ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3478783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
347945480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
348045480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
348145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
348245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
348345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3484dce9da9cSMatthew 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);
3485d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3486d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3487d57bb9dbSMatthew G. Knepley     PetscInt  c;
3488d57bb9dbSMatthew G. Knepley 
34899566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
349063a3b9bcSJacob 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);
3491d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
34921dca8a05SBarry 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);
3493d57bb9dbSMatthew G. Knepley     }
3494d57bb9dbSMatthew G. Knepley   }
34959566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34979566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35009566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35019566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35029566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35039566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
35049566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3505f971fd6bSMatthew G. Knepley   b->type   = type;
350645480ffeSMatthew G. Knepley   b->label  = label;
350745480ffeSMatthew G. Knepley   b->Nv     = Nv;
350858ebd649SToby Isaac   b->field  = field;
350945480ffeSMatthew G. Knepley   b->Nc     = Nc;
351058ebd649SToby Isaac   b->func   = bcFunc;
351156cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
351258ebd649SToby Isaac   b->ctx    = ctx;
351345480ffeSMatthew G. Knepley   b->next   = NULL;
351445480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
351545480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
351645480ffeSMatthew G. Knepley   while (head) {
351745480ffeSMatthew G. Knepley     if (!head->next) {
351845480ffeSMatthew G. Knepley       head->next = b;
351945480ffeSMatthew G. Knepley       head       = b;
352045480ffeSMatthew G. Knepley     }
352145480ffeSMatthew G. Knepley     head = head->next;
352245480ffeSMatthew G. Knepley     ++n;
352345480ffeSMatthew G. Knepley   }
35249371c9d4SSatish Balay   if (bd) {
35259371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
35269371c9d4SSatish Balay     *bd = n;
35279371c9d4SSatish Balay   }
35283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352945480ffeSMatthew G. Knepley }
353045480ffeSMatthew G. Knepley 
353145480ffeSMatthew G. Knepley /*@C
3532dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3533dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that
3534dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
353545480ffeSMatthew G. Knepley 
353620f4b53cSBarry Smith   Collective
353745480ffeSMatthew G. Knepley 
353845480ffeSMatthew G. Knepley   Input Parameters:
3539dce8aebaSBarry Smith + ds       - The `PetscDS` object
3540dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
354145480ffeSMatthew G. Knepley . name     - The BC name
354245480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3543dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
354445480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
354545480ffeSMatthew G. Knepley . field    - The field to constrain
354645480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
354745480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
354845480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3549a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
355045480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
355145480ffeSMatthew G. Knepley 
35522fe279fdSBarry Smith   Output Parameter:
355360225df5SJacob Faibussowitsch . bd - The boundary number
355445480ffeSMatthew G. Knepley 
355545480ffeSMatthew G. Knepley   Options Database Keys:
355645480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
355745480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
355845480ffeSMatthew G. Knepley 
355920f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3560dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3561dce8aebaSBarry Smith .vb
356220f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3563dce8aebaSBarry Smith .ve
3564dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3565dce8aebaSBarry Smith .vb
356620f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3567dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3568dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3569dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3570dce8aebaSBarry Smith .ve
357145480ffeSMatthew G. Knepley + dim - the spatial dimension
357245480ffeSMatthew G. Knepley . Nf - the number of fields
357345480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
357445480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
357545480ffeSMatthew G. Knepley . u - each field evaluated at the current point
357645480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
357745480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
357845480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
357945480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
358045480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
358145480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
358245480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
358345480ffeSMatthew G. Knepley . t - current time
358445480ffeSMatthew G. Knepley . x - coordinates of the current point
358545480ffeSMatthew G. Knepley . numConstants - number of constant parameters
358645480ffeSMatthew G. Knepley . constants - constant parameters
358745480ffeSMatthew G. Knepley - bcval - output values at the current point
358845480ffeSMatthew G. Knepley 
358945480ffeSMatthew G. Knepley   Level: developer
359045480ffeSMatthew G. Knepley 
3591dce8aebaSBarry Smith   Note:
3592dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3593dce8aebaSBarry Smith 
3594dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
359545480ffeSMatthew G. Knepley @*/
3596d71ae5a4SJacob 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)
3597d71ae5a4SJacob Faibussowitsch {
359845480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
359945480ffeSMatthew G. Knepley   PetscInt   n    = 0;
360045480ffeSMatthew G. Knepley 
360145480ffeSMatthew G. Knepley   PetscFunctionBegin;
360245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
360345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
360445480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
360545480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
360645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
360745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
360845480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
36099566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
36109566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
36119566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
36129566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
36139566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
36149566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
36159566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
36169566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
36179566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
361845480ffeSMatthew G. Knepley   b->type   = type;
361945480ffeSMatthew G. Knepley   b->label  = NULL;
362045480ffeSMatthew G. Knepley   b->Nv     = Nv;
362145480ffeSMatthew G. Knepley   b->field  = field;
362245480ffeSMatthew G. Knepley   b->Nc     = Nc;
362345480ffeSMatthew G. Knepley   b->func   = bcFunc;
362445480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
362545480ffeSMatthew G. Knepley   b->ctx    = ctx;
362645480ffeSMatthew G. Knepley   b->next   = NULL;
362745480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
362845480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
362945480ffeSMatthew G. Knepley   while (head) {
363045480ffeSMatthew G. Knepley     if (!head->next) {
363145480ffeSMatthew G. Knepley       head->next = b;
363245480ffeSMatthew G. Knepley       head       = b;
363345480ffeSMatthew G. Knepley     }
363445480ffeSMatthew G. Knepley     head = head->next;
363545480ffeSMatthew G. Knepley     ++n;
363645480ffeSMatthew G. Knepley   }
36379371c9d4SSatish Balay   if (bd) {
36389371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
36399371c9d4SSatish Balay     *bd = n;
36409371c9d4SSatish Balay   }
36413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
364258ebd649SToby Isaac }
364358ebd649SToby Isaac 
3644b67eacb3SMatthew G. Knepley /*@C
3645dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3646dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals
3647dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3648b67eacb3SMatthew G. Knepley 
3649b67eacb3SMatthew G. Knepley   Input Parameters:
3650dce8aebaSBarry Smith + ds       - The `PetscDS` object
3651b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3652dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3653b67eacb3SMatthew G. Knepley . name     - The BC name
365445480ffeSMatthew G. Knepley . label    - The label defining constrained points
3655dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
365645480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3657b67eacb3SMatthew G. Knepley . field    - The field to constrain
365845480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3659b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3660b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3661a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3662b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3663b67eacb3SMatthew G. Knepley 
3664b67eacb3SMatthew G. Knepley   Level: developer
3665b67eacb3SMatthew G. Knepley 
3666dce8aebaSBarry Smith   Note:
3667dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3668dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3669dce8aebaSBarry Smith 
3670dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3671b67eacb3SMatthew G. Knepley @*/
3672d71ae5a4SJacob 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)
3673d71ae5a4SJacob Faibussowitsch {
3674b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3675b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3676b67eacb3SMatthew G. Knepley 
3677b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3678b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3679b67eacb3SMatthew G. Knepley   while (b) {
3680b67eacb3SMatthew G. Knepley     if (n == bd) break;
3681b67eacb3SMatthew G. Knepley     b = b->next;
3682b67eacb3SMatthew G. Knepley     ++n;
3683b67eacb3SMatthew G. Knepley   }
368463a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3685b67eacb3SMatthew G. Knepley   if (name) {
36869566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
36879566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3688b67eacb3SMatthew G. Knepley   }
3689b67eacb3SMatthew G. Knepley   b->type = type;
369045480ffeSMatthew G. Knepley   if (label) {
369145480ffeSMatthew G. Knepley     const char *name;
369245480ffeSMatthew G. Knepley 
369345480ffeSMatthew G. Knepley     b->label = label;
36949566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
36959566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
36969566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
369745480ffeSMatthew G. Knepley   }
369845480ffeSMatthew G. Knepley   if (Nv >= 0) {
369945480ffeSMatthew G. Knepley     b->Nv = Nv;
37009566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
37019566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
37029566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
370345480ffeSMatthew G. Knepley   }
370445480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
370545480ffeSMatthew G. Knepley   if (Nc >= 0) {
370645480ffeSMatthew G. Knepley     b->Nc = Nc;
37079566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
37089566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
37099566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
371045480ffeSMatthew G. Knepley   }
371145480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
371245480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
371345480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
37143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3715b67eacb3SMatthew G. Knepley }
3716b67eacb3SMatthew G. Knepley 
371758ebd649SToby Isaac /*@
371858ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
371958ebd649SToby Isaac 
37202fe279fdSBarry Smith   Input Parameter:
3721dce8aebaSBarry Smith . ds - The `PetscDS` object
372258ebd649SToby Isaac 
37232fe279fdSBarry Smith   Output Parameter:
372458ebd649SToby Isaac . numBd - The number of BC
372558ebd649SToby Isaac 
372658ebd649SToby Isaac   Level: intermediate
372758ebd649SToby Isaac 
3728dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
372958ebd649SToby Isaac @*/
3730d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3731d71ae5a4SJacob Faibussowitsch {
373258ebd649SToby Isaac   DSBoundary b = ds->boundary;
373358ebd649SToby Isaac 
373458ebd649SToby Isaac   PetscFunctionBegin;
373558ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3736dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
373758ebd649SToby Isaac   *numBd = 0;
37389371c9d4SSatish Balay   while (b) {
37399371c9d4SSatish Balay     ++(*numBd);
37409371c9d4SSatish Balay     b = b->next;
37419371c9d4SSatish Balay   }
37423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
374358ebd649SToby Isaac }
374458ebd649SToby Isaac 
374558ebd649SToby Isaac /*@C
37469a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
374758ebd649SToby Isaac 
374858ebd649SToby Isaac   Input Parameters:
3749dce8aebaSBarry Smith + ds - The `PetscDS` object
375058ebd649SToby Isaac - bd - The BC number
375158ebd649SToby Isaac 
375258ebd649SToby Isaac   Output Parameters:
3753dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3754dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
375558ebd649SToby Isaac . name   - The BC name
375645480ffeSMatthew G. Knepley . label  - The label defining constrained points
3757dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
375845480ffeSMatthew G. Knepley . values - An array of ids for constrained points
375958ebd649SToby Isaac . field  - The field to constrain
376045480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
376158ebd649SToby Isaac . comps  - An array of constrained component numbers
376260225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
376360225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
376458ebd649SToby Isaac - ctx    - An optional user context for bcFunc
376558ebd649SToby Isaac 
376658ebd649SToby Isaac   Options Database Keys:
376758ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
376858ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
376958ebd649SToby Isaac 
377058ebd649SToby Isaac   Level: developer
377158ebd649SToby Isaac 
3772dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
377358ebd649SToby Isaac @*/
3774d71ae5a4SJacob 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)
3775d71ae5a4SJacob Faibussowitsch {
377658ebd649SToby Isaac   DSBoundary b = ds->boundary;
377758ebd649SToby Isaac   PetscInt   n = 0;
377858ebd649SToby Isaac 
377958ebd649SToby Isaac   PetscFunctionBegin;
378058ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
378158ebd649SToby Isaac   while (b) {
378258ebd649SToby Isaac     if (n == bd) break;
378358ebd649SToby Isaac     b = b->next;
378458ebd649SToby Isaac     ++n;
378558ebd649SToby Isaac   }
378663a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
378745480ffeSMatthew G. Knepley   if (wf) {
378845480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
378945480ffeSMatthew G. Knepley     *wf = b->wf;
379045480ffeSMatthew G. Knepley   }
3791f971fd6bSMatthew G. Knepley   if (type) {
379245480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3793f971fd6bSMatthew G. Knepley     *type = b->type;
379458ebd649SToby Isaac   }
379558ebd649SToby Isaac   if (name) {
379645480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
379758ebd649SToby Isaac     *name = b->name;
379858ebd649SToby Isaac   }
379945480ffeSMatthew G. Knepley   if (label) {
380045480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
380145480ffeSMatthew G. Knepley     *label = b->label;
380245480ffeSMatthew G. Knepley   }
380345480ffeSMatthew G. Knepley   if (Nv) {
380445480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
380545480ffeSMatthew G. Knepley     *Nv = b->Nv;
380645480ffeSMatthew G. Knepley   }
380745480ffeSMatthew G. Knepley   if (values) {
380845480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
380945480ffeSMatthew G. Knepley     *values = b->values;
381058ebd649SToby Isaac   }
381158ebd649SToby Isaac   if (field) {
381245480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
381358ebd649SToby Isaac     *field = b->field;
381458ebd649SToby Isaac   }
381545480ffeSMatthew G. Knepley   if (Nc) {
381645480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
381745480ffeSMatthew G. Knepley     *Nc = b->Nc;
381858ebd649SToby Isaac   }
381958ebd649SToby Isaac   if (comps) {
382045480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
382158ebd649SToby Isaac     *comps = b->comps;
382258ebd649SToby Isaac   }
382358ebd649SToby Isaac   if (func) {
382445480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
382558ebd649SToby Isaac     *func = b->func;
382658ebd649SToby Isaac   }
382756cf3b9cSMatthew G. Knepley   if (func_t) {
382845480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
382956cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
383056cf3b9cSMatthew G. Knepley   }
383158ebd649SToby Isaac   if (ctx) {
383245480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
383358ebd649SToby Isaac     *ctx = b->ctx;
383458ebd649SToby Isaac   }
38353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
383658ebd649SToby Isaac }
383758ebd649SToby Isaac 
3838d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3839d71ae5a4SJacob Faibussowitsch {
384045480ffeSMatthew G. Knepley   PetscFunctionBegin;
38419566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
38429566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
38439566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
38449566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
38459566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
384645480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
384745480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
384845480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
38499566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
38509566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
385145480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
385245480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
38539566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
38549566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
385545480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
385645480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
385745480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
38583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
385945480ffeSMatthew G. Knepley }
386045480ffeSMatthew G. Knepley 
38619252d075SMatthew G. Knepley /*@
38629252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
38639252d075SMatthew G. Knepley 
386420f4b53cSBarry Smith   Not Collective
38659252d075SMatthew G. Knepley 
386636951cb5SMatthew G. Knepley   Input Parameters:
3867dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3868dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
386936951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
38709252d075SMatthew G. Knepley 
38719252d075SMatthew G. Knepley   Output Parameter:
3872dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
38739252d075SMatthew G. Knepley 
38749252d075SMatthew G. Knepley   Level: intermediate
38759252d075SMatthew G. Knepley 
3876dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38779252d075SMatthew G. Knepley @*/
3878d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3879d71ae5a4SJacob Faibussowitsch {
388045480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3881dff059c6SToby Isaac 
3882dff059c6SToby Isaac   PetscFunctionBegin;
388336951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
388436951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
38853ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
38869566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
388736951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
388836951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3889dff059c6SToby Isaac     DSBoundary bNew;
389036951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3891dff059c6SToby Isaac 
389236951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
389336951cb5SMatthew G. Knepley       PetscInt f;
389436951cb5SMatthew G. Knepley 
38959371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
38969371c9d4SSatish Balay         if (b->field == fields[f]) break;
389736951cb5SMatthew G. Knepley       if (f == numFields) continue;
389836951cb5SMatthew G. Knepley       fieldNew = f;
389936951cb5SMatthew G. Knepley     }
39009566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
390136951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3902dff059c6SToby Isaac     *lastnext   = bNew;
3903dff059c6SToby Isaac     lastnext    = &(bNew->next);
3904dff059c6SToby Isaac   }
39053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3906dff059c6SToby Isaac }
3907dff059c6SToby Isaac 
39086c1eb96dSMatthew G. Knepley /*@
3909dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
391045480ffeSMatthew G. Knepley 
391120f4b53cSBarry Smith   Not Collective
391245480ffeSMatthew G. Knepley 
391345480ffeSMatthew G. Knepley   Input Parameter:
3914dce8aebaSBarry Smith . ds - The `PetscDS` object
391545480ffeSMatthew G. Knepley 
391645480ffeSMatthew G. Knepley   Level: intermediate
391745480ffeSMatthew G. Knepley 
3918dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
391945480ffeSMatthew G. Knepley @*/
3920d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3921d71ae5a4SJacob Faibussowitsch {
392245480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
392345480ffeSMatthew G. Knepley 
392445480ffeSMatthew G. Knepley   PetscFunctionBegin;
392545480ffeSMatthew G. Knepley   while (next) {
392645480ffeSMatthew G. Knepley     DSBoundary b = next;
392745480ffeSMatthew G. Knepley 
392845480ffeSMatthew G. Knepley     next = b->next;
39299566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
39309566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
39319566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
39329566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
39339566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
39349566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
393545480ffeSMatthew G. Knepley   }
39363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
393745480ffeSMatthew G. Knepley }
393845480ffeSMatthew G. Knepley 
393945480ffeSMatthew G. Knepley /*@
39406c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
39416c1eb96dSMatthew G. Knepley 
394220f4b53cSBarry Smith   Not Collective
39436c1eb96dSMatthew G. Knepley 
3944d8d19677SJose E. Roman   Input Parameters:
3945dce8aebaSBarry Smith + prob      - The `PetscDS` object
39466c1eb96dSMatthew G. Knepley . numFields - Number of new fields
39476c1eb96dSMatthew G. Knepley - fields    - Old field number for each new field
39486c1eb96dSMatthew G. Knepley 
39496c1eb96dSMatthew G. Knepley   Output Parameter:
3950dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39516c1eb96dSMatthew G. Knepley 
39526c1eb96dSMatthew G. Knepley   Level: intermediate
39536c1eb96dSMatthew G. Knepley 
3954dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39556c1eb96dSMatthew G. Knepley @*/
3956d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3957d71ae5a4SJacob Faibussowitsch {
39586c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
39596c1eb96dSMatthew G. Knepley 
39606c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
39616c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3962dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
39636c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
396645480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
39676c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39686c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
39696c1eb96dSMatthew G. Knepley     PetscObject    disc;
39706c1eb96dSMatthew G. Knepley 
39716c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
39729566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
39739566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
39746c1eb96dSMatthew G. Knepley   }
39753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39766c1eb96dSMatthew G. Knepley }
39776c1eb96dSMatthew G. Knepley 
39786c1eb96dSMatthew G. Knepley /*@
39799252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
39809252d075SMatthew G. Knepley 
398120f4b53cSBarry Smith   Not Collective
39829252d075SMatthew G. Knepley 
3983d8d19677SJose E. Roman   Input Parameters:
3984dce8aebaSBarry Smith + prob      - The `PetscDS` object
39859252d075SMatthew G. Knepley . numFields - Number of new fields
39869252d075SMatthew G. Knepley - fields    - Old field number for each new field
39879252d075SMatthew G. Knepley 
39889252d075SMatthew G. Knepley   Output Parameter:
3989dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39909252d075SMatthew G. Knepley 
39919252d075SMatthew G. Knepley   Level: intermediate
39929252d075SMatthew G. Knepley 
3993dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39949252d075SMatthew G. Knepley @*/
3995d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3996d71ae5a4SJacob Faibussowitsch {
39979252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
39989252d075SMatthew G. Knepley 
39999252d075SMatthew G. Knepley   PetscFunctionBegin;
40009252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4001dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
40029252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
40039566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40049566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
400563a3b9bcSJacob 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);
40069252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
40079252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
40089252d075SMatthew G. Knepley     PetscPointFunc   obj;
40099252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
40109252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
40119252d075SMatthew G. Knepley     PetscRiemannFunc r;
40129252d075SMatthew G. Knepley 
4013c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
40149566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
40159566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
40169566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
40179566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
40189566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
40199566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
40209566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
40219566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
40229252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
40239252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
40249252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
40259252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
40269252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
40279252d075SMatthew G. Knepley 
4028c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
40299566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
40309566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
40319566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
40329566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
40339566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
40349566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
40359252d075SMatthew G. Knepley     }
40369252d075SMatthew G. Knepley   }
40373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40389252d075SMatthew G. Knepley }
40399252d075SMatthew G. Knepley 
4040da51fcedSMatthew G. Knepley /*@
4041dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
4042da51fcedSMatthew G. Knepley 
404320f4b53cSBarry Smith   Not Collective
4044da51fcedSMatthew G. Knepley 
4045da51fcedSMatthew G. Knepley   Input Parameter:
4046dce8aebaSBarry Smith . prob - The `PetscDS` object
4047da51fcedSMatthew G. Knepley 
4048da51fcedSMatthew G. Knepley   Output Parameter:
4049dce8aebaSBarry Smith . newprob - The `PetscDS` copy
4050da51fcedSMatthew G. Knepley 
4051da51fcedSMatthew G. Knepley   Level: intermediate
4052da51fcedSMatthew G. Knepley 
4053dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
4054da51fcedSMatthew G. Knepley @*/
4055d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
4056d71ae5a4SJacob Faibussowitsch {
4057b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
40589252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4059da51fcedSMatthew G. Knepley 
4060da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4061da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4062da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40639566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
406563a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
40669566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
40679566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
40689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
40693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40709252d075SMatthew G. Knepley }
407145480ffeSMatthew G. Knepley 
40729252d075SMatthew G. Knepley /*@
4073dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4074da51fcedSMatthew G. Knepley 
407520f4b53cSBarry Smith   Not Collective
40769252d075SMatthew G. Knepley 
40779252d075SMatthew G. Knepley   Input Parameter:
4078dce8aebaSBarry Smith . prob - The `PetscDS` object
40799252d075SMatthew G. Knepley 
40809252d075SMatthew G. Knepley   Output Parameter:
4081dce8aebaSBarry Smith . newprob - The `PetscDS` copy
40829252d075SMatthew G. Knepley 
40839252d075SMatthew G. Knepley   Level: intermediate
40849252d075SMatthew G. Knepley 
4085dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
40869252d075SMatthew G. Knepley @*/
4087d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4088d71ae5a4SJacob Faibussowitsch {
40899252d075SMatthew G. Knepley   PetscInt           Nc;
40909252d075SMatthew G. Knepley   const PetscScalar *constants;
40919252d075SMatthew G. Knepley 
40929252d075SMatthew G. Knepley   PetscFunctionBegin;
40939252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
40949252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40959566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
40969566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
40973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4098da51fcedSMatthew G. Knepley }
4099da51fcedSMatthew G. Knepley 
410045480ffeSMatthew G. Knepley /*@
4101dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
410245480ffeSMatthew G. Knepley 
410320f4b53cSBarry Smith   Not Collective
410445480ffeSMatthew G. Knepley 
410545480ffeSMatthew G. Knepley   Input Parameter:
4106dce8aebaSBarry Smith . ds - The `PetscDS` object
410745480ffeSMatthew G. Knepley 
410845480ffeSMatthew G. Knepley   Output Parameter:
4109dce8aebaSBarry Smith . newds - The `PetscDS` copy
411045480ffeSMatthew G. Knepley 
411145480ffeSMatthew G. Knepley   Level: intermediate
411245480ffeSMatthew G. Knepley 
4113dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
411445480ffeSMatthew G. Knepley @*/
4115d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4116d71ae5a4SJacob Faibussowitsch {
411745480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
411845480ffeSMatthew G. Knepley   void                *ctx;
411945480ffeSMatthew G. Knepley   PetscInt             Nf, f;
412045480ffeSMatthew G. Knepley 
412145480ffeSMatthew G. Knepley   PetscFunctionBegin;
412245480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
412345480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
41249566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
412545480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
41269566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
41279566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
41289566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
41299566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
413045480ffeSMatthew G. Knepley   }
41313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
413245480ffeSMatthew G. Knepley }
413345480ffeSMatthew G. Knepley 
413407218a29SMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, DM dmNew, PetscDS dsNew)
413507218a29SMatthew G. Knepley {
413607218a29SMatthew G. Knepley   DSBoundary b;
413707218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
413807218a29SMatthew G. Knepley   PetscBool  isCohesive;
413907218a29SMatthew G. Knepley   void      *ctx;
414007218a29SMatthew G. Knepley 
414107218a29SMatthew G. Knepley   PetscFunctionBegin;
414207218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
414307218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
414407218a29SMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew));
414507218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
414607218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
414707218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
414807218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
414907218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
415007218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
415107218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
415207218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
415307218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
415407218a29SMatthew G. Knepley   }
415507218a29SMatthew G. Knepley   if (Nf) {
415607218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
415707218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
415807218a29SMatthew G. Knepley   }
415907218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
416007218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
416107218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
416207218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
416307218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
416407218a29SMatthew G. Knepley   }
416507218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
416607218a29SMatthew G. Knepley }
416707218a29SMatthew G. Knepley 
4168d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4169d71ae5a4SJacob Faibussowitsch {
4170df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4171b1353e8eSMatthew G. Knepley 
4172b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4173b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4174b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
41759371c9d4SSatish Balay   if (height == 0) {
41769371c9d4SSatish Balay     *subprob = prob;
41773ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
41789371c9d4SSatish Balay   }
41799566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41809566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
418163a3b9bcSJacob 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);
41829566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4183df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4184b1353e8eSMatthew G. Knepley     PetscInt cdim;
4185b1353e8eSMatthew G. Knepley 
41869566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
41879566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
41889566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4189b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4190b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4191b1353e8eSMatthew G. Knepley       PetscObject  obj;
4192b1353e8eSMatthew G. Knepley       PetscClassId id;
4193b1353e8eSMatthew G. Knepley 
41949566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
41959566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
41969566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
419763a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
41989566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4199b1353e8eSMatthew G. Knepley     }
4200b1353e8eSMatthew G. Knepley   }
4201df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
42023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4203b1353e8eSMatthew G. Knepley }
4204b1353e8eSMatthew G. Knepley 
42054366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
42064366bac7SMatthew G. Knepley {
42074366bac7SMatthew G. Knepley   IS              permIS;
42084366bac7SMatthew G. Knepley   PetscQuadrature quad;
42094366bac7SMatthew G. Knepley   DMPolytopeType  ct;
42104366bac7SMatthew G. Knepley   const PetscInt *perm;
42114366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
42124366bac7SMatthew G. Knepley 
42134366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
42144366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
42154366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
42164366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
42174366bac7SMatthew 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);
42184366bac7SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangments(ct) / 2;
42194366bac7SMatthew 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);
42204366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
42214366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
42224366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
42234366bac7SMatthew G. Knepley   *qperm = perm[q];
42244366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
42254366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
42264366bac7SMatthew G. Knepley }
42274366bac7SMatthew G. Knepley 
4228d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4229d71ae5a4SJacob Faibussowitsch {
4230c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4231c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4232c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4233c7bd5f0bSMatthew G. Knepley 
4234c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4235c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4236665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
4237665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
42389566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
423963a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
42409566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4241665f567fSMatthew G. Knepley   if (obj) {
42429566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4243665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4244665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4245665f567fSMatthew G. Knepley   }
42463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4247c7bd5f0bSMatthew G. Knepley }
4248c7bd5f0bSMatthew G. Knepley 
4249d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4250d71ae5a4SJacob Faibussowitsch {
42512764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42529566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
42533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42542764a2aaSMatthew G. Knepley }
42552764a2aaSMatthew G. Knepley 
4256d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4257d71ae5a4SJacob Faibussowitsch {
42582764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42596528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
42606528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
42616528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
42626528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
42633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42642764a2aaSMatthew G. Knepley }
42652764a2aaSMatthew G. Knepley 
42662764a2aaSMatthew G. Knepley /*MC
42672764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
42682764a2aaSMatthew G. Knepley 
42692764a2aaSMatthew G. Knepley   Level: intermediate
42702764a2aaSMatthew G. Knepley 
4271db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
42722764a2aaSMatthew G. Knepley M*/
42732764a2aaSMatthew G. Knepley 
4274d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4275d71ae5a4SJacob Faibussowitsch {
42762764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
42772764a2aaSMatthew G. Knepley 
42782764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42796528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
42804dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
42816528b96dSMatthew G. Knepley   ds->data = b;
42822764a2aaSMatthew G. Knepley 
42839566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
42843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42852764a2aaSMatthew G. Knepley }
4286