xref: /petsc/src/dm/dt/interface/dtds.c (revision f4f49eeac7efa77fffa46b7ff95a3ed169f659ed)
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);
1164f572ea9SToby Isaac   PetscAssertPointer(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__)
201a8f51744SPierre Jolivet       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic")
20215943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
203a8f51744SPierre 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       }
217a8f51744SPierre 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;
377e59ddd55SMatthew G. Knepley   PetscInt       maxOrder[4] = {-2, -2, -2, -2};
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;
5578434afd1SBarry Smith   PetscSimplePointFn **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);
628*f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*ds, PETSCDS_CLASSID, 1);
6292764a2aaSMatthew G. Knepley 
630*f4f49eeaSPierre Jolivet   if (--((PetscObject)*ds)->refct > 0) {
6319371c9d4SSatish Balay     *ds = NULL;
6323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6339371c9d4SSatish Balay   }
634*f4f49eeaSPierre Jolivet   ((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));
648*f4f49eeaSPierre Jolivet   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) {
65285036b15SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangements((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;
6824f572ea9SToby Isaac   PetscAssertPointer(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);
7214f572ea9SToby Isaac   PetscAssertPointer(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);
7454f572ea9SToby Isaac   PetscAssertPointer(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);
7814f572ea9SToby Isaac   PetscAssertPointer(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);
8284f572ea9SToby Isaac   PetscAssertPointer(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);
8734f572ea9SToby Isaac   PetscAssertPointer(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);
8994f572ea9SToby Isaac   PetscAssertPointer(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);
9254f572ea9SToby Isaac   PetscAssertPointer(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));
9784f572ea9SToby Isaac   PetscAssertPointer(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));
10034f572ea9SToby Isaac   PetscAssertPointer(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);
10284f572ea9SToby Isaac   PetscAssertPointer(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);
10524f572ea9SToby Isaac   if (disc) PetscAssertPointer(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);
10914f572ea9SToby Isaac   PetscAssertPointer(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);
11924f572ea9SToby Isaac   PetscAssertPointer(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);
12414f572ea9SToby Isaac   PetscAssertPointer(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 
1279a4e35b19SJacob Faibussowitsch   Output Parameter:
1280c8943706SMatthew G. Knepley . obj - integrand for the test function term
1281c8943706SMatthew G. Knepley 
1282c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1283c8943706SMatthew G. Knepley + dim          - the spatial dimension
1284c8943706SMatthew G. Knepley . Nf           - the number of fields
1285a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1286c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1287c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1288c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1289c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1290c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1291c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1292c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1293c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1294c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1295c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1296c8943706SMatthew G. Knepley . t            - current time
1297c8943706SMatthew G. Knepley . x            - coordinates of the current point
1298c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1299c8943706SMatthew G. Knepley . constants    - constant parameters
1300c8943706SMatthew G. Knepley - obj          - output values at the current point
1301c8943706SMatthew G. Knepley 
1302c8943706SMatthew G. Knepley   Level: intermediate
1303c8943706SMatthew G. Knepley 
1304c8943706SMatthew G. Knepley   Note:
13051d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi obj(u, u_t, \nabla u, x, t)$
1306c8943706SMatthew G. Knepley 
1307c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetObjective()`, `PetscDSGetResidual()`
1308c8943706SMatthew G. Knepley @*/
1309d71ae5a4SJacob 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[]))
1310d71ae5a4SJacob Faibussowitsch {
13116528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
13126528b96dSMatthew G. Knepley   PetscInt        n;
13136528b96dSMatthew G. Knepley 
13142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13164f572ea9SToby Isaac   PetscAssertPointer(obj, 3);
131763a3b9bcSJacob 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);
13189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
13196528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
13203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13212764a2aaSMatthew G. Knepley }
13222764a2aaSMatthew G. Knepley 
1323c8943706SMatthew G. Knepley /*@C
1324c8943706SMatthew G. Knepley   PetscDSSetObjective - Set the pointwise objective function for a given test field
1325c8943706SMatthew G. Knepley 
1326c8943706SMatthew G. Knepley   Not Collective
1327c8943706SMatthew G. Knepley 
1328c8943706SMatthew G. Knepley   Input Parameters:
1329c8943706SMatthew G. Knepley + ds  - The `PetscDS`
1330c8943706SMatthew G. Knepley . f   - The test field number
1331c8943706SMatthew G. Knepley - obj - integrand for the test function term
1332c8943706SMatthew G. Knepley 
1333c8943706SMatthew G. Knepley   Calling sequence of `obj`:
1334c8943706SMatthew G. Knepley + dim          - the spatial dimension
1335c8943706SMatthew G. Knepley . Nf           - the number of fields
1336a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1337c8943706SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1338c8943706SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1339c8943706SMatthew G. Knepley . u            - each field evaluated at the current point
1340c8943706SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1341c8943706SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1342c8943706SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1343c8943706SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1344c8943706SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1345c8943706SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1346c8943706SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1347c8943706SMatthew G. Knepley . t            - current time
1348c8943706SMatthew G. Knepley . x            - coordinates of the current point
1349c8943706SMatthew G. Knepley . numConstants - number of constant parameters
1350c8943706SMatthew G. Knepley . constants    - constant parameters
1351c8943706SMatthew G. Knepley - obj          - output values at the current point
1352c8943706SMatthew G. Knepley 
1353c8943706SMatthew G. Knepley   Level: intermediate
1354c8943706SMatthew G. Knepley 
1355c8943706SMatthew G. Knepley   Note:
13561d27aa22SBarry Smith   We are using a first order FEM model for the weak form\: $  \int_\Omega \phi obj(u, u_t, \nabla u, x, t)$
1357c8943706SMatthew G. Knepley 
1358c8943706SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetObjective()`, `PetscDSSetResidual()`
1359c8943706SMatthew G. Knepley @*/
1360d71ae5a4SJacob 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[]))
1361d71ae5a4SJacob Faibussowitsch {
13622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13636528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
13646528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
136563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13669566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
13673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13682764a2aaSMatthew G. Knepley }
13692764a2aaSMatthew G. Knepley 
1370194d53e6SMatthew G. Knepley /*@C
1371194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1372194d53e6SMatthew G. Knepley 
137320f4b53cSBarry Smith   Not Collective
1374194d53e6SMatthew G. Knepley 
1375194d53e6SMatthew G. Knepley   Input Parameters:
1376dce8aebaSBarry Smith + ds - The `PetscDS`
1377194d53e6SMatthew G. Knepley - f  - The test field number
1378194d53e6SMatthew G. Knepley 
1379194d53e6SMatthew G. Knepley   Output Parameters:
1380194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1381194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1382194d53e6SMatthew G. Knepley 
1383a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1384194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1385194d53e6SMatthew G. Knepley . Nf           - the number of fields
1386a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1387194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1388194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1389194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1390194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1391194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1392194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1393194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1394194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1395194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1396194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1397194d53e6SMatthew G. Knepley . t            - current time
1398194d53e6SMatthew G. Knepley . x            - coordinates of the current point
139997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
140097b6e6e8SMatthew G. Knepley . constants    - constant parameters
1401194d53e6SMatthew G. Knepley - f0           - output values at the current point
1402194d53e6SMatthew G. Knepley 
1403194d53e6SMatthew G. Knepley   Level: intermediate
1404194d53e6SMatthew G. Knepley 
1405dce8aebaSBarry Smith   Note:
1406a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1407a4e35b19SJacob Faibussowitsch 
14081d27aa22SBarry 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)$
1409dce8aebaSBarry Smith 
1410dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1411194d53e6SMatthew G. Knepley @*/
1412a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1413d71ae5a4SJacob Faibussowitsch {
14146528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
14156528b96dSMatthew G. Knepley   PetscInt        n0, n1;
14166528b96dSMatthew G. Knepley 
14172764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14186528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
141963a3b9bcSJacob 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);
14209566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
14216528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
14226528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14242764a2aaSMatthew G. Knepley }
14252764a2aaSMatthew G. Knepley 
1426194d53e6SMatthew G. Knepley /*@C
1427194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1428194d53e6SMatthew G. Knepley 
142920f4b53cSBarry Smith   Not Collective
1430194d53e6SMatthew G. Knepley 
1431194d53e6SMatthew G. Knepley   Input Parameters:
1432dce8aebaSBarry Smith + ds - The `PetscDS`
1433194d53e6SMatthew G. Knepley . f  - The test field number
1434194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1435194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1436194d53e6SMatthew G. Knepley 
1437a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1438194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1439194d53e6SMatthew G. Knepley . Nf           - the number of fields
1440a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1441194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1442194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1443194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1444194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1445194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1446194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1447194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1448194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1449194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1450194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1451194d53e6SMatthew G. Knepley . t            - current time
1452194d53e6SMatthew G. Knepley . x            - coordinates of the current point
145397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
145497b6e6e8SMatthew G. Knepley . constants    - constant parameters
1455194d53e6SMatthew G. Knepley - f0           - output values at the current point
1456194d53e6SMatthew G. Knepley 
1457194d53e6SMatthew G. Knepley   Level: intermediate
1458194d53e6SMatthew G. Knepley 
1459dce8aebaSBarry Smith   Note:
1460a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1461a4e35b19SJacob Faibussowitsch 
14621d27aa22SBarry 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)$
1463dce8aebaSBarry Smith 
1464dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1465194d53e6SMatthew G. Knepley @*/
1466a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1467d71ae5a4SJacob Faibussowitsch {
14682764a2aaSMatthew G. Knepley   PetscFunctionBegin;
14696528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1470f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1471f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
147263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14752764a2aaSMatthew G. Knepley }
14762764a2aaSMatthew G. Knepley 
14773e75805dSMatthew G. Knepley /*@C
1478cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1479cb36c0f9SMatthew G. Knepley 
148020f4b53cSBarry Smith   Not Collective
1481cb36c0f9SMatthew G. Knepley 
1482cb36c0f9SMatthew G. Knepley   Input Parameters:
1483dce8aebaSBarry Smith + ds - The `PetscDS`
1484cb36c0f9SMatthew G. Knepley - f  - The test field number
1485cb36c0f9SMatthew G. Knepley 
1486cb36c0f9SMatthew G. Knepley   Output Parameters:
1487cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1488cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1489cb36c0f9SMatthew G. Knepley 
1490a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
1491cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1492cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1493a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1494cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1495cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1496cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1497cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1498cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1499cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1500cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1501cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1502cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1503cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1504cb36c0f9SMatthew G. Knepley . t            - current time
1505cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1506cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1507cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1508cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1509cb36c0f9SMatthew G. Knepley 
1510cb36c0f9SMatthew G. Knepley   Level: intermediate
1511cb36c0f9SMatthew G. Knepley 
1512dce8aebaSBarry Smith   Note:
1513a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1514a4e35b19SJacob Faibussowitsch 
15151d27aa22SBarry 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)$
1516dce8aebaSBarry Smith 
1517dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1518cb36c0f9SMatthew G. Knepley @*/
1519a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1520d71ae5a4SJacob Faibussowitsch {
1521cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1522cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1523cb36c0f9SMatthew G. Knepley 
1524cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1525cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
152663a3b9bcSJacob 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);
15279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1528cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1529cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
15303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1531cb36c0f9SMatthew G. Knepley }
1532cb36c0f9SMatthew G. Knepley 
1533cb36c0f9SMatthew G. Knepley /*@C
1534cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1535cb36c0f9SMatthew G. Knepley 
153620f4b53cSBarry Smith   Not Collective
1537cb36c0f9SMatthew G. Knepley 
1538cb36c0f9SMatthew G. Knepley   Input Parameters:
1539dce8aebaSBarry Smith + ds - The `PetscDS`
1540cb36c0f9SMatthew G. Knepley . f  - The test field number
1541cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1542cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1543cb36c0f9SMatthew G. Knepley 
1544a4e35b19SJacob Faibussowitsch   Calling sequence for the callbacks `f0`:
1545cb36c0f9SMatthew G. Knepley + dim          - the spatial dimension
1546cb36c0f9SMatthew G. Knepley . Nf           - the number of fields
1547a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1548cb36c0f9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1549cb36c0f9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1550cb36c0f9SMatthew G. Knepley . u            - each field evaluated at the current point
1551cb36c0f9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1552cb36c0f9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1553cb36c0f9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1554cb36c0f9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1555cb36c0f9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1556cb36c0f9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1557cb36c0f9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1558cb36c0f9SMatthew G. Knepley . t            - current time
1559cb36c0f9SMatthew G. Knepley . x            - coordinates of the current point
1560cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1561cb36c0f9SMatthew G. Knepley . constants    - constant parameters
1562cb36c0f9SMatthew G. Knepley - f0           - output values at the current point
1563cb36c0f9SMatthew G. Knepley 
1564cb36c0f9SMatthew G. Knepley   Level: intermediate
1565cb36c0f9SMatthew G. Knepley 
1566dce8aebaSBarry Smith   Note:
1567a4e35b19SJacob Faibussowitsch   `f1` has an identical form and is omitted for brevity.
1568a4e35b19SJacob Faibussowitsch 
15691d27aa22SBarry 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)$
1570dce8aebaSBarry Smith 
1571dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1572cb36c0f9SMatthew G. Knepley @*/
1573a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1574d71ae5a4SJacob Faibussowitsch {
1575cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1576cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1577cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1578cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
157963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1582cb36c0f9SMatthew G. Knepley }
1583cb36c0f9SMatthew G. Knepley 
1584cb36c0f9SMatthew G. Knepley /*@C
1585dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
15863e75805dSMatthew G. Knepley 
158720f4b53cSBarry Smith   Not Collective
15883e75805dSMatthew G. Knepley 
15893e75805dSMatthew G. Knepley   Input Parameter:
159060225df5SJacob Faibussowitsch . ds - The `PetscDS`
15913e75805dSMatthew G. Knepley 
15923e75805dSMatthew G. Knepley   Output Parameter:
15933e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15943e75805dSMatthew G. Knepley 
15953e75805dSMatthew G. Knepley   Level: intermediate
15963e75805dSMatthew G. Knepley 
1597dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15983e75805dSMatthew G. Knepley @*/
1599d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1600d71ae5a4SJacob Faibussowitsch {
16013e75805dSMatthew G. Knepley   PetscFunctionBegin;
16026528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
16043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16053e75805dSMatthew G. Knepley }
16063e75805dSMatthew G. Knepley 
1607194d53e6SMatthew G. Knepley /*@C
1608194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1609194d53e6SMatthew G. Knepley 
161020f4b53cSBarry Smith   Not Collective
1611194d53e6SMatthew G. Knepley 
1612194d53e6SMatthew G. Knepley   Input Parameters:
1613dce8aebaSBarry Smith + ds - The `PetscDS`
1614194d53e6SMatthew G. Knepley . f  - The test field number
1615194d53e6SMatthew G. Knepley - g  - The field number
1616194d53e6SMatthew G. Knepley 
1617194d53e6SMatthew G. Knepley   Output Parameters:
1618194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1619194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1620194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1621194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1622194d53e6SMatthew G. Knepley 
1623a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1624194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1625194d53e6SMatthew G. Knepley . Nf           - the number of fields
1626a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1627194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1628194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1629194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1630194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1631194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1632194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1633194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1634194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1635194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1636194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1637194d53e6SMatthew G. Knepley . t            - current time
16382aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1639194d53e6SMatthew G. Knepley . x            - coordinates of the current point
164097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
164197b6e6e8SMatthew G. Knepley . constants    - constant parameters
1642194d53e6SMatthew G. Knepley - g0           - output values at the current point
1643194d53e6SMatthew G. Knepley 
1644194d53e6SMatthew G. Knepley   Level: intermediate
1645194d53e6SMatthew G. Knepley 
1646dce8aebaSBarry Smith   Note:
1647a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
164860225df5SJacob Faibussowitsch 
1649a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
16501d27aa22SBarry Smith 
16511d27aa22SBarry Smith   $$
1652dce8aebaSBarry 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
16531d27aa22SBarry Smith   $$
1654dce8aebaSBarry Smith 
1655dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1656194d53e6SMatthew G. Knepley @*/
1657a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1658d71ae5a4SJacob Faibussowitsch {
16596528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
16606528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
16616528b96dSMatthew G. Knepley 
16622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16636528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
166463a3b9bcSJacob 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);
166563a3b9bcSJacob 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);
16669566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16676528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16686528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16696528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16706528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16722764a2aaSMatthew G. Knepley }
16732764a2aaSMatthew G. Knepley 
1674194d53e6SMatthew G. Knepley /*@C
1675194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1676194d53e6SMatthew G. Knepley 
167720f4b53cSBarry Smith   Not Collective
1678194d53e6SMatthew G. Knepley 
1679194d53e6SMatthew G. Knepley   Input Parameters:
1680dce8aebaSBarry Smith + ds - The `PetscDS`
1681194d53e6SMatthew G. Knepley . f  - The test field number
1682194d53e6SMatthew G. Knepley . g  - The field number
1683194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1684194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1685194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1686194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1687194d53e6SMatthew G. Knepley 
1688a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1689194d53e6SMatthew G. Knepley + dim          - the spatial dimension
1690194d53e6SMatthew G. Knepley . Nf           - the number of fields
1691a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1692194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1693194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1694194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
1695194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1696194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1697194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1698194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1699194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1700194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1701194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1702194d53e6SMatthew G. Knepley . t            - current time
17032aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1704194d53e6SMatthew G. Knepley . x            - coordinates of the current point
170597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
170697b6e6e8SMatthew G. Knepley . constants    - constant parameters
1707194d53e6SMatthew G. Knepley - g0           - output values at the current point
1708194d53e6SMatthew G. Knepley 
1709194d53e6SMatthew G. Knepley   Level: intermediate
1710194d53e6SMatthew G. Knepley 
1711dce8aebaSBarry Smith   Note:
1712a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
171360225df5SJacob Faibussowitsch 
1714a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1715dce8aebaSBarry 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
1716dce8aebaSBarry Smith 
1717dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1718194d53e6SMatthew G. Knepley @*/
1719a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1720d71ae5a4SJacob Faibussowitsch {
17212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
17226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
17232764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
17242764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
17252764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
17262764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
172763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
172863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
17299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
17303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17312764a2aaSMatthew G. Knepley }
17322764a2aaSMatthew G. Knepley 
1733475e0ac9SMatthew G. Knepley /*@C
1734dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
173555c1f793SMatthew G. Knepley 
173620f4b53cSBarry Smith   Not Collective
173755c1f793SMatthew G. Knepley 
173855c1f793SMatthew G. Knepley   Input Parameters:
1739dce8aebaSBarry Smith + prob      - The `PetscDS`
174055c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
174155c1f793SMatthew G. Knepley 
174255c1f793SMatthew G. Knepley   Level: intermediate
174355c1f793SMatthew G. Knepley 
1744dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
174555c1f793SMatthew G. Knepley @*/
1746d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1747d71ae5a4SJacob Faibussowitsch {
174855c1f793SMatthew G. Knepley   PetscFunctionBegin;
174955c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
175055c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
17513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
175255c1f793SMatthew G. Knepley }
175355c1f793SMatthew G. Knepley 
175455c1f793SMatthew G. Knepley /*@C
1755dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1756475e0ac9SMatthew G. Knepley 
175720f4b53cSBarry Smith   Not Collective
1758475e0ac9SMatthew G. Knepley 
1759475e0ac9SMatthew G. Knepley   Input Parameter:
176060225df5SJacob Faibussowitsch . ds - The `PetscDS`
1761475e0ac9SMatthew G. Knepley 
1762475e0ac9SMatthew G. Knepley   Output Parameter:
1763475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1764475e0ac9SMatthew G. Knepley 
1765475e0ac9SMatthew G. Knepley   Level: intermediate
1766475e0ac9SMatthew G. Knepley 
1767dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1768475e0ac9SMatthew G. Knepley @*/
1769d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1770d71ae5a4SJacob Faibussowitsch {
1771475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17726528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1773475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17743ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17759566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1777475e0ac9SMatthew G. Knepley }
1778475e0ac9SMatthew G. Knepley 
1779475e0ac9SMatthew G. Knepley /*@C
1780dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1781dce8aebaSBarry Smith   the system matrix is used to build the preconditioner.
1782475e0ac9SMatthew G. Knepley 
178320f4b53cSBarry Smith   Not Collective
1784475e0ac9SMatthew G. Knepley 
1785475e0ac9SMatthew G. Knepley   Input Parameters:
1786dce8aebaSBarry Smith + ds - The `PetscDS`
1787475e0ac9SMatthew G. Knepley . f  - The test field number
1788475e0ac9SMatthew G. Knepley - g  - The field number
1789475e0ac9SMatthew G. Knepley 
1790475e0ac9SMatthew G. Knepley   Output Parameters:
1791475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1792475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1793475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1794475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1795475e0ac9SMatthew G. Knepley 
1796a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1797475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1798475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1799a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1800475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1801475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1802475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1803475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1804475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1805475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1806475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1807475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1808475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1809475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1810475e0ac9SMatthew G. Knepley . t            - current time
1811475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1812475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
181397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
181497b6e6e8SMatthew G. Knepley . constants    - constant parameters
1815475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1816475e0ac9SMatthew G. Knepley 
1817475e0ac9SMatthew G. Knepley   Level: intermediate
1818475e0ac9SMatthew G. Knepley 
1819dce8aebaSBarry Smith   Note:
1820a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
1821a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1822dce8aebaSBarry 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
1823dce8aebaSBarry Smith 
1824dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1825475e0ac9SMatthew G. Knepley @*/
1826a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1827d71ae5a4SJacob Faibussowitsch {
18286528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
18296528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
18306528b96dSMatthew G. Knepley 
1831475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18326528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
183363a3b9bcSJacob 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);
183463a3b9bcSJacob 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);
18359566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
18366528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
18376528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
18386528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
18396528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
18403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1841475e0ac9SMatthew G. Knepley }
1842475e0ac9SMatthew G. Knepley 
1843475e0ac9SMatthew G. Knepley /*@C
1844dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1845dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1846475e0ac9SMatthew G. Knepley 
184720f4b53cSBarry Smith   Not Collective
1848475e0ac9SMatthew G. Knepley 
1849475e0ac9SMatthew G. Knepley   Input Parameters:
1850dce8aebaSBarry Smith + ds - The `PetscDS`
1851475e0ac9SMatthew G. Knepley . f  - The test field number
1852475e0ac9SMatthew G. Knepley . g  - The field number
1853475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1854475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1855475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1856475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1857475e0ac9SMatthew G. Knepley 
1858a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1859475e0ac9SMatthew G. Knepley + dim          - the spatial dimension
1860475e0ac9SMatthew G. Knepley . Nf           - the number of fields
1861a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1862475e0ac9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1863475e0ac9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1864475e0ac9SMatthew G. Knepley . u            - each field evaluated at the current point
1865475e0ac9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1866475e0ac9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1867475e0ac9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1868475e0ac9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1869475e0ac9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1870475e0ac9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1871475e0ac9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1872475e0ac9SMatthew G. Knepley . t            - current time
1873475e0ac9SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1874475e0ac9SMatthew G. Knepley . x            - coordinates of the current point
187597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
187697b6e6e8SMatthew G. Knepley . constants    - constant parameters
1877475e0ac9SMatthew G. Knepley - g0           - output values at the current point
1878475e0ac9SMatthew G. Knepley 
1879475e0ac9SMatthew G. Knepley   Level: intermediate
1880475e0ac9SMatthew G. Knepley 
1881dce8aebaSBarry Smith   Note:
1882a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
188360225df5SJacob Faibussowitsch 
1884a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1885dce8aebaSBarry 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
1886dce8aebaSBarry Smith 
1887dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1888475e0ac9SMatthew G. Knepley @*/
1889a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1890d71ae5a4SJacob Faibussowitsch {
1891475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18926528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1893475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1894475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1895475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1896475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
189763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
189863a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18999566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1901475e0ac9SMatthew G. Knepley }
1902475e0ac9SMatthew G. Knepley 
1903b7e05686SMatthew G. Knepley /*@C
1904b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1905b7e05686SMatthew G. Knepley 
190620f4b53cSBarry Smith   Not Collective
1907b7e05686SMatthew G. Knepley 
1908b7e05686SMatthew G. Knepley   Input Parameter:
1909dce8aebaSBarry Smith . ds - The `PetscDS`
1910b7e05686SMatthew G. Knepley 
1911b7e05686SMatthew G. Knepley   Output Parameter:
1912b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1913b7e05686SMatthew G. Knepley 
1914b7e05686SMatthew G. Knepley   Level: intermediate
1915b7e05686SMatthew G. Knepley 
1916dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1917b7e05686SMatthew G. Knepley @*/
1918d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1919d71ae5a4SJacob Faibussowitsch {
1920b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19216528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
19229566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
19233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1924b7e05686SMatthew G. Knepley }
1925b7e05686SMatthew G. Knepley 
1926b7e05686SMatthew G. Knepley /*@C
1927b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1928b7e05686SMatthew G. Knepley 
192920f4b53cSBarry Smith   Not Collective
1930b7e05686SMatthew G. Knepley 
1931b7e05686SMatthew G. Knepley   Input Parameters:
1932dce8aebaSBarry Smith + ds - The `PetscDS`
1933b7e05686SMatthew G. Knepley . f  - The test field number
1934b7e05686SMatthew G. Knepley - g  - The field number
1935b7e05686SMatthew G. Knepley 
1936b7e05686SMatthew G. Knepley   Output Parameters:
1937b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1938b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1939b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1940b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1941b7e05686SMatthew G. Knepley 
1942a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
1943b7e05686SMatthew G. Knepley + dim          - the spatial dimension
1944b7e05686SMatthew G. Knepley . Nf           - the number of fields
1945a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
1946b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
1947b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
1948b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
1949b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
1950b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
1951b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
1952b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
1953b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
1954b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
1955b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
1956b7e05686SMatthew G. Knepley . t            - current time
1957b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
1958b7e05686SMatthew G. Knepley . x            - coordinates of the current point
195997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
196097b6e6e8SMatthew G. Knepley . constants    - constant parameters
1961b7e05686SMatthew G. Knepley - g0           - output values at the current point
1962b7e05686SMatthew G. Knepley 
1963b7e05686SMatthew G. Knepley   Level: intermediate
1964b7e05686SMatthew G. Knepley 
1965dce8aebaSBarry Smith   Note:
1966a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
196760225df5SJacob Faibussowitsch 
1968a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
1969dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1970dce8aebaSBarry Smith 
1971dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1972b7e05686SMatthew G. Knepley @*/
1973a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1974d71ae5a4SJacob Faibussowitsch {
19756528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19766528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19776528b96dSMatthew G. Knepley 
1978b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19796528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
198063a3b9bcSJacob 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);
198163a3b9bcSJacob 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);
19829566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19836528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19846528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19856528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19866528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1988b7e05686SMatthew G. Knepley }
1989b7e05686SMatthew G. Knepley 
1990b7e05686SMatthew G. Knepley /*@C
1991b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1992b7e05686SMatthew G. Knepley 
199320f4b53cSBarry Smith   Not Collective
1994b7e05686SMatthew G. Knepley 
1995b7e05686SMatthew G. Knepley   Input Parameters:
1996dce8aebaSBarry Smith + ds - The `PetscDS`
1997b7e05686SMatthew G. Knepley . f  - The test field number
1998b7e05686SMatthew G. Knepley . g  - The field number
1999b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
2000b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2001b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2002b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2003b7e05686SMatthew G. Knepley 
2004a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2005b7e05686SMatthew G. Knepley + dim          - the spatial dimension
2006b7e05686SMatthew G. Knepley . Nf           - the number of fields
2007a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2008b7e05686SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2009b7e05686SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2010b7e05686SMatthew G. Knepley . u            - each field evaluated at the current point
2011b7e05686SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2012b7e05686SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2013b7e05686SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2014b7e05686SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2015b7e05686SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2016b7e05686SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2017b7e05686SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2018b7e05686SMatthew G. Knepley . t            - current time
2019b7e05686SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2020b7e05686SMatthew G. Knepley . x            - coordinates of the current point
202197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
202297b6e6e8SMatthew G. Knepley . constants    - constant parameters
2023b7e05686SMatthew G. Knepley - g0           - output values at the current point
2024b7e05686SMatthew G. Knepley 
2025b7e05686SMatthew G. Knepley   Level: intermediate
2026b7e05686SMatthew G. Knepley 
2027dce8aebaSBarry Smith   Note:
2028a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
202960225df5SJacob Faibussowitsch 
2030a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2031dce8aebaSBarry 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
2032dce8aebaSBarry Smith 
2033dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
2034b7e05686SMatthew G. Knepley @*/
2035a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2036d71ae5a4SJacob Faibussowitsch {
2037b7e05686SMatthew G. Knepley   PetscFunctionBegin;
20386528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2039b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
2040b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
2041b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
2042b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
204363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
204463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
20459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
20463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2047b7e05686SMatthew G. Knepley }
2048b7e05686SMatthew G. Knepley 
20490c2f2876SMatthew G. Knepley /*@C
20500c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20510c2f2876SMatthew G. Knepley 
205220f4b53cSBarry Smith   Not Collective
20530c2f2876SMatthew G. Knepley 
20544165533cSJose E. Roman   Input Parameters:
2055dce8aebaSBarry Smith + ds - The `PetscDS` object
20560c2f2876SMatthew G. Knepley - f  - The field number
20570c2f2876SMatthew G. Knepley 
20584165533cSJose E. Roman   Output Parameter:
20590c2f2876SMatthew G. Knepley . r - Riemann solver
20600c2f2876SMatthew G. Knepley 
206120f4b53cSBarry Smith   Calling sequence of `r`:
20625db36cf9SMatthew G. Knepley + dim          - The spatial dimension
20635db36cf9SMatthew G. Knepley . Nf           - The number of fields
20645db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
20650c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
20660c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
20670c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
20680c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
206997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
207097b6e6e8SMatthew G. Knepley . constants    - constant parameters
20710c2f2876SMatthew G. Knepley - ctx          - optional user context
20720c2f2876SMatthew G. Knepley 
20730c2f2876SMatthew G. Knepley   Level: intermediate
20740c2f2876SMatthew G. Knepley 
2075dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20760c2f2876SMatthew G. Knepley @*/
2077d71ae5a4SJacob 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))
2078d71ae5a4SJacob Faibussowitsch {
20796528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20806528b96dSMatthew G. Knepley   PetscInt          n;
20816528b96dSMatthew G. Knepley 
20820c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20836528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20844f572ea9SToby Isaac   PetscAssertPointer(r, 3);
208563a3b9bcSJacob 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);
20869566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20876528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20890c2f2876SMatthew G. Knepley }
20900c2f2876SMatthew G. Knepley 
20910c2f2876SMatthew G. Knepley /*@C
20920c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20930c2f2876SMatthew G. Knepley 
209420f4b53cSBarry Smith   Not Collective
20950c2f2876SMatthew G. Knepley 
20964165533cSJose E. Roman   Input Parameters:
2097dce8aebaSBarry Smith + ds - The `PetscDS` object
20980c2f2876SMatthew G. Knepley . f  - The field number
20990c2f2876SMatthew G. Knepley - r  - Riemann solver
21000c2f2876SMatthew G. Knepley 
210120f4b53cSBarry Smith   Calling sequence of `r`:
21025db36cf9SMatthew G. Knepley + dim          - The spatial dimension
21035db36cf9SMatthew G. Knepley . Nf           - The number of fields
21045db36cf9SMatthew G. Knepley . x            - The coordinates at a point on the interface
21050c2f2876SMatthew G. Knepley . n            - The normal vector to the interface
21060c2f2876SMatthew G. Knepley . uL           - The state vector to the left of the interface
21070c2f2876SMatthew G. Knepley . uR           - The state vector to the right of the interface
21080c2f2876SMatthew G. Knepley . flux         - output array of flux through the interface
210997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
211097b6e6e8SMatthew G. Knepley . constants    - constant parameters
21110c2f2876SMatthew G. Knepley - ctx          - optional user context
21120c2f2876SMatthew G. Knepley 
21130c2f2876SMatthew G. Knepley   Level: intermediate
21140c2f2876SMatthew G. Knepley 
2115dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
21160c2f2876SMatthew G. Knepley @*/
2117d71ae5a4SJacob 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))
2118d71ae5a4SJacob Faibussowitsch {
21190c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21206528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2121de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
212263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21239566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
21243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21250c2f2876SMatthew G. Knepley }
21260c2f2876SMatthew G. Knepley 
212732d2bbc9SMatthew G. Knepley /*@C
212832d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
212932d2bbc9SMatthew G. Knepley 
213020f4b53cSBarry Smith   Not Collective
213132d2bbc9SMatthew G. Knepley 
213232d2bbc9SMatthew G. Knepley   Input Parameters:
2133dce8aebaSBarry Smith + ds - The `PetscDS`
213432d2bbc9SMatthew G. Knepley - f  - The field number
213532d2bbc9SMatthew G. Knepley 
2136f899ff85SJose E. Roman   Output Parameter:
2137a2b725a8SWilliam Gropp . update - update function
213832d2bbc9SMatthew G. Knepley 
213920f4b53cSBarry Smith   Calling sequence of `update`:
214032d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
214132d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2142a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
214332d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
214432d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
214532d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
214632d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
214732d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
214832d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
214932d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
215032d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
215132d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
215232d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
215332d2bbc9SMatthew G. Knepley . t            - current time
215432d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2155a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2156a4e35b19SJacob Faibussowitsch . constants    - constant parameters
215732d2bbc9SMatthew G. Knepley - uNew         - new value for field at the current point
215832d2bbc9SMatthew G. Knepley 
215932d2bbc9SMatthew G. Knepley   Level: intermediate
216032d2bbc9SMatthew G. Knepley 
2161dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
216232d2bbc9SMatthew G. Knepley @*/
2163d71ae5a4SJacob 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[]))
2164d71ae5a4SJacob Faibussowitsch {
216532d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21666528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
216763a3b9bcSJacob 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);
21689371c9d4SSatish Balay   if (update) {
21694f572ea9SToby Isaac     PetscAssertPointer(update, 3);
21709371c9d4SSatish Balay     *update = ds->update[f];
21719371c9d4SSatish Balay   }
21723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217332d2bbc9SMatthew G. Knepley }
217432d2bbc9SMatthew G. Knepley 
217532d2bbc9SMatthew G. Knepley /*@C
21763fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
217732d2bbc9SMatthew G. Knepley 
217820f4b53cSBarry Smith   Not Collective
217932d2bbc9SMatthew G. Knepley 
218032d2bbc9SMatthew G. Knepley   Input Parameters:
2181dce8aebaSBarry Smith + ds     - The `PetscDS`
218232d2bbc9SMatthew G. Knepley . f      - The field number
218332d2bbc9SMatthew G. Knepley - update - update function
218432d2bbc9SMatthew G. Knepley 
218520f4b53cSBarry Smith   Calling sequence of `update`:
218632d2bbc9SMatthew G. Knepley + dim          - the spatial dimension
218732d2bbc9SMatthew G. Knepley . Nf           - the number of fields
2188a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
218932d2bbc9SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
219032d2bbc9SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
219132d2bbc9SMatthew G. Knepley . u            - each field evaluated at the current point
219232d2bbc9SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
219332d2bbc9SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
219432d2bbc9SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
219532d2bbc9SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
219632d2bbc9SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
219732d2bbc9SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
219832d2bbc9SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
219932d2bbc9SMatthew G. Knepley . t            - current time
220032d2bbc9SMatthew G. Knepley . x            - coordinates of the current point
2201a4e35b19SJacob Faibussowitsch . numConstants - number of constant parameters
2202a4e35b19SJacob Faibussowitsch . constants    - constant parameters
220332d2bbc9SMatthew G. Knepley - uNew         - new field values at the current point
220432d2bbc9SMatthew G. Knepley 
220532d2bbc9SMatthew G. Knepley   Level: intermediate
220632d2bbc9SMatthew G. Knepley 
2207dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
220832d2bbc9SMatthew G. Knepley @*/
2209d71ae5a4SJacob 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[]))
2210d71ae5a4SJacob Faibussowitsch {
221132d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
22126528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
221332d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
221463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22159566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22166528b96dSMatthew G. Knepley   ds->update[f] = update;
22173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
221832d2bbc9SMatthew G. Knepley }
221932d2bbc9SMatthew G. Knepley 
2220d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2221d71ae5a4SJacob Faibussowitsch {
22220c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22236528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
222463a3b9bcSJacob 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);
22254f572ea9SToby Isaac   PetscAssertPointer(ctx, 3);
22263ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
22273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22280c2f2876SMatthew G. Knepley }
22290c2f2876SMatthew G. Knepley 
2230d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2231d71ae5a4SJacob Faibussowitsch {
22320c2f2876SMatthew G. Knepley   PetscFunctionBegin;
22336528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
223463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22359566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22366528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22380c2f2876SMatthew G. Knepley }
22390c2f2876SMatthew G. Knepley 
2240194d53e6SMatthew G. Knepley /*@C
2241194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2242194d53e6SMatthew G. Knepley 
224320f4b53cSBarry Smith   Not Collective
2244194d53e6SMatthew G. Knepley 
2245194d53e6SMatthew G. Knepley   Input Parameters:
22466528b96dSMatthew G. Knepley + ds - The PetscDS
2247194d53e6SMatthew G. Knepley - f  - The test field number
2248194d53e6SMatthew G. Knepley 
2249194d53e6SMatthew G. Knepley   Output Parameters:
2250194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2251194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2252194d53e6SMatthew G. Knepley 
2253a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2254194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2255194d53e6SMatthew G. Knepley . Nf           - the number of fields
2256a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2257194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2258194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2259194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2260194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2261194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2262194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2263194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2264194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2265194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2266194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2267194d53e6SMatthew G. Knepley . t            - current time
2268194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2269194d53e6SMatthew G. Knepley . n            - unit normal at the current point
227097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
227197b6e6e8SMatthew G. Knepley . constants    - constant parameters
2272194d53e6SMatthew G. Knepley - f0           - output values at the current point
2273194d53e6SMatthew G. Knepley 
2274194d53e6SMatthew G. Knepley   Level: intermediate
2275194d53e6SMatthew G. Knepley 
2276dce8aebaSBarry Smith   Note:
2277a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
227860225df5SJacob Faibussowitsch 
2279a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2280dce8aebaSBarry 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
2281dce8aebaSBarry Smith 
2282dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2283194d53e6SMatthew G. Knepley @*/
2284a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2285d71ae5a4SJacob Faibussowitsch {
22866528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22876528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22886528b96dSMatthew G. Knepley 
22892764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
229163a3b9bcSJacob 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);
22929566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22936528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22946528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22962764a2aaSMatthew G. Knepley }
22972764a2aaSMatthew G. Knepley 
2298194d53e6SMatthew G. Knepley /*@C
2299194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2300194d53e6SMatthew G. Knepley 
230120f4b53cSBarry Smith   Not Collective
2302194d53e6SMatthew G. Knepley 
2303194d53e6SMatthew G. Knepley   Input Parameters:
2304dce8aebaSBarry Smith + ds - The `PetscDS`
2305194d53e6SMatthew G. Knepley . f  - The test field number
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 
2309a4e35b19SJacob Faibussowitsch   Calling sequence of `f0`:
2310194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2311194d53e6SMatthew G. Knepley . Nf           - the number of fields
2312a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2313194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2314194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2315194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2316194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2317194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2318194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2319194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2320194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2321194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2322194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2323194d53e6SMatthew G. Knepley . t            - current time
2324194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2325194d53e6SMatthew G. Knepley . n            - unit normal at the current point
232697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
232797b6e6e8SMatthew G. Knepley . constants    - constant parameters
2328194d53e6SMatthew G. Knepley - f0           - output values at the current point
2329194d53e6SMatthew G. Knepley 
2330194d53e6SMatthew G. Knepley   Level: intermediate
2331194d53e6SMatthew G. Knepley 
2332dce8aebaSBarry Smith   Note:
2333a4e35b19SJacob Faibussowitsch   The calling sequence of `f1` is identical, and therefore omitted for brevity.
233460225df5SJacob Faibussowitsch 
2335a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2336dce8aebaSBarry 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
2337dce8aebaSBarry Smith 
2338dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2339194d53e6SMatthew G. Knepley @*/
2340a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2341d71ae5a4SJacob Faibussowitsch {
23422764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23436528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
234463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23472764a2aaSMatthew G. Knepley }
23482764a2aaSMatthew G. Knepley 
234927f02ce8SMatthew G. Knepley /*@
2350dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
235127f02ce8SMatthew G. Knepley 
235220f4b53cSBarry Smith   Not Collective
235327f02ce8SMatthew G. Knepley 
235427f02ce8SMatthew G. Knepley   Input Parameter:
2355dce8aebaSBarry Smith . ds - The `PetscDS`
235627f02ce8SMatthew G. Knepley 
235727f02ce8SMatthew G. Knepley   Output Parameter:
235827f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
235927f02ce8SMatthew G. Knepley 
236027f02ce8SMatthew G. Knepley   Level: intermediate
236127f02ce8SMatthew G. Knepley 
2362dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
236327f02ce8SMatthew G. Knepley @*/
2364d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2365d71ae5a4SJacob Faibussowitsch {
236627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23684f572ea9SToby Isaac   PetscAssertPointer(hasBdJac, 2);
23699566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
237127f02ce8SMatthew G. Knepley }
237227f02ce8SMatthew G. Knepley 
2373194d53e6SMatthew G. Knepley /*@C
2374194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2375194d53e6SMatthew G. Knepley 
237620f4b53cSBarry Smith   Not Collective
2377194d53e6SMatthew G. Knepley 
2378194d53e6SMatthew G. Knepley   Input Parameters:
2379dce8aebaSBarry Smith + ds - The `PetscDS`
2380194d53e6SMatthew G. Knepley . f  - The test field number
2381194d53e6SMatthew G. Knepley - g  - The field number
2382194d53e6SMatthew G. Knepley 
2383194d53e6SMatthew G. Knepley   Output Parameters:
2384194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2385194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2386194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2387194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2388194d53e6SMatthew G. Knepley 
2389a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2390194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2391194d53e6SMatthew G. Knepley . Nf           - the number of fields
2392a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2393194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2394194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2395194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2396194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2397194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2398194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2399194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2400194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2401194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2402194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2403194d53e6SMatthew G. Knepley . t            - current time
24042aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2405194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2406194d53e6SMatthew G. Knepley . n            - normal at the current point
240797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
240897b6e6e8SMatthew G. Knepley . constants    - constant parameters
2409194d53e6SMatthew G. Knepley - g0           - output values at the current point
2410194d53e6SMatthew G. Knepley 
2411194d53e6SMatthew G. Knepley   Level: intermediate
2412194d53e6SMatthew G. Knepley 
2413dce8aebaSBarry Smith   Note:
2414a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
241560225df5SJacob Faibussowitsch 
2416a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2417dce8aebaSBarry 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
2418dce8aebaSBarry Smith 
2419dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2420194d53e6SMatthew G. Knepley @*/
2421a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2422d71ae5a4SJacob Faibussowitsch {
24236528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
24246528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
24256528b96dSMatthew G. Knepley 
24262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24276528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
242863a3b9bcSJacob 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);
242963a3b9bcSJacob 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);
24309566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24316528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24326528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24336528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24346528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24362764a2aaSMatthew G. Knepley }
24372764a2aaSMatthew G. Knepley 
2438194d53e6SMatthew G. Knepley /*@C
2439194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2440194d53e6SMatthew G. Knepley 
244120f4b53cSBarry Smith   Not Collective
2442194d53e6SMatthew G. Knepley 
2443194d53e6SMatthew G. Knepley   Input Parameters:
24446528b96dSMatthew G. Knepley + ds - The PetscDS
2445194d53e6SMatthew G. Knepley . f  - The test field number
2446194d53e6SMatthew G. Knepley . g  - The field number
2447194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2448194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2449194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2450194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2451194d53e6SMatthew G. Knepley 
2452a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
2453194d53e6SMatthew G. Knepley + dim          - the spatial dimension
2454194d53e6SMatthew G. Knepley . Nf           - the number of fields
2455a4e35b19SJacob Faibussowitsch . NfAux        - the number of auxiliary fields
2456194d53e6SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
2457194d53e6SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
2458194d53e6SMatthew G. Knepley . u            - each field evaluated at the current point
2459194d53e6SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
2460194d53e6SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
2461194d53e6SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
2462194d53e6SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
2463194d53e6SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
2464194d53e6SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
2465194d53e6SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
2466194d53e6SMatthew G. Knepley . t            - current time
24672aa1fc23SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
2468194d53e6SMatthew G. Knepley . x            - coordinates of the current point
2469194d53e6SMatthew G. Knepley . n            - normal at the current point
247097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
247197b6e6e8SMatthew G. Knepley . constants    - constant parameters
2472194d53e6SMatthew G. Knepley - g0           - output values at the current point
2473194d53e6SMatthew G. Knepley 
2474194d53e6SMatthew G. Knepley   Level: intermediate
2475194d53e6SMatthew G. Knepley 
2476dce8aebaSBarry Smith   Note:
2477a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
247860225df5SJacob Faibussowitsch 
2479a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2480dce8aebaSBarry 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
2481dce8aebaSBarry Smith 
2482dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2483194d53e6SMatthew G. Knepley @*/
2484a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2485d71ae5a4SJacob Faibussowitsch {
24862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24876528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24882764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24892764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24902764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24912764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
249263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
249363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24962764a2aaSMatthew G. Knepley }
24972764a2aaSMatthew G. Knepley 
249827f02ce8SMatthew G. Knepley /*@
249927f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
250027f02ce8SMatthew G. Knepley 
250120f4b53cSBarry Smith   Not Collective
250227f02ce8SMatthew G. Knepley 
250327f02ce8SMatthew G. Knepley   Input Parameter:
2504dce8aebaSBarry Smith . ds - The `PetscDS`
250527f02ce8SMatthew G. Knepley 
250627f02ce8SMatthew G. Knepley   Output Parameter:
250760225df5SJacob Faibussowitsch . hasBdJacPre - flag that pointwise function for the boundary Jacobian preconditioner has been set
250827f02ce8SMatthew G. Knepley 
250927f02ce8SMatthew G. Knepley   Level: intermediate
251027f02ce8SMatthew G. Knepley 
2511dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
251227f02ce8SMatthew G. Knepley @*/
2513d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2514d71ae5a4SJacob Faibussowitsch {
251527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25166528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
25174f572ea9SToby Isaac   PetscAssertPointer(hasBdJacPre, 2);
25189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
25193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
252027f02ce8SMatthew G. Knepley }
252127f02ce8SMatthew G. Knepley 
252227f02ce8SMatthew G. Knepley /*@C
252327f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
252427f02ce8SMatthew G. Knepley 
252520f4b53cSBarry Smith   Not Collective; No Fortran Support
252627f02ce8SMatthew G. Knepley 
252727f02ce8SMatthew G. Knepley   Input Parameters:
2528dce8aebaSBarry Smith + ds - The `PetscDS`
252927f02ce8SMatthew G. Knepley . f  - The test field number
253027f02ce8SMatthew G. Knepley - g  - The field number
253127f02ce8SMatthew G. Knepley 
253227f02ce8SMatthew G. Knepley   Output Parameters:
253327f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
253427f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
253527f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
253627f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
253727f02ce8SMatthew G. Knepley 
2538a4e35b19SJacob Faibussowitsch   Calling sequence of `g0`:
253927f02ce8SMatthew G. Knepley + dim          - the spatial dimension
254027f02ce8SMatthew G. Knepley . Nf           - the number of fields
254127f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
254227f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
254327f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
254427f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
254527f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
254627f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
254727f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
254827f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
254927f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
255027f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
255127f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
255227f02ce8SMatthew G. Knepley . t            - current time
255327f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
255427f02ce8SMatthew G. Knepley . x            - coordinates of the current point
255527f02ce8SMatthew G. Knepley . n            - normal at the current point
255627f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
255727f02ce8SMatthew G. Knepley . constants    - constant parameters
255827f02ce8SMatthew G. Knepley - g0           - output values at the current point
255927f02ce8SMatthew G. Knepley 
256027f02ce8SMatthew G. Knepley   Level: intermediate
256127f02ce8SMatthew G. Knepley 
2562dce8aebaSBarry Smith   Note:
2563a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
256460225df5SJacob Faibussowitsch 
2565a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2566dce8aebaSBarry 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
2567dce8aebaSBarry Smith 
2568dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
256927f02ce8SMatthew G. Knepley @*/
2570a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2571d71ae5a4SJacob Faibussowitsch {
25726528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25736528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25746528b96dSMatthew G. Knepley 
257527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
257763a3b9bcSJacob 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);
257863a3b9bcSJacob 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);
25799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25806528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25816528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25826528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25836528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
258527f02ce8SMatthew G. Knepley }
258627f02ce8SMatthew G. Knepley 
258727f02ce8SMatthew G. Knepley /*@C
258827f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
258927f02ce8SMatthew G. Knepley 
259020f4b53cSBarry Smith   Not Collective; No Fortran Support
259127f02ce8SMatthew G. Knepley 
259227f02ce8SMatthew G. Knepley   Input Parameters:
2593dce8aebaSBarry Smith + ds - The `PetscDS`
259427f02ce8SMatthew G. Knepley . f  - The test field number
259527f02ce8SMatthew G. Knepley . g  - The field number
259627f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
259727f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
259827f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
259927f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
260027f02ce8SMatthew G. Knepley 
2601a4e35b19SJacob Faibussowitsch   Calling sequence of `g0':
260227f02ce8SMatthew G. Knepley + dim          - the spatial dimension
260327f02ce8SMatthew G. Knepley . Nf           - the number of fields
260427f02ce8SMatthew G. Knepley . NfAux        - the number of auxiliary fields
260527f02ce8SMatthew G. Knepley . uOff         - the offset into u[] and u_t[] for each field
260627f02ce8SMatthew G. Knepley . uOff_x       - the offset into u_x[] for each field
260727f02ce8SMatthew G. Knepley . u            - each field evaluated at the current point
260827f02ce8SMatthew G. Knepley . u_t          - the time derivative of each field evaluated at the current point
260927f02ce8SMatthew G. Knepley . u_x          - the gradient of each field evaluated at the current point
261027f02ce8SMatthew G. Knepley . aOff         - the offset into a[] and a_t[] for each auxiliary field
261127f02ce8SMatthew G. Knepley . aOff_x       - the offset into a_x[] for each auxiliary field
261227f02ce8SMatthew G. Knepley . a            - each auxiliary field evaluated at the current point
261327f02ce8SMatthew G. Knepley . a_t          - the time derivative of each auxiliary field evaluated at the current point
261427f02ce8SMatthew G. Knepley . a_x          - the gradient of auxiliary each field evaluated at the current point
261527f02ce8SMatthew G. Knepley . t            - current time
261627f02ce8SMatthew G. Knepley . u_tShift     - the multiplier a for dF/dU_t
261727f02ce8SMatthew G. Knepley . x            - coordinates of the current point
261827f02ce8SMatthew G. Knepley . n            - normal at the current point
261927f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
262027f02ce8SMatthew G. Knepley . constants    - constant parameters
262127f02ce8SMatthew G. Knepley - g0           - output values at the current point
262227f02ce8SMatthew G. Knepley 
262327f02ce8SMatthew G. Knepley   Level: intermediate
262427f02ce8SMatthew G. Knepley 
2625dce8aebaSBarry Smith   Note:
2626a4e35b19SJacob Faibussowitsch   `g1`, `g2`, and `g3` have identical calling sequences to `g0` and are omitted for brevity.
262760225df5SJacob Faibussowitsch 
2628a4e35b19SJacob Faibussowitsch   We are using a first order FEM model for the weak form\:
2629dce8aebaSBarry 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
2630dce8aebaSBarry Smith 
2631dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
263227f02ce8SMatthew G. Knepley @*/
2633a4e35b19SJacob 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, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
2634d71ae5a4SJacob Faibussowitsch {
263527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26366528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
263727f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
263827f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
263927f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
264027f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
264163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
264263a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26439566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
264527f02ce8SMatthew G. Knepley }
264627f02ce8SMatthew G. Knepley 
26470d3e9b51SMatthew G. Knepley /*@C
2648c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2649c371a6d1SMatthew G. Knepley 
265020f4b53cSBarry Smith   Not Collective
2651c371a6d1SMatthew G. Knepley 
2652c371a6d1SMatthew G. Knepley   Input Parameters:
2653c371a6d1SMatthew G. Knepley + prob - The PetscDS
2654c371a6d1SMatthew G. Knepley - f    - The test field number
2655c371a6d1SMatthew G. Knepley 
2656d8d19677SJose E. Roman   Output Parameters:
2657a4e35b19SJacob Faibussowitsch + sol - exact solution for the test field
2658a4e35b19SJacob Faibussowitsch - ctx - exact solution context
2659c371a6d1SMatthew G. Knepley 
266020f4b53cSBarry Smith   Calling sequence of `exactSol`:
2661c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2662c371a6d1SMatthew G. Knepley . t   - current time
2663c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2664c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2665a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2666c371a6d1SMatthew G. Knepley - ctx - a user context
2667c371a6d1SMatthew G. Knepley 
2668c371a6d1SMatthew G. Knepley   Level: intermediate
2669c371a6d1SMatthew G. Knepley 
2670dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2671c371a6d1SMatthew G. Knepley @*/
2672d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2673d71ae5a4SJacob Faibussowitsch {
2674c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2675c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
267663a3b9bcSJacob 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);
26779371c9d4SSatish Balay   if (sol) {
26784f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
26799371c9d4SSatish Balay     *sol = prob->exactSol[f];
26809371c9d4SSatish Balay   }
26819371c9d4SSatish Balay   if (ctx) {
26824f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
26839371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26849371c9d4SSatish Balay   }
26853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2686c371a6d1SMatthew G. Knepley }
2687c371a6d1SMatthew G. Knepley 
2688c371a6d1SMatthew G. Knepley /*@C
2689578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2690c371a6d1SMatthew G. Knepley 
269120f4b53cSBarry Smith   Not Collective
2692c371a6d1SMatthew G. Knepley 
2693c371a6d1SMatthew G. Knepley   Input Parameters:
2694dce8aebaSBarry Smith + prob - The `PetscDS`
2695c371a6d1SMatthew G. Knepley . f    - The test field number
269695cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
269720f4b53cSBarry Smith - ctx  - solution context or `NULL`
2698c371a6d1SMatthew G. Knepley 
269920f4b53cSBarry Smith   Calling sequence of `sol`:
2700c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2701c371a6d1SMatthew G. Knepley . t   - current time
2702c371a6d1SMatthew G. Knepley . x   - coordinates of the current point
2703c371a6d1SMatthew G. Knepley . Nc  - the number of field components
2704c371a6d1SMatthew G. Knepley . u   - the solution field evaluated at the current point
2705c371a6d1SMatthew G. Knepley - ctx - a user context
2706c371a6d1SMatthew G. Knepley 
2707c371a6d1SMatthew G. Knepley   Level: intermediate
2708c371a6d1SMatthew G. Knepley 
2709dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2710c371a6d1SMatthew G. Knepley @*/
2711d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2712d71ae5a4SJacob Faibussowitsch {
2713c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2714c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
271563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27169566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27179371c9d4SSatish Balay   if (sol) {
27189371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27199371c9d4SSatish Balay     prob->exactSol[f] = sol;
27209371c9d4SSatish Balay   }
27219371c9d4SSatish Balay   if (ctx) {
27229371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27239371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27249371c9d4SSatish Balay   }
27253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2726c371a6d1SMatthew G. Knepley }
2727c371a6d1SMatthew G. Knepley 
27285638fd0eSMatthew G. Knepley /*@C
2729f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2730f2cacb80SMatthew G. Knepley 
273120f4b53cSBarry Smith   Not Collective
2732f2cacb80SMatthew G. Knepley 
2733f2cacb80SMatthew G. Knepley   Input Parameters:
2734dce8aebaSBarry Smith + prob - The `PetscDS`
2735f2cacb80SMatthew G. Knepley - f    - The test field number
2736f2cacb80SMatthew G. Knepley 
2737d8d19677SJose E. Roman   Output Parameters:
2738a4e35b19SJacob Faibussowitsch + sol - time derivative of the exact solution for the test field
2739a4e35b19SJacob Faibussowitsch - ctx - time derivative of the exact solution context
2740f2cacb80SMatthew G. Knepley 
274120f4b53cSBarry Smith   Calling sequence of `exactSol`:
2742f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2743f2cacb80SMatthew G. Knepley . t   - current time
2744f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2745f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2746a4e35b19SJacob Faibussowitsch . u   - the solution field evaluated at the current point
2747f2cacb80SMatthew G. Knepley - ctx - a user context
2748f2cacb80SMatthew G. Knepley 
2749f2cacb80SMatthew G. Knepley   Level: intermediate
2750f2cacb80SMatthew G. Knepley 
2751dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2752f2cacb80SMatthew G. Knepley @*/
2753d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2754d71ae5a4SJacob Faibussowitsch {
2755f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2756f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
275763a3b9bcSJacob 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);
27589371c9d4SSatish Balay   if (sol) {
27594f572ea9SToby Isaac     PetscAssertPointer(sol, 3);
27609371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27619371c9d4SSatish Balay   }
27629371c9d4SSatish Balay   if (ctx) {
27634f572ea9SToby Isaac     PetscAssertPointer(ctx, 4);
27649371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27659371c9d4SSatish Balay   }
27663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2767f2cacb80SMatthew G. Knepley }
2768f2cacb80SMatthew G. Knepley 
2769f2cacb80SMatthew G. Knepley /*@C
2770f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2771f2cacb80SMatthew G. Knepley 
277220f4b53cSBarry Smith   Not Collective
2773f2cacb80SMatthew G. Knepley 
2774f2cacb80SMatthew G. Knepley   Input Parameters:
2775dce8aebaSBarry Smith + prob - The `PetscDS`
2776f2cacb80SMatthew G. Knepley . f    - The test field number
2777f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
277820f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2779f2cacb80SMatthew G. Knepley 
278020f4b53cSBarry Smith   Calling sequence of `sol`:
2781f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2782f2cacb80SMatthew G. Knepley . t   - current time
2783f2cacb80SMatthew G. Knepley . x   - coordinates of the current point
2784f2cacb80SMatthew G. Knepley . Nc  - the number of field components
2785f2cacb80SMatthew G. Knepley . u   - the solution field evaluated at the current point
2786f2cacb80SMatthew G. Knepley - ctx - a user context
2787f2cacb80SMatthew G. Knepley 
2788f2cacb80SMatthew G. Knepley   Level: intermediate
2789f2cacb80SMatthew G. Knepley 
2790dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2791f2cacb80SMatthew G. Knepley @*/
2792d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2793d71ae5a4SJacob Faibussowitsch {
2794f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2795f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
279663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27979566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27989371c9d4SSatish Balay   if (sol) {
27999371c9d4SSatish Balay     PetscValidFunction(sol, 3);
28009371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
28019371c9d4SSatish Balay   }
28029371c9d4SSatish Balay   if (ctx) {
28039371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28049371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28059371c9d4SSatish Balay   }
28063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2807f2cacb80SMatthew G. Knepley }
2808f2cacb80SMatthew G. Knepley 
2809f2cacb80SMatthew G. Knepley /*@C
281097b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
281197b6e6e8SMatthew G. Knepley 
281220f4b53cSBarry Smith   Not Collective
281397b6e6e8SMatthew G. Knepley 
281497b6e6e8SMatthew G. Knepley   Input Parameter:
2815dce8aebaSBarry Smith . prob - The `PetscDS` object
281697b6e6e8SMatthew G. Knepley 
281797b6e6e8SMatthew G. Knepley   Output Parameters:
281897b6e6e8SMatthew G. Knepley + numConstants - The number of constants
281997b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
282097b6e6e8SMatthew G. Knepley 
282197b6e6e8SMatthew G. Knepley   Level: intermediate
282297b6e6e8SMatthew G. Knepley 
2823dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
282497b6e6e8SMatthew G. Knepley @*/
2825d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2826d71ae5a4SJacob Faibussowitsch {
282797b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
282897b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28299371c9d4SSatish Balay   if (numConstants) {
28304f572ea9SToby Isaac     PetscAssertPointer(numConstants, 2);
28319371c9d4SSatish Balay     *numConstants = prob->numConstants;
28329371c9d4SSatish Balay   }
28339371c9d4SSatish Balay   if (constants) {
28344f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
28359371c9d4SSatish Balay     *constants = prob->constants;
28369371c9d4SSatish Balay   }
28373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
283897b6e6e8SMatthew G. Knepley }
283997b6e6e8SMatthew G. Knepley 
28400d3e9b51SMatthew G. Knepley /*@C
284197b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
284297b6e6e8SMatthew G. Knepley 
284320f4b53cSBarry Smith   Not Collective
284497b6e6e8SMatthew G. Knepley 
284597b6e6e8SMatthew G. Knepley   Input Parameters:
2846dce8aebaSBarry Smith + prob         - The `PetscDS` object
284797b6e6e8SMatthew G. Knepley . numConstants - The number of constants
284897b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
284997b6e6e8SMatthew G. Knepley 
285097b6e6e8SMatthew G. Knepley   Level: intermediate
285197b6e6e8SMatthew G. Knepley 
2852dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
285397b6e6e8SMatthew G. Knepley @*/
2854d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2855d71ae5a4SJacob Faibussowitsch {
285697b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
285797b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
285897b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28599566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
286097b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
286197b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28629566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
286320be0f5bSMatthew G. Knepley     } else {
286420be0f5bSMatthew G. Knepley       prob->constants = NULL;
286520be0f5bSMatthew G. Knepley     }
286620be0f5bSMatthew G. Knepley   }
286720be0f5bSMatthew G. Knepley   if (prob->numConstants) {
28684f572ea9SToby Isaac     PetscAssertPointer(constants, 3);
28699566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
287097b6e6e8SMatthew G. Knepley   }
28713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
287297b6e6e8SMatthew G. Knepley }
287397b6e6e8SMatthew G. Knepley 
28744cd1e086SMatthew G. Knepley /*@
28754cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28764cd1e086SMatthew G. Knepley 
287720f4b53cSBarry Smith   Not Collective
28784cd1e086SMatthew G. Knepley 
28794cd1e086SMatthew G. Knepley   Input Parameters:
2880dce8aebaSBarry Smith + prob - The `PetscDS` object
28814cd1e086SMatthew G. Knepley - disc - The discretization object
28824cd1e086SMatthew G. Knepley 
28834cd1e086SMatthew G. Knepley   Output Parameter:
28844cd1e086SMatthew G. Knepley . f - The field number
28854cd1e086SMatthew G. Knepley 
28864cd1e086SMatthew G. Knepley   Level: beginner
28874cd1e086SMatthew G. Knepley 
2888dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28894cd1e086SMatthew G. Knepley @*/
2890d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2891d71ae5a4SJacob Faibussowitsch {
28924cd1e086SMatthew G. Knepley   PetscInt g;
28934cd1e086SMatthew G. Knepley 
28944cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28954cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28964f572ea9SToby Isaac   PetscAssertPointer(f, 3);
28974cd1e086SMatthew G. Knepley   *f = -1;
28989371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
28999371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
29009371c9d4SSatish Balay   }
290108401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
29024cd1e086SMatthew G. Knepley   *f = g;
29033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29044cd1e086SMatthew G. Knepley }
29054cd1e086SMatthew G. Knepley 
29064cd1e086SMatthew G. Knepley /*@
29074cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
29084cd1e086SMatthew G. Knepley 
290920f4b53cSBarry Smith   Not Collective
29104cd1e086SMatthew G. Knepley 
29114cd1e086SMatthew G. Knepley   Input Parameters:
2912dce8aebaSBarry Smith + prob - The `PetscDS` object
29134cd1e086SMatthew G. Knepley - f    - The field number
29144cd1e086SMatthew G. Knepley 
29154cd1e086SMatthew G. Knepley   Output Parameter:
29164cd1e086SMatthew G. Knepley . size - The size
29174cd1e086SMatthew G. Knepley 
29184cd1e086SMatthew G. Knepley   Level: beginner
29194cd1e086SMatthew G. Knepley 
2920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29214cd1e086SMatthew G. Knepley @*/
2922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2923d71ae5a4SJacob Faibussowitsch {
29244cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29254cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29264f572ea9SToby Isaac   PetscAssertPointer(size, 3);
292763a3b9bcSJacob 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);
29289566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2929d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29314cd1e086SMatthew G. Knepley }
29324cd1e086SMatthew G. Knepley 
2933bc4ae4beSMatthew G. Knepley /*@
2934bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2935bc4ae4beSMatthew G. Knepley 
293620f4b53cSBarry Smith   Not Collective
2937bc4ae4beSMatthew G. Knepley 
2938bc4ae4beSMatthew G. Knepley   Input Parameters:
2939dce8aebaSBarry Smith + prob - The `PetscDS` object
2940bc4ae4beSMatthew G. Knepley - f    - The field number
2941bc4ae4beSMatthew G. Knepley 
2942bc4ae4beSMatthew G. Knepley   Output Parameter:
2943bc4ae4beSMatthew G. Knepley . off - The offset
2944bc4ae4beSMatthew G. Knepley 
2945bc4ae4beSMatthew G. Knepley   Level: beginner
2946bc4ae4beSMatthew G. Knepley 
2947dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2948bc4ae4beSMatthew G. Knepley @*/
2949d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2950d71ae5a4SJacob Faibussowitsch {
29514cd1e086SMatthew G. Knepley   PetscInt size, g;
29522764a2aaSMatthew G. Knepley 
29532764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29542764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29554f572ea9SToby Isaac   PetscAssertPointer(off, 3);
295663a3b9bcSJacob 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);
29572764a2aaSMatthew G. Knepley   *off = 0;
29582764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29599566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29604cd1e086SMatthew G. Knepley     *off += size;
29612764a2aaSMatthew G. Knepley   }
29623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29632764a2aaSMatthew G. Knepley }
29642764a2aaSMatthew G. Knepley 
2965bc4ae4beSMatthew G. Knepley /*@
29665fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29675fedec97SMatthew G. Knepley 
296820f4b53cSBarry Smith   Not Collective
29695fedec97SMatthew G. Knepley 
29705fedec97SMatthew G. Knepley   Input Parameters:
297160225df5SJacob Faibussowitsch + ds - The `PetscDS` object
29725fedec97SMatthew G. Knepley - f  - The field number
29735fedec97SMatthew G. Knepley 
29745fedec97SMatthew G. Knepley   Output Parameter:
29755fedec97SMatthew G. Knepley . off - The offset
29765fedec97SMatthew G. Knepley 
29775fedec97SMatthew G. Knepley   Level: beginner
29785fedec97SMatthew G. Knepley 
2979dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29805fedec97SMatthew G. Knepley @*/
2981d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2982d71ae5a4SJacob Faibussowitsch {
29835fedec97SMatthew G. Knepley   PetscInt size, g;
29845fedec97SMatthew G. Knepley 
29855fedec97SMatthew G. Knepley   PetscFunctionBegin;
29865fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
29874f572ea9SToby Isaac   PetscAssertPointer(off, 3);
298863a3b9bcSJacob 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);
29895fedec97SMatthew G. Knepley   *off = 0;
29905fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29915fedec97SMatthew G. Knepley     PetscBool cohesive;
29925fedec97SMatthew G. Knepley 
29939566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29949566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29955fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29965fedec97SMatthew G. Knepley   }
29973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29985fedec97SMatthew G. Knepley }
29995fedec97SMatthew G. Knepley 
30005fedec97SMatthew G. Knepley /*@
300147e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
3002bc4ae4beSMatthew G. Knepley 
300320f4b53cSBarry Smith   Not Collective
3004bc4ae4beSMatthew G. Knepley 
300547e57110SSander Arens   Input Parameter:
3006dce8aebaSBarry Smith . prob - The `PetscDS` object
3007bc4ae4beSMatthew G. Knepley 
3008bc4ae4beSMatthew G. Knepley   Output Parameter:
300947e57110SSander Arens . dimensions - The number of dimensions
3010bc4ae4beSMatthew G. Knepley 
3011bc4ae4beSMatthew G. Knepley   Level: beginner
3012bc4ae4beSMatthew G. Knepley 
3013dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3014bc4ae4beSMatthew G. Knepley @*/
3015d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3016d71ae5a4SJacob Faibussowitsch {
30172764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30182764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30199566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30204f572ea9SToby Isaac   PetscAssertPointer(dimensions, 2);
302147e57110SSander Arens   *dimensions = prob->Nb;
30223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30236ce16762SMatthew G. Knepley }
302447e57110SSander Arens 
302547e57110SSander Arens /*@
302647e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
302747e57110SSander Arens 
302820f4b53cSBarry Smith   Not Collective
302947e57110SSander Arens 
303047e57110SSander Arens   Input Parameter:
3031dce8aebaSBarry Smith . prob - The `PetscDS` object
303247e57110SSander Arens 
303347e57110SSander Arens   Output Parameter:
303447e57110SSander Arens . components - The number of components
303547e57110SSander Arens 
303647e57110SSander Arens   Level: beginner
303747e57110SSander Arens 
3038dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
303947e57110SSander Arens @*/
3040d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3041d71ae5a4SJacob Faibussowitsch {
304247e57110SSander Arens   PetscFunctionBegin;
304347e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30449566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
30454f572ea9SToby Isaac   PetscAssertPointer(components, 2);
304647e57110SSander Arens   *components = prob->Nc;
30473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30486ce16762SMatthew G. Knepley }
30496ce16762SMatthew G. Knepley 
30506ce16762SMatthew G. Knepley /*@
30516ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30526ce16762SMatthew G. Knepley 
305320f4b53cSBarry Smith   Not Collective
30546ce16762SMatthew G. Knepley 
30556ce16762SMatthew G. Knepley   Input Parameters:
3056dce8aebaSBarry Smith + prob - The `PetscDS` object
30576ce16762SMatthew G. Knepley - f    - The field number
30586ce16762SMatthew G. Knepley 
30596ce16762SMatthew G. Knepley   Output Parameter:
30606ce16762SMatthew G. Knepley . off - The offset
30616ce16762SMatthew G. Knepley 
30626ce16762SMatthew G. Knepley   Level: beginner
30636ce16762SMatthew G. Knepley 
3064dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30656ce16762SMatthew G. Knepley @*/
3066d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3067d71ae5a4SJacob Faibussowitsch {
30686ce16762SMatthew G. Knepley   PetscFunctionBegin;
30696ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30704f572ea9SToby Isaac   PetscAssertPointer(off, 3);
307163a3b9bcSJacob 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);
30729566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
307347e57110SSander Arens   *off = prob->off[f];
30743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30752764a2aaSMatthew G. Knepley }
30762764a2aaSMatthew G. Knepley 
3077194d53e6SMatthew G. Knepley /*@
3078194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3079194d53e6SMatthew G. Knepley 
308020f4b53cSBarry Smith   Not Collective
3081194d53e6SMatthew G. Knepley 
3082194d53e6SMatthew G. Knepley   Input Parameter:
3083dce8aebaSBarry Smith . prob - The `PetscDS` object
3084194d53e6SMatthew G. Knepley 
3085194d53e6SMatthew G. Knepley   Output Parameter:
3086194d53e6SMatthew G. Knepley . offsets - The offsets
3087194d53e6SMatthew G. Knepley 
3088194d53e6SMatthew G. Knepley   Level: beginner
3089194d53e6SMatthew G. Knepley 
3090dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3091194d53e6SMatthew G. Knepley @*/
3092d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3093d71ae5a4SJacob Faibussowitsch {
3094194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3095194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30964f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
30979566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3098194d53e6SMatthew G. Knepley   *offsets = prob->off;
30993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3100194d53e6SMatthew G. Knepley }
3101194d53e6SMatthew G. Knepley 
3102194d53e6SMatthew G. Knepley /*@
3103194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3104194d53e6SMatthew G. Knepley 
310520f4b53cSBarry Smith   Not Collective
3106194d53e6SMatthew G. Knepley 
3107194d53e6SMatthew G. Knepley   Input Parameter:
3108dce8aebaSBarry Smith . prob - The `PetscDS` object
3109194d53e6SMatthew G. Knepley 
3110194d53e6SMatthew G. Knepley   Output Parameter:
3111194d53e6SMatthew G. Knepley . offsets - The offsets
3112194d53e6SMatthew G. Knepley 
3113194d53e6SMatthew G. Knepley   Level: beginner
3114194d53e6SMatthew G. Knepley 
3115dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3116194d53e6SMatthew G. Knepley @*/
3117d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3118d71ae5a4SJacob Faibussowitsch {
3119194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3120194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
31214f572ea9SToby Isaac   PetscAssertPointer(offsets, 2);
31229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3123194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3125194d53e6SMatthew G. Knepley }
3126194d53e6SMatthew G. Knepley 
31279ee2af8cSMatthew G. Knepley /*@
31289ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31299ee2af8cSMatthew G. Knepley 
313020f4b53cSBarry Smith   Not Collective
31319ee2af8cSMatthew G. Knepley 
31329ee2af8cSMatthew G. Knepley   Input Parameters:
3133dce8aebaSBarry Smith + ds - The `PetscDS` object
31349ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31359ee2af8cSMatthew G. Knepley 
31369ee2af8cSMatthew G. Knepley   Output Parameter:
31379ee2af8cSMatthew G. Knepley . offsets - The offsets
31389ee2af8cSMatthew G. Knepley 
31399ee2af8cSMatthew G. Knepley   Level: beginner
31409ee2af8cSMatthew G. Knepley 
3141dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31429ee2af8cSMatthew G. Knepley @*/
3143d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3144d71ae5a4SJacob Faibussowitsch {
31459ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31469ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31474f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
314828b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
314963a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31509566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31519ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31539ee2af8cSMatthew G. Knepley }
31549ee2af8cSMatthew G. Knepley 
31559ee2af8cSMatthew G. Knepley /*@
31569ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31579ee2af8cSMatthew G. Knepley 
315820f4b53cSBarry Smith   Not Collective
31599ee2af8cSMatthew G. Knepley 
31609ee2af8cSMatthew G. Knepley   Input Parameters:
3161dce8aebaSBarry Smith + ds - The `PetscDS` object
31629ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31639ee2af8cSMatthew G. Knepley 
31649ee2af8cSMatthew G. Knepley   Output Parameter:
31659ee2af8cSMatthew G. Knepley . offsets - The offsets
31669ee2af8cSMatthew G. Knepley 
31679ee2af8cSMatthew G. Knepley   Level: beginner
31689ee2af8cSMatthew G. Knepley 
3169dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31709ee2af8cSMatthew G. Knepley @*/
3171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3172d71ae5a4SJacob Faibussowitsch {
31739ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31749ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31754f572ea9SToby Isaac   PetscAssertPointer(offsets, 3);
317628b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
317763a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31789566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31799ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31819ee2af8cSMatthew G. Knepley }
31829ee2af8cSMatthew G. Knepley 
318368c9edb9SMatthew G. Knepley /*@C
318468c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
318568c9edb9SMatthew G. Knepley 
318620f4b53cSBarry Smith   Not Collective
318768c9edb9SMatthew G. Knepley 
318868c9edb9SMatthew G. Knepley   Input Parameter:
3189dce8aebaSBarry Smith . prob - The `PetscDS` object
319068c9edb9SMatthew G. Knepley 
3191ef0bb6c7SMatthew G. Knepley   Output Parameter:
3192ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
319368c9edb9SMatthew G. Knepley 
319468c9edb9SMatthew G. Knepley   Level: intermediate
319568c9edb9SMatthew G. Knepley 
3196dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
319768c9edb9SMatthew G. Knepley @*/
3198d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3199d71ae5a4SJacob Faibussowitsch {
32002764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32012764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32024f572ea9SToby Isaac   PetscAssertPointer(T, 2);
32039566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3204ef0bb6c7SMatthew G. Knepley   *T = prob->T;
32053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32062764a2aaSMatthew G. Knepley }
32072764a2aaSMatthew G. Knepley 
320868c9edb9SMatthew G. Knepley /*@C
32094d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
321068c9edb9SMatthew G. Knepley 
321120f4b53cSBarry Smith   Not Collective
321268c9edb9SMatthew G. Knepley 
321368c9edb9SMatthew G. Knepley   Input Parameter:
3214dce8aebaSBarry Smith . prob - The `PetscDS` object
321568c9edb9SMatthew G. Knepley 
3216ef0bb6c7SMatthew G. Knepley   Output Parameter:
3217a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
321868c9edb9SMatthew G. Knepley 
321968c9edb9SMatthew G. Knepley   Level: intermediate
322068c9edb9SMatthew G. Knepley 
3221dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
322268c9edb9SMatthew G. Knepley @*/
3223d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3224d71ae5a4SJacob Faibussowitsch {
32252764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32262764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32274f572ea9SToby Isaac   PetscAssertPointer(Tf, 2);
32289566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3229ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32312764a2aaSMatthew G. Knepley }
32322764a2aaSMatthew G. Knepley 
3233d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3234d71ae5a4SJacob Faibussowitsch {
32352764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32362764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32379566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32389371c9d4SSatish Balay   if (u) {
32394f572ea9SToby Isaac     PetscAssertPointer(u, 2);
32409371c9d4SSatish Balay     *u = prob->u;
32419371c9d4SSatish Balay   }
32429371c9d4SSatish Balay   if (u_t) {
32434f572ea9SToby Isaac     PetscAssertPointer(u_t, 3);
32449371c9d4SSatish Balay     *u_t = prob->u_t;
32459371c9d4SSatish Balay   }
32469371c9d4SSatish Balay   if (u_x) {
32474f572ea9SToby Isaac     PetscAssertPointer(u_x, 4);
32489371c9d4SSatish Balay     *u_x = prob->u_x;
32499371c9d4SSatish Balay   }
32503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32512764a2aaSMatthew G. Knepley }
32522764a2aaSMatthew G. Knepley 
3253d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3254d71ae5a4SJacob Faibussowitsch {
32552764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32562764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32579566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32589371c9d4SSatish Balay   if (f0) {
32594f572ea9SToby Isaac     PetscAssertPointer(f0, 2);
32609371c9d4SSatish Balay     *f0 = prob->f0;
32619371c9d4SSatish Balay   }
32629371c9d4SSatish Balay   if (f1) {
32634f572ea9SToby Isaac     PetscAssertPointer(f1, 3);
32649371c9d4SSatish Balay     *f1 = prob->f1;
32659371c9d4SSatish Balay   }
32669371c9d4SSatish Balay   if (g0) {
32674f572ea9SToby Isaac     PetscAssertPointer(g0, 4);
32689371c9d4SSatish Balay     *g0 = prob->g0;
32699371c9d4SSatish Balay   }
32709371c9d4SSatish Balay   if (g1) {
32714f572ea9SToby Isaac     PetscAssertPointer(g1, 5);
32729371c9d4SSatish Balay     *g1 = prob->g1;
32739371c9d4SSatish Balay   }
32749371c9d4SSatish Balay   if (g2) {
32754f572ea9SToby Isaac     PetscAssertPointer(g2, 6);
32769371c9d4SSatish Balay     *g2 = prob->g2;
32779371c9d4SSatish Balay   }
32789371c9d4SSatish Balay   if (g3) {
32794f572ea9SToby Isaac     PetscAssertPointer(g3, 7);
32809371c9d4SSatish Balay     *g3 = prob->g3;
32819371c9d4SSatish Balay   }
32823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32832764a2aaSMatthew G. Knepley }
32842764a2aaSMatthew G. Knepley 
3285d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3286d71ae5a4SJacob Faibussowitsch {
32872764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32882764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32899566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32909371c9d4SSatish Balay   if (x) {
32914f572ea9SToby Isaac     PetscAssertPointer(x, 2);
32929371c9d4SSatish Balay     *x = prob->x;
32939371c9d4SSatish Balay   }
32949371c9d4SSatish Balay   if (basisReal) {
32954f572ea9SToby Isaac     PetscAssertPointer(basisReal, 3);
32969371c9d4SSatish Balay     *basisReal = prob->basisReal;
32979371c9d4SSatish Balay   }
32989371c9d4SSatish Balay   if (basisDerReal) {
32994f572ea9SToby Isaac     PetscAssertPointer(basisDerReal, 4);
33009371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
33019371c9d4SSatish Balay   }
33029371c9d4SSatish Balay   if (testReal) {
33034f572ea9SToby Isaac     PetscAssertPointer(testReal, 5);
33049371c9d4SSatish Balay     *testReal = prob->testReal;
33059371c9d4SSatish Balay   }
33069371c9d4SSatish Balay   if (testDerReal) {
33074f572ea9SToby Isaac     PetscAssertPointer(testDerReal, 6);
33089371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
33099371c9d4SSatish Balay   }
33103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33112764a2aaSMatthew G. Knepley }
33122764a2aaSMatthew G. Knepley 
331358ebd649SToby Isaac /*@C
3314a4e35b19SJacob Faibussowitsch   PetscDSAddBoundary - Add a boundary condition to the model.
331558ebd649SToby Isaac 
331620f4b53cSBarry Smith   Collective
3317783e2ec8SMatthew G. Knepley 
331858ebd649SToby Isaac   Input Parameters:
331958ebd649SToby Isaac + ds       - The PetscDS object
3320dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
332158ebd649SToby Isaac . name     - The BC name
332245480ffeSMatthew G. Knepley . label    - The label defining constrained points
3323dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
332445480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
332558ebd649SToby Isaac . field    - The field to constrain
332645480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
332758ebd649SToby Isaac . comps    - An array of constrained component numbers
332858ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3329a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
333058ebd649SToby Isaac - ctx      - An optional user context for bcFunc
333158ebd649SToby Isaac 
33322fe279fdSBarry Smith   Output Parameter:
333360225df5SJacob Faibussowitsch . bd - The boundary number
333445480ffeSMatthew G. Knepley 
333558ebd649SToby Isaac   Options Database Keys:
333658ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
333758ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
333858ebd649SToby Isaac 
3339dce8aebaSBarry Smith   Level: developer
3340dce8aebaSBarry Smith 
334156cf3b9cSMatthew G. Knepley   Note:
3342a4e35b19SJacob Faibussowitsch   Both `bcFunc` and `bcFunc_t` will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, then the calling sequence is\:
334356cf3b9cSMatthew G. Knepley 
334420f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
334556cf3b9cSMatthew G. Knepley 
3346a4e35b19SJacob Faibussowitsch   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is\:
3347dce8aebaSBarry Smith .vb
334820f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3349dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3350dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3351dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3352dce8aebaSBarry Smith .ve
335356cf3b9cSMatthew G. Knepley + dim - the spatial dimension
335456cf3b9cSMatthew G. Knepley . Nf - the number of fields
335556cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
335656cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
335756cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
335856cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
335956cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
336056cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
336156cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
336256cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
336356cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
336456cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
336556cf3b9cSMatthew G. Knepley . t - current time
336656cf3b9cSMatthew G. Knepley . x - coordinates of the current point
336756cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
336856cf3b9cSMatthew G. Knepley . constants - constant parameters
336956cf3b9cSMatthew G. Knepley - bcval - output values at the current point
337056cf3b9cSMatthew G. Knepley 
3371a4e35b19SJacob Faibussowitsch   Notes:
3372a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3373a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3374a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3375a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3376a4e35b19SJacob Faibussowitsch 
3377dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
337858ebd649SToby Isaac @*/
3379d71ae5a4SJacob 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)
3380d71ae5a4SJacob Faibussowitsch {
338145480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
338245480ffeSMatthew G. Knepley   PetscInt    n    = 0;
338345480ffeSMatthew G. Knepley   const char *lname;
338458ebd649SToby Isaac 
338558ebd649SToby Isaac   PetscFunctionBegin;
338658ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3387783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
33884f572ea9SToby Isaac   PetscAssertPointer(name, 3);
338945480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
339045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
339145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
339245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3393dce9da9cSMatthew 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);
3394d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3395d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3396d57bb9dbSMatthew G. Knepley     PetscInt  c;
3397d57bb9dbSMatthew G. Knepley 
33989566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
339963a3b9bcSJacob 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);
3400d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
34011dca8a05SBarry 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);
3402d57bb9dbSMatthew G. Knepley     }
3403d57bb9dbSMatthew G. Knepley   }
34049566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34059566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34069566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34079566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34089566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34099566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34109566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34119566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34129566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
34139566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3414f971fd6bSMatthew G. Knepley   b->type   = type;
341545480ffeSMatthew G. Knepley   b->label  = label;
341645480ffeSMatthew G. Knepley   b->Nv     = Nv;
341758ebd649SToby Isaac   b->field  = field;
341845480ffeSMatthew G. Knepley   b->Nc     = Nc;
341958ebd649SToby Isaac   b->func   = bcFunc;
342056cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
342158ebd649SToby Isaac   b->ctx    = ctx;
342245480ffeSMatthew G. Knepley   b->next   = NULL;
342345480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
342445480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
342545480ffeSMatthew G. Knepley   while (head) {
342645480ffeSMatthew G. Knepley     if (!head->next) {
342745480ffeSMatthew G. Knepley       head->next = b;
342845480ffeSMatthew G. Knepley       head       = b;
342945480ffeSMatthew G. Knepley     }
343045480ffeSMatthew G. Knepley     head = head->next;
343145480ffeSMatthew G. Knepley     ++n;
343245480ffeSMatthew G. Knepley   }
34339371c9d4SSatish Balay   if (bd) {
34344f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
34359371c9d4SSatish Balay     *bd = n;
34369371c9d4SSatish Balay   }
34373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
343845480ffeSMatthew G. Knepley }
343945480ffeSMatthew G. Knepley 
3440a4e35b19SJacob Faibussowitsch // PetscClangLinter pragma ignore: -fdoc-section-header-unknown
344145480ffeSMatthew G. Knepley /*@C
3442a4e35b19SJacob Faibussowitsch   PetscDSAddBoundaryByName - Add a boundary condition to the model.
344345480ffeSMatthew G. Knepley 
344420f4b53cSBarry Smith   Collective
344545480ffeSMatthew G. Knepley 
344645480ffeSMatthew G. Knepley   Input Parameters:
3447dce8aebaSBarry Smith + ds       - The `PetscDS` object
3448dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
344945480ffeSMatthew G. Knepley . name     - The BC name
345045480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3451dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
345245480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
345345480ffeSMatthew G. Knepley . field    - The field to constrain
345445480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
345545480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
345645480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3457a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
345845480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
345945480ffeSMatthew G. Knepley 
34602fe279fdSBarry Smith   Output Parameter:
346160225df5SJacob Faibussowitsch . bd - The boundary number
346245480ffeSMatthew G. Knepley 
346345480ffeSMatthew G. Knepley   Options Database Keys:
346445480ffeSMatthew G. Knepley + -bc_<boundary name> <num>      - Overrides the boundary ids
346545480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
346645480ffeSMatthew G. Knepley 
346720f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3468dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3469dce8aebaSBarry Smith .vb
347020f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3471dce8aebaSBarry Smith .ve
3472dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3473dce8aebaSBarry Smith .vb
347420f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3475dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3476dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3477dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3478dce8aebaSBarry Smith .ve
347945480ffeSMatthew G. Knepley + dim - the spatial dimension
348045480ffeSMatthew G. Knepley . Nf - the number of fields
348145480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
348245480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
348345480ffeSMatthew G. Knepley . u - each field evaluated at the current point
348445480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
348545480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
348645480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
348745480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
348845480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
348945480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
349045480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
349145480ffeSMatthew G. Knepley . t - current time
349245480ffeSMatthew G. Knepley . x - coordinates of the current point
349345480ffeSMatthew G. Knepley . numConstants - number of constant parameters
349445480ffeSMatthew G. Knepley . constants - constant parameters
349545480ffeSMatthew G. Knepley - bcval - output values at the current point
349645480ffeSMatthew G. Knepley 
349745480ffeSMatthew G. Knepley   Level: developer
349845480ffeSMatthew G. Knepley 
3499a4e35b19SJacob Faibussowitsch   Notes:
3500a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3501a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3502a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3503a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3504a4e35b19SJacob Faibussowitsch 
3505dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3506dce8aebaSBarry Smith 
3507dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
350845480ffeSMatthew G. Knepley @*/
3509d71ae5a4SJacob 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)
3510d71ae5a4SJacob Faibussowitsch {
351145480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
351245480ffeSMatthew G. Knepley   PetscInt   n    = 0;
351345480ffeSMatthew G. Knepley 
351445480ffeSMatthew G. Knepley   PetscFunctionBegin;
351545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
351645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
35174f572ea9SToby Isaac   PetscAssertPointer(name, 3);
35184f572ea9SToby Isaac   PetscAssertPointer(lname, 4);
351945480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
352045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
352145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
35229566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
35239566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
35249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
35259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
35269566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35279566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35299566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35309566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
353145480ffeSMatthew G. Knepley   b->type   = type;
353245480ffeSMatthew G. Knepley   b->label  = NULL;
353345480ffeSMatthew G. Knepley   b->Nv     = Nv;
353445480ffeSMatthew G. Knepley   b->field  = field;
353545480ffeSMatthew G. Knepley   b->Nc     = Nc;
353645480ffeSMatthew G. Knepley   b->func   = bcFunc;
353745480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
353845480ffeSMatthew G. Knepley   b->ctx    = ctx;
353945480ffeSMatthew G. Knepley   b->next   = NULL;
354045480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
354145480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
354245480ffeSMatthew G. Knepley   while (head) {
354345480ffeSMatthew G. Knepley     if (!head->next) {
354445480ffeSMatthew G. Knepley       head->next = b;
354545480ffeSMatthew G. Knepley       head       = b;
354645480ffeSMatthew G. Knepley     }
354745480ffeSMatthew G. Knepley     head = head->next;
354845480ffeSMatthew G. Knepley     ++n;
354945480ffeSMatthew G. Knepley   }
35509371c9d4SSatish Balay   if (bd) {
35514f572ea9SToby Isaac     PetscAssertPointer(bd, 13);
35529371c9d4SSatish Balay     *bd = n;
35539371c9d4SSatish Balay   }
35543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355558ebd649SToby Isaac }
355658ebd649SToby Isaac 
3557b67eacb3SMatthew G. Knepley /*@C
3558a4e35b19SJacob Faibussowitsch   PetscDSUpdateBoundary - Change a boundary condition for the model.
3559b67eacb3SMatthew G. Knepley 
3560b67eacb3SMatthew G. Knepley   Input Parameters:
3561dce8aebaSBarry Smith + ds       - The `PetscDS` object
3562b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3563dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3564b67eacb3SMatthew G. Knepley . name     - The BC name
356545480ffeSMatthew G. Knepley . label    - The label defining constrained points
3566dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
356745480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3568b67eacb3SMatthew G. Knepley . field    - The field to constrain
356945480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3570b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3571b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3572a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3573b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3574b67eacb3SMatthew G. Knepley 
3575b67eacb3SMatthew G. Knepley   Level: developer
3576b67eacb3SMatthew G. Knepley 
3577a4e35b19SJacob Faibussowitsch   Notes:
3578a4e35b19SJacob Faibussowitsch   The pointwise functions are used to provide boundary values for essential boundary
3579a4e35b19SJacob Faibussowitsch   conditions. In FEM, they are acting upon by dual basis functionals to generate FEM
3580a4e35b19SJacob Faibussowitsch   coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3581a4e35b19SJacob Faibussowitsch   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
3582a4e35b19SJacob Faibussowitsch 
3583dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3584dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3585dce8aebaSBarry Smith 
3586dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3587b67eacb3SMatthew G. Knepley @*/
3588d71ae5a4SJacob 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)
3589d71ae5a4SJacob Faibussowitsch {
3590b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3591b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3592b67eacb3SMatthew G. Knepley 
3593b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3594b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3595b67eacb3SMatthew G. Knepley   while (b) {
3596b67eacb3SMatthew G. Knepley     if (n == bd) break;
3597b67eacb3SMatthew G. Knepley     b = b->next;
3598b67eacb3SMatthew G. Knepley     ++n;
3599b67eacb3SMatthew G. Knepley   }
360063a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3601b67eacb3SMatthew G. Knepley   if (name) {
36029566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
36039566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3604b67eacb3SMatthew G. Knepley   }
3605b67eacb3SMatthew G. Knepley   b->type = type;
360645480ffeSMatthew G. Knepley   if (label) {
360745480ffeSMatthew G. Knepley     const char *name;
360845480ffeSMatthew G. Knepley 
360945480ffeSMatthew G. Knepley     b->label = label;
36109566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
36119566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
36129566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
361345480ffeSMatthew G. Knepley   }
361445480ffeSMatthew G. Knepley   if (Nv >= 0) {
361545480ffeSMatthew G. Knepley     b->Nv = Nv;
36169566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
36179566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
36189566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
361945480ffeSMatthew G. Knepley   }
362045480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
362145480ffeSMatthew G. Knepley   if (Nc >= 0) {
362245480ffeSMatthew G. Knepley     b->Nc = Nc;
36239566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36249566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
36259566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
362645480ffeSMatthew G. Knepley   }
362745480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
362845480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
362945480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
36303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3631b67eacb3SMatthew G. Knepley }
3632b67eacb3SMatthew G. Knepley 
363358ebd649SToby Isaac /*@
363458ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
363558ebd649SToby Isaac 
36362fe279fdSBarry Smith   Input Parameter:
3637dce8aebaSBarry Smith . ds - The `PetscDS` object
363858ebd649SToby Isaac 
36392fe279fdSBarry Smith   Output Parameter:
364058ebd649SToby Isaac . numBd - The number of BC
364158ebd649SToby Isaac 
364258ebd649SToby Isaac   Level: intermediate
364358ebd649SToby Isaac 
3644dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
364558ebd649SToby Isaac @*/
3646d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3647d71ae5a4SJacob Faibussowitsch {
364858ebd649SToby Isaac   DSBoundary b = ds->boundary;
364958ebd649SToby Isaac 
365058ebd649SToby Isaac   PetscFunctionBegin;
365158ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
36524f572ea9SToby Isaac   PetscAssertPointer(numBd, 2);
365358ebd649SToby Isaac   *numBd = 0;
36549371c9d4SSatish Balay   while (b) {
36559371c9d4SSatish Balay     ++(*numBd);
36569371c9d4SSatish Balay     b = b->next;
36579371c9d4SSatish Balay   }
36583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
365958ebd649SToby Isaac }
366058ebd649SToby Isaac 
366158ebd649SToby Isaac /*@C
36629a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
366358ebd649SToby Isaac 
366458ebd649SToby Isaac   Input Parameters:
3665dce8aebaSBarry Smith + ds - The `PetscDS` object
366658ebd649SToby Isaac - bd - The BC number
366758ebd649SToby Isaac 
366858ebd649SToby Isaac   Output Parameters:
3669dce8aebaSBarry Smith + wf     - The `PetscWeakForm` holding the pointwise functions
3670dce8aebaSBarry Smith . type   - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
367158ebd649SToby Isaac . name   - The BC name
367245480ffeSMatthew G. Knepley . label  - The label defining constrained points
3673dce8aebaSBarry Smith . Nv     - The number of `DMLabel` ids for constrained points
367445480ffeSMatthew G. Knepley . values - An array of ids for constrained points
367558ebd649SToby Isaac . field  - The field to constrain
367645480ffeSMatthew G. Knepley . Nc     - The number of constrained field components
367758ebd649SToby Isaac . comps  - An array of constrained component numbers
367860225df5SJacob Faibussowitsch . func   - A pointwise function giving boundary values
367960225df5SJacob Faibussowitsch . func_t - A pointwise function giving the time derivative of the boundary values
368058ebd649SToby Isaac - ctx    - An optional user context for bcFunc
368158ebd649SToby Isaac 
368258ebd649SToby Isaac   Options Database Keys:
368358ebd649SToby Isaac + -bc_<boundary name> <num>      - Overrides the boundary ids
368458ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
368558ebd649SToby Isaac 
368658ebd649SToby Isaac   Level: developer
368758ebd649SToby Isaac 
3688dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
368958ebd649SToby Isaac @*/
3690d71ae5a4SJacob 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)
3691d71ae5a4SJacob Faibussowitsch {
369258ebd649SToby Isaac   DSBoundary b = ds->boundary;
369358ebd649SToby Isaac   PetscInt   n = 0;
369458ebd649SToby Isaac 
369558ebd649SToby Isaac   PetscFunctionBegin;
369658ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
369758ebd649SToby Isaac   while (b) {
369858ebd649SToby Isaac     if (n == bd) break;
369958ebd649SToby Isaac     b = b->next;
370058ebd649SToby Isaac     ++n;
370158ebd649SToby Isaac   }
370263a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
370345480ffeSMatthew G. Knepley   if (wf) {
37044f572ea9SToby Isaac     PetscAssertPointer(wf, 3);
370545480ffeSMatthew G. Knepley     *wf = b->wf;
370645480ffeSMatthew G. Knepley   }
3707f971fd6bSMatthew G. Knepley   if (type) {
37084f572ea9SToby Isaac     PetscAssertPointer(type, 4);
3709f971fd6bSMatthew G. Knepley     *type = b->type;
371058ebd649SToby Isaac   }
371158ebd649SToby Isaac   if (name) {
37124f572ea9SToby Isaac     PetscAssertPointer(name, 5);
371358ebd649SToby Isaac     *name = b->name;
371458ebd649SToby Isaac   }
371545480ffeSMatthew G. Knepley   if (label) {
37164f572ea9SToby Isaac     PetscAssertPointer(label, 6);
371745480ffeSMatthew G. Knepley     *label = b->label;
371845480ffeSMatthew G. Knepley   }
371945480ffeSMatthew G. Knepley   if (Nv) {
37204f572ea9SToby Isaac     PetscAssertPointer(Nv, 7);
372145480ffeSMatthew G. Knepley     *Nv = b->Nv;
372245480ffeSMatthew G. Knepley   }
372345480ffeSMatthew G. Knepley   if (values) {
37244f572ea9SToby Isaac     PetscAssertPointer(values, 8);
372545480ffeSMatthew G. Knepley     *values = b->values;
372658ebd649SToby Isaac   }
372758ebd649SToby Isaac   if (field) {
37284f572ea9SToby Isaac     PetscAssertPointer(field, 9);
372958ebd649SToby Isaac     *field = b->field;
373058ebd649SToby Isaac   }
373145480ffeSMatthew G. Knepley   if (Nc) {
37324f572ea9SToby Isaac     PetscAssertPointer(Nc, 10);
373345480ffeSMatthew G. Knepley     *Nc = b->Nc;
373458ebd649SToby Isaac   }
373558ebd649SToby Isaac   if (comps) {
37364f572ea9SToby Isaac     PetscAssertPointer(comps, 11);
373758ebd649SToby Isaac     *comps = b->comps;
373858ebd649SToby Isaac   }
373958ebd649SToby Isaac   if (func) {
37404f572ea9SToby Isaac     PetscAssertPointer(func, 12);
374158ebd649SToby Isaac     *func = b->func;
374258ebd649SToby Isaac   }
374356cf3b9cSMatthew G. Knepley   if (func_t) {
37444f572ea9SToby Isaac     PetscAssertPointer(func_t, 13);
374556cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
374656cf3b9cSMatthew G. Knepley   }
374758ebd649SToby Isaac   if (ctx) {
37484f572ea9SToby Isaac     PetscAssertPointer(ctx, 14);
374958ebd649SToby Isaac     *ctx = b->ctx;
375058ebd649SToby Isaac   }
37513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
375258ebd649SToby Isaac }
375358ebd649SToby Isaac 
375410af620dSMatthew G. Knepley /*@
375510af620dSMatthew G. Knepley   PetscDSUpdateBoundaryLabels - Update `DMLabel` in each boundary condition using the label name and the input `DM`
375610af620dSMatthew G. Knepley 
375710af620dSMatthew G. Knepley   Not Collective
375810af620dSMatthew G. Knepley 
375910af620dSMatthew G. Knepley   Input Parameters:
376010af620dSMatthew G. Knepley + ds - The source `PetscDS` object
376110af620dSMatthew G. Knepley - dm - The `DM` holding labels
376210af620dSMatthew G. Knepley 
376310af620dSMatthew G. Knepley   Level: intermediate
376410af620dSMatthew G. Knepley 
376510af620dSMatthew G. Knepley .seealso: `PetscDS`, `DMBoundary`, `DM`, `PetscDSCopyBoundary()`, `PetscDSCreate()`, `DMGetLabel()`
376610af620dSMatthew G. Knepley @*/
376710af620dSMatthew G. Knepley PetscErrorCode PetscDSUpdateBoundaryLabels(PetscDS ds, DM dm)
376810af620dSMatthew G. Knepley {
376910af620dSMatthew G. Knepley   DSBoundary b;
377010af620dSMatthew G. Knepley 
377110af620dSMatthew G. Knepley   PetscFunctionBegin;
377210af620dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
377310af620dSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
377410af620dSMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
377510af620dSMatthew G. Knepley     if (b->lname) PetscCall(DMGetLabel(dm, b->lname, &b->label));
377610af620dSMatthew G. Knepley   }
377710af620dSMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
377810af620dSMatthew G. Knepley }
377910af620dSMatthew G. Knepley 
3780d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3781d71ae5a4SJacob Faibussowitsch {
378245480ffeSMatthew G. Knepley   PetscFunctionBegin;
37839566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37849566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37859566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37869566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37879566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
378845480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
378945480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
379045480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37929566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
379345480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
379445480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37959566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37969566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
379745480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
379845480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
379945480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
38003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
380145480ffeSMatthew G. Knepley }
380245480ffeSMatthew G. Knepley 
38039252d075SMatthew G. Knepley /*@
38049252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
38059252d075SMatthew G. Knepley 
380620f4b53cSBarry Smith   Not Collective
38079252d075SMatthew G. Knepley 
380836951cb5SMatthew G. Knepley   Input Parameters:
3809dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3810dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
381136951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
38129252d075SMatthew G. Knepley 
38139252d075SMatthew G. Knepley   Output Parameter:
3814dce8aebaSBarry Smith . newds - The target `PetscDS`, now with a copy of the boundary conditions
38159252d075SMatthew G. Knepley 
38169252d075SMatthew G. Knepley   Level: intermediate
38179252d075SMatthew G. Knepley 
3818dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38199252d075SMatthew G. Knepley @*/
3820d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3821d71ae5a4SJacob Faibussowitsch {
382245480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3823dff059c6SToby Isaac 
3824dff059c6SToby Isaac   PetscFunctionBegin;
382536951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
382636951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
38273ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
38289566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
3829*f4f49eeaSPierre Jolivet   lastnext = &newds->boundary;
383036951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3831dff059c6SToby Isaac     DSBoundary bNew;
383236951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3833dff059c6SToby Isaac 
383436951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
383536951cb5SMatthew G. Knepley       PetscInt f;
383636951cb5SMatthew G. Knepley 
38379371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
38389371c9d4SSatish Balay         if (b->field == fields[f]) break;
383936951cb5SMatthew G. Knepley       if (f == numFields) continue;
384036951cb5SMatthew G. Knepley       fieldNew = f;
384136951cb5SMatthew G. Knepley     }
38429566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
384336951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3844dff059c6SToby Isaac     *lastnext   = bNew;
3845*f4f49eeaSPierre Jolivet     lastnext    = &bNew->next;
3846dff059c6SToby Isaac   }
38473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3848dff059c6SToby Isaac }
3849dff059c6SToby Isaac 
38506c1eb96dSMatthew G. Knepley /*@
3851dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
385245480ffeSMatthew G. Knepley 
385320f4b53cSBarry Smith   Not Collective
385445480ffeSMatthew G. Knepley 
385545480ffeSMatthew G. Knepley   Input Parameter:
3856dce8aebaSBarry Smith . ds - The `PetscDS` object
385745480ffeSMatthew G. Knepley 
385845480ffeSMatthew G. Knepley   Level: intermediate
385945480ffeSMatthew G. Knepley 
3860dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
386145480ffeSMatthew G. Knepley @*/
3862d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3863d71ae5a4SJacob Faibussowitsch {
386445480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
386545480ffeSMatthew G. Knepley 
386645480ffeSMatthew G. Knepley   PetscFunctionBegin;
386745480ffeSMatthew G. Knepley   while (next) {
386845480ffeSMatthew G. Knepley     DSBoundary b = next;
386945480ffeSMatthew G. Knepley 
387045480ffeSMatthew G. Knepley     next = b->next;
38719566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38729566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38739566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38749566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38759566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38769566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
387745480ffeSMatthew G. Knepley   }
38783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
387945480ffeSMatthew G. Knepley }
388045480ffeSMatthew G. Knepley 
388145480ffeSMatthew G. Knepley /*@
38826c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38836c1eb96dSMatthew G. Knepley 
388420f4b53cSBarry Smith   Not Collective
38856c1eb96dSMatthew G. Knepley 
3886d8d19677SJose E. Roman   Input Parameters:
3887dce8aebaSBarry Smith + prob      - The `PetscDS` object
38886c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38896c1eb96dSMatthew G. Knepley - fields    - Old field number for each new field
38906c1eb96dSMatthew G. Knepley 
38916c1eb96dSMatthew G. Knepley   Output Parameter:
3892dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38936c1eb96dSMatthew G. Knepley 
38946c1eb96dSMatthew G. Knepley   Level: intermediate
38956c1eb96dSMatthew G. Knepley 
3896dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38976c1eb96dSMatthew G. Knepley @*/
3898d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3899d71ae5a4SJacob Faibussowitsch {
39006c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
39016c1eb96dSMatthew G. Knepley 
39026c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
39036c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39044f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
39056c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39069566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39079566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
390845480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
39096c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39106c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
39116c1eb96dSMatthew G. Knepley     PetscObject    disc;
39126c1eb96dSMatthew G. Knepley 
39136c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
39149566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
39159566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
39166c1eb96dSMatthew G. Knepley   }
39173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39186c1eb96dSMatthew G. Knepley }
39196c1eb96dSMatthew G. Knepley 
39206c1eb96dSMatthew G. Knepley /*@
39219252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
39229252d075SMatthew G. Knepley 
392320f4b53cSBarry Smith   Not Collective
39249252d075SMatthew G. Knepley 
3925d8d19677SJose E. Roman   Input Parameters:
3926dce8aebaSBarry Smith + prob      - The `PetscDS` object
39279252d075SMatthew G. Knepley . numFields - Number of new fields
39289252d075SMatthew G. Knepley - fields    - Old field number for each new field
39299252d075SMatthew G. Knepley 
39309252d075SMatthew G. Knepley   Output Parameter:
3931dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39329252d075SMatthew G. Knepley 
39339252d075SMatthew G. Knepley   Level: intermediate
39349252d075SMatthew G. Knepley 
3935dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39369252d075SMatthew G. Knepley @*/
3937d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3938d71ae5a4SJacob Faibussowitsch {
39399252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
39409252d075SMatthew G. Knepley 
39419252d075SMatthew G. Knepley   PetscFunctionBegin;
39429252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39434f572ea9SToby Isaac   if (fields) PetscAssertPointer(fields, 3);
39449252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39459566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39469566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
394763a3b9bcSJacob 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);
39489252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39499252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
39509252d075SMatthew G. Knepley     PetscPointFunc   obj;
39519252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
39529252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
39539252d075SMatthew G. Knepley     PetscRiemannFunc r;
39549252d075SMatthew G. Knepley 
3955c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
39569566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
39579566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39589566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39599566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39609566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39619566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39629566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39639566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39649252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39659252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39669252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39679252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39689252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39699252d075SMatthew G. Knepley 
3970c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39719566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39729566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39739566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39749566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39759566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39769566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39779252d075SMatthew G. Knepley     }
39789252d075SMatthew G. Knepley   }
39793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39809252d075SMatthew G. Knepley }
39819252d075SMatthew G. Knepley 
3982da51fcedSMatthew G. Knepley /*@
3983dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3984da51fcedSMatthew G. Knepley 
398520f4b53cSBarry Smith   Not Collective
3986da51fcedSMatthew G. Knepley 
3987da51fcedSMatthew G. Knepley   Input Parameter:
3988dce8aebaSBarry Smith . prob - The `PetscDS` object
3989da51fcedSMatthew G. Knepley 
3990da51fcedSMatthew G. Knepley   Output Parameter:
3991dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3992da51fcedSMatthew G. Knepley 
3993da51fcedSMatthew G. Knepley   Level: intermediate
3994da51fcedSMatthew G. Knepley 
3995dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3996da51fcedSMatthew G. Knepley @*/
3997d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3998d71ae5a4SJacob Faibussowitsch {
3999b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
40009252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
4001da51fcedSMatthew G. Knepley 
4002da51fcedSMatthew G. Knepley   PetscFunctionBegin;
4003da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4004da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40059566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40069566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
400763a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
40089566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
40099566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
40109566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
40113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40129252d075SMatthew G. Knepley }
401345480ffeSMatthew G. Knepley 
40149252d075SMatthew G. Knepley /*@
4015dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
4016da51fcedSMatthew G. Knepley 
401720f4b53cSBarry Smith   Not Collective
40189252d075SMatthew G. Knepley 
40199252d075SMatthew G. Knepley   Input Parameter:
4020dce8aebaSBarry Smith . prob - The `PetscDS` object
40219252d075SMatthew G. Knepley 
40229252d075SMatthew G. Knepley   Output Parameter:
4023dce8aebaSBarry Smith . newprob - The `PetscDS` copy
40249252d075SMatthew G. Knepley 
40259252d075SMatthew G. Knepley   Level: intermediate
40269252d075SMatthew G. Knepley 
4027dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
40289252d075SMatthew G. Knepley @*/
4029d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
4030d71ae5a4SJacob Faibussowitsch {
40319252d075SMatthew G. Knepley   PetscInt           Nc;
40329252d075SMatthew G. Knepley   const PetscScalar *constants;
40339252d075SMatthew G. Knepley 
40349252d075SMatthew G. Knepley   PetscFunctionBegin;
40359252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
40369252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
40379566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
40389566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
40393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4040da51fcedSMatthew G. Knepley }
4041da51fcedSMatthew G. Knepley 
404245480ffeSMatthew G. Knepley /*@
4043dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
404445480ffeSMatthew G. Knepley 
404520f4b53cSBarry Smith   Not Collective
404645480ffeSMatthew G. Knepley 
404745480ffeSMatthew G. Knepley   Input Parameter:
4048dce8aebaSBarry Smith . ds - The `PetscDS` object
404945480ffeSMatthew G. Knepley 
405045480ffeSMatthew G. Knepley   Output Parameter:
4051dce8aebaSBarry Smith . newds - The `PetscDS` copy
405245480ffeSMatthew G. Knepley 
405345480ffeSMatthew G. Knepley   Level: intermediate
405445480ffeSMatthew G. Knepley 
4055dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
405645480ffeSMatthew G. Knepley @*/
4057d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4058d71ae5a4SJacob Faibussowitsch {
40598434afd1SBarry Smith   PetscSimplePointFn *sol;
406045480ffeSMatthew G. Knepley   void               *ctx;
406145480ffeSMatthew G. Knepley   PetscInt            Nf, f;
406245480ffeSMatthew G. Knepley 
406345480ffeSMatthew G. Knepley   PetscFunctionBegin;
406445480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
406545480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40669566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
406745480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40689566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40699566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40709566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40719566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
407245480ffeSMatthew G. Knepley   }
40733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
407445480ffeSMatthew G. Knepley }
407545480ffeSMatthew G. Knepley 
407607218a29SMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, DM dmNew, PetscDS dsNew)
407707218a29SMatthew G. Knepley {
407807218a29SMatthew G. Knepley   DSBoundary b;
407907218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
408007218a29SMatthew G. Knepley   PetscBool  isCohesive;
408107218a29SMatthew G. Knepley   void      *ctx;
408207218a29SMatthew G. Knepley 
408307218a29SMatthew G. Knepley   PetscFunctionBegin;
408407218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
408507218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
408607218a29SMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew));
408707218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
408807218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
408907218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
409007218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
409107218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
409207218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
409307218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
409407218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
409507218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
409607218a29SMatthew G. Knepley   }
409707218a29SMatthew G. Knepley   if (Nf) {
409807218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
409907218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
410007218a29SMatthew G. Knepley   }
410107218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
410207218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
410307218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
410407218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
410507218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
410607218a29SMatthew G. Knepley   }
410707218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
410807218a29SMatthew G. Knepley }
410907218a29SMatthew G. Knepley 
4110d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4111d71ae5a4SJacob Faibussowitsch {
4112df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4113b1353e8eSMatthew G. Knepley 
4114b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4115b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
41164f572ea9SToby Isaac   PetscAssertPointer(subprob, 3);
41179371c9d4SSatish Balay   if (height == 0) {
41189371c9d4SSatish Balay     *subprob = prob;
41193ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
41209371c9d4SSatish Balay   }
41219566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
41229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
412363a3b9bcSJacob 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);
41249566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4125df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4126b1353e8eSMatthew G. Knepley     PetscInt cdim;
4127b1353e8eSMatthew G. Knepley 
41289566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
41299566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
41309566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4131b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4132b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4133b1353e8eSMatthew G. Knepley       PetscObject  obj;
4134b1353e8eSMatthew G. Knepley       PetscClassId id;
4135b1353e8eSMatthew G. Knepley 
41369566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
41379566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
41389566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
413963a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
41409566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4141b1353e8eSMatthew G. Knepley     }
4142b1353e8eSMatthew G. Knepley   }
4143df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
41443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4145b1353e8eSMatthew G. Knepley }
4146b1353e8eSMatthew G. Knepley 
41474366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
41484366bac7SMatthew G. Knepley {
41494366bac7SMatthew G. Knepley   IS              permIS;
41504366bac7SMatthew G. Knepley   PetscQuadrature quad;
41514366bac7SMatthew G. Knepley   DMPolytopeType  ct;
41524366bac7SMatthew G. Knepley   const PetscInt *perm;
41534366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
41544366bac7SMatthew G. Knepley 
41554366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
41564366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
41574366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
41584366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
41594366bac7SMatthew 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);
416085036b15SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangements(ct) / 2;
41614366bac7SMatthew 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);
41624366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
41634366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
41644366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
41654366bac7SMatthew G. Knepley   *qperm = perm[q];
41664366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
41674366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
41684366bac7SMatthew G. Knepley }
41694366bac7SMatthew G. Knepley 
4170d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4171d71ae5a4SJacob Faibussowitsch {
4172c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4173c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4174c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4175c7bd5f0bSMatthew G. Knepley 
4176c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4177c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41784f572ea9SToby Isaac   PetscAssertPointer(disctype, 3);
4179665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
41809566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
418163a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
41829566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4183665f567fSMatthew G. Knepley   if (obj) {
41849566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4185665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4186665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4187665f567fSMatthew G. Knepley   }
41883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4189c7bd5f0bSMatthew G. Knepley }
4190c7bd5f0bSMatthew G. Knepley 
4191d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4192d71ae5a4SJacob Faibussowitsch {
41932764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41949566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
41953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41962764a2aaSMatthew G. Knepley }
41972764a2aaSMatthew G. Knepley 
4198d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4199d71ae5a4SJacob Faibussowitsch {
42002764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42016528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
42026528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
42036528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
42046528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
42053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42062764a2aaSMatthew G. Knepley }
42072764a2aaSMatthew G. Knepley 
42082764a2aaSMatthew G. Knepley /*MC
42092764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
42102764a2aaSMatthew G. Knepley 
42112764a2aaSMatthew G. Knepley   Level: intermediate
42122764a2aaSMatthew G. Knepley 
4213db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
42142764a2aaSMatthew G. Knepley M*/
42152764a2aaSMatthew G. Knepley 
4216d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4217d71ae5a4SJacob Faibussowitsch {
42182764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
42192764a2aaSMatthew G. Knepley 
42202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
42216528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
42224dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
42236528b96dSMatthew G. Knepley   ds->data = b;
42242764a2aaSMatthew G. Knepley 
42259566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
42263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42272764a2aaSMatthew G. Knepley }
4228