xref: /petsc/src/dm/dt/interface/dtds.c (revision be87f6c03c1c1fd6df2d720f847e0b83790d9220)
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 
302764a2aaSMatthew G. Knepley   Sample usage:
312764a2aaSMatthew G. Knepley .vb
322764a2aaSMatthew G. Knepley     PetscDSRegister("my_ds", MyPetscDSCreate);
332764a2aaSMatthew G. Knepley .ve
342764a2aaSMatthew G. Knepley 
352764a2aaSMatthew G. Knepley   Then, your PetscDS type can be chosen with the procedural interface via
362764a2aaSMatthew G. Knepley .vb
372764a2aaSMatthew G. Knepley     PetscDSCreate(MPI_Comm, PetscDS *);
382764a2aaSMatthew G. Knepley     PetscDSSetType(PetscDS, "my_ds");
392764a2aaSMatthew G. Knepley .ve
402764a2aaSMatthew G. Knepley    or at runtime via the option
412764a2aaSMatthew G. Knepley .vb
422764a2aaSMatthew G. Knepley     -petscds_type my_ds
432764a2aaSMatthew G. Knepley .ve
442764a2aaSMatthew G. Knepley 
452764a2aaSMatthew G. Knepley   Level: advanced
462764a2aaSMatthew G. Knepley 
47dce8aebaSBarry Smith   Note:
48dce8aebaSBarry Smith   `PetscDSRegister()` may be called multiple times to add several user-defined `PetscDSs`
49dce8aebaSBarry Smith 
50dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSRegisterAll()`, `PetscDSRegisterDestroy()`
512764a2aaSMatthew G. Knepley @*/
52d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
53d71ae5a4SJacob Faibussowitsch {
542764a2aaSMatthew G. Knepley   PetscFunctionBegin;
559566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&PetscDSList, sname, function));
563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
572764a2aaSMatthew G. Knepley }
582764a2aaSMatthew G. Knepley 
592764a2aaSMatthew G. Knepley /*@C
60dce8aebaSBarry Smith   PetscDSSetType - Builds a particular `PetscDS`
612764a2aaSMatthew G. Knepley 
6220f4b53cSBarry Smith   Collective; No Fortran Support
632764a2aaSMatthew G. Knepley 
642764a2aaSMatthew G. Knepley   Input Parameters:
65dce8aebaSBarry Smith + prob - The `PetscDS` object
66dce8aebaSBarry Smith - name - The `PetscDSType`
672764a2aaSMatthew G. Knepley 
682764a2aaSMatthew G. Knepley   Options Database Key:
692764a2aaSMatthew G. Knepley . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
702764a2aaSMatthew G. Knepley 
712764a2aaSMatthew G. Knepley   Level: intermediate
722764a2aaSMatthew G. Knepley 
73dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSGetType()`, `PetscDSCreate()`
742764a2aaSMatthew G. Knepley @*/
75d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
76d71ae5a4SJacob Faibussowitsch {
772764a2aaSMatthew G. Knepley   PetscErrorCode (*r)(PetscDS);
782764a2aaSMatthew G. Knepley   PetscBool match;
792764a2aaSMatthew G. Knepley 
802764a2aaSMatthew G. Knepley   PetscFunctionBegin;
812764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)prob, name, &match));
833ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
842764a2aaSMatthew G. Knepley 
859566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
869566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscDSList, name, &r));
8728b400f6SJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
882764a2aaSMatthew G. Knepley 
89dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, destroy);
902764a2aaSMatthew G. Knepley   prob->ops->destroy = NULL;
91dbbe0bcdSBarry Smith 
929566063dSJacob Faibussowitsch   PetscCall((*r)(prob));
939566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)prob, name));
943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
952764a2aaSMatthew G. Knepley }
962764a2aaSMatthew G. Knepley 
972764a2aaSMatthew G. Knepley /*@C
98dce8aebaSBarry Smith   PetscDSGetType - Gets the `PetscDSType` name (as a string) from the `PetscDS`
992764a2aaSMatthew G. Knepley 
10020f4b53cSBarry Smith   Not Collective; No Fortran Support
1012764a2aaSMatthew G. Knepley 
1022764a2aaSMatthew G. Knepley   Input Parameter:
103dce8aebaSBarry Smith . prob  - The `PetscDS`
1042764a2aaSMatthew G. Knepley 
1052764a2aaSMatthew G. Knepley   Output Parameter:
106dce8aebaSBarry Smith . name - The `PetscDSType` name
1072764a2aaSMatthew G. Knepley 
1082764a2aaSMatthew G. Knepley   Level: intermediate
1092764a2aaSMatthew G. Knepley 
110dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSSetType()`, `PetscDSCreate()`
1112764a2aaSMatthew G. Knepley @*/
112d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
113d71ae5a4SJacob Faibussowitsch {
1142764a2aaSMatthew G. Knepley   PetscFunctionBegin;
1152764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
116c959eef4SJed Brown   PetscValidPointer(name, 2);
1179566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
1182764a2aaSMatthew G. Knepley   *name = ((PetscObject)prob)->type_name;
1193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1202764a2aaSMatthew G. Knepley }
1212764a2aaSMatthew G. Knepley 
122d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
123d71ae5a4SJacob Faibussowitsch {
1247d8a60eaSMatthew G. Knepley   PetscViewerFormat  format;
12597b6e6e8SMatthew G. Knepley   const PetscScalar *constants;
1265fedec97SMatthew G. Knepley   PetscInt           Nf, numConstants, f;
1277d8a60eaSMatthew G. Knepley 
1287d8a60eaSMatthew G. Knepley   PetscFunctionBegin;
1299566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
1309566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13163a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "Discrete System with %" PetscInt_FMT " fields\n", Nf));
1329566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
13363a3b9bcSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  cell total dim %" PetscInt_FMT " total comp %" PetscInt_FMT "\n", ds->totDim, ds->totComp));
1349566063dSJacob Faibussowitsch   if (ds->isCohesive) PetscCall(PetscViewerASCIIPrintf(viewer, "  cohesive cell\n"));
1355fedec97SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
13640967b3bSMatthew G. Knepley     DSBoundary      b;
1377d8a60eaSMatthew G. Knepley     PetscObject     obj;
1387d8a60eaSMatthew G. Knepley     PetscClassId    id;
139f35450b9SMatthew G. Knepley     PetscQuadrature q;
1407d8a60eaSMatthew G. Knepley     const char     *name;
141f35450b9SMatthew G. Knepley     PetscInt        Nc, Nq, Nqc;
1427d8a60eaSMatthew G. Knepley 
1439566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(ds, f, &obj));
1449566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
1459566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName(obj, &name));
1469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>"));
1479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1487d8a60eaSMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
1499566063dSJacob Faibussowitsch       PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc));
1509566063dSJacob Faibussowitsch       PetscCall(PetscFEGetQuadrature((PetscFE)obj, &q));
1519566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FEM"));
1527d8a60eaSMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
1539566063dSJacob Faibussowitsch       PetscCall(PetscFVGetNumComponents((PetscFV)obj, &Nc));
1549566063dSJacob Faibussowitsch       PetscCall(PetscFVGetQuadrature((PetscFV)obj, &q));
1559566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " FVM"));
1569371c9d4SSatish Balay     } else SETERRQ(PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
15763a3b9bcSJacob Faibussowitsch     if (Nc > 1) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " components", Nc));
15863a3b9bcSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT " component ", Nc));
1599566063dSJacob Faibussowitsch     if (ds->implicit[f]) PetscCall(PetscViewerASCIIPrintf(viewer, " (implicit)"));
1609566063dSJacob Faibussowitsch     else PetscCall(PetscViewerASCIIPrintf(viewer, " (explicit)"));
1613e60c2a6SMatthew G. Knepley     if (q) {
1629566063dSJacob Faibussowitsch       PetscCall(PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL));
16363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, " (Nq %" PetscInt_FMT " Nqc %" PetscInt_FMT ")", Nq, Nqc));
1643e60c2a6SMatthew G. Knepley     }
16563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "-jet", ds->jetDegree[f]));
1669566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1679566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1689566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
1699566063dSJacob Faibussowitsch     if (id == PETSCFE_CLASSID) PetscCall(PetscFEView((PetscFE)obj, viewer));
1709566063dSJacob Faibussowitsch     else if (id == PETSCFV_CLASSID) PetscCall(PetscFVView((PetscFV)obj, viewer));
1719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
17240967b3bSMatthew G. Knepley 
1735fedec97SMatthew G. Knepley     for (b = ds->boundary; b; b = b->next) {
17406ad1575SMatthew G. Knepley       char    *name;
17540967b3bSMatthew G. Knepley       PetscInt c, i;
17640967b3bSMatthew G. Knepley 
17740967b3bSMatthew G. Knepley       if (b->field != f) continue;
1789566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]));
18045480ffeSMatthew G. Knepley       if (!b->Nc) {
1819566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  all components\n"));
18240967b3bSMatthew G. Knepley       } else {
1839566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  components: "));
1849566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
18545480ffeSMatthew G. Knepley         for (c = 0; c < b->Nc; ++c) {
1869566063dSJacob Faibussowitsch           if (c > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
18763a3b9bcSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->comps[c]));
18840967b3bSMatthew G. Knepley         }
1899566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1909566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
19140967b3bSMatthew G. Knepley       }
1929566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  values: "));
1939566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
19445480ffeSMatthew G. Knepley       for (i = 0; i < b->Nv; ++i) {
1959566063dSJacob Faibussowitsch         if (i > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
19663a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT, b->values[i]));
19740967b3bSMatthew G. Knepley       }
1989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
20015943bb8SPierre Jolivet #if defined(__clang__)
2011c7e414eSJacob Faibussowitsch       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic");
20215943bb8SPierre Jolivet #elif defined(__GNUC__) || defined(__GNUG__)
2031c7e414eSJacob Faibussowitsch       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       }
2171c7e414eSJacob Faibussowitsch       PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END();
2189566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormView(b->wf, viewer));
2199566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
22040967b3bSMatthew G. Knepley     }
2217d8a60eaSMatthew G. Knepley   }
2229566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(ds, &numConstants, &constants));
22397b6e6e8SMatthew G. Knepley   if (numConstants) {
22463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT " constants\n", numConstants));
2259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
2269566063dSJacob Faibussowitsch     for (f = 0; f < numConstants; ++f) PetscCall(PetscViewerASCIIPrintf(viewer, "%g\n", (double)PetscRealPart(constants[f])));
2279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
22897b6e6e8SMatthew G. Knepley   }
2299566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormView(ds->wf, viewer));
2309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2327d8a60eaSMatthew G. Knepley }
2337d8a60eaSMatthew G. Knepley 
2342764a2aaSMatthew G. Knepley /*@C
235dce8aebaSBarry Smith    PetscDSViewFromOptions - View a `PetscDS` based on values in the options database
236fe2efc57SMark 
23720f4b53cSBarry Smith    Collective
238fe2efc57SMark 
239fe2efc57SMark    Input Parameters:
240dce8aebaSBarry Smith +  A - the `PetscDS` object
24120f4b53cSBarry Smith .  obj - Optional object that provides the options prefix used in the search
242736c3998SJose E. Roman -  name - command line option
243fe2efc57SMark 
244fe2efc57SMark    Level: intermediate
245dce8aebaSBarry Smith 
246dce8aebaSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscDSView()`, `PetscObjectViewFromOptions()`, `PetscDSCreate()`
247fe2efc57SMark @*/
248d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSViewFromOptions(PetscDS A, PetscObject obj, const char name[])
249d71ae5a4SJacob Faibussowitsch {
250fe2efc57SMark   PetscFunctionBegin;
251fe2efc57SMark   PetscValidHeaderSpecific(A, PETSCDS_CLASSID, 1);
2529566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
2533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
254fe2efc57SMark }
255fe2efc57SMark 
256fe2efc57SMark /*@C
257dce8aebaSBarry Smith   PetscDSView - Views a `PetscDS`
2582764a2aaSMatthew G. Knepley 
25920f4b53cSBarry Smith   Collective
2602764a2aaSMatthew G. Knepley 
261d8d19677SJose E. Roman   Input Parameters:
262dce8aebaSBarry Smith + prob - the `PetscDS` object to view
2632764a2aaSMatthew G. Knepley - v  - the viewer
2642764a2aaSMatthew G. Knepley 
2652764a2aaSMatthew G. Knepley   Level: developer
2662764a2aaSMatthew G. Knepley 
26720f4b53cSBarry Smith .seealso: `PetscDSType`, `PetscDS`, `PetscViewer`, `PetscDSDestroy()`, `PetscDSViewFromOptions()`
2682764a2aaSMatthew G. Knepley @*/
269d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
270d71ae5a4SJacob Faibussowitsch {
2717d8a60eaSMatthew G. Knepley   PetscBool iascii;
2722764a2aaSMatthew G. Knepley 
2732764a2aaSMatthew G. Knepley   PetscFunctionBegin;
2742764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2759566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)prob), &v));
276ad540459SPierre Jolivet   else PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);
2779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &iascii));
2789566063dSJacob Faibussowitsch   if (iascii) PetscCall(PetscDSView_Ascii(prob, v));
279dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, view, v);
2803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2812764a2aaSMatthew G. Knepley }
2822764a2aaSMatthew G. Knepley 
2832764a2aaSMatthew G. Knepley /*@
284dce8aebaSBarry Smith   PetscDSSetFromOptions - sets parameters in a `PetscDS` from the options database
2852764a2aaSMatthew G. Knepley 
28620f4b53cSBarry Smith   Collective
2872764a2aaSMatthew G. Knepley 
2882764a2aaSMatthew G. Knepley   Input Parameter:
289dce8aebaSBarry Smith . prob - the `PetscDS` object to set options for
2902764a2aaSMatthew G. Knepley 
291dce8aebaSBarry Smith   Options Database Keys:
292dce8aebaSBarry Smith + -petscds_type <type>     - Set the `PetscDS` type
293dce8aebaSBarry Smith . -petscds_view <view opt> - View the `PetscDS`
294147403d9SBarry Smith . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
295147403d9SBarry Smith . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
296147403d9SBarry Smith - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition
2972764a2aaSMatthew G. Knepley 
298dce8aebaSBarry Smith   Level: intermediate
2992764a2aaSMatthew G. Knepley 
300dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`
3012764a2aaSMatthew G. Knepley @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
303d71ae5a4SJacob Faibussowitsch {
304f1fd5e65SToby Isaac   DSBoundary  b;
3052764a2aaSMatthew G. Knepley   const char *defaultType;
3062764a2aaSMatthew G. Knepley   char        name[256];
3072764a2aaSMatthew G. Knepley   PetscBool   flg;
3082764a2aaSMatthew G. Knepley 
3092764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3102764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3112764a2aaSMatthew G. Knepley   if (!((PetscObject)prob)->type_name) {
3122764a2aaSMatthew G. Knepley     defaultType = PETSCDSBASIC;
3132764a2aaSMatthew G. Knepley   } else {
3142764a2aaSMatthew G. Knepley     defaultType = ((PetscObject)prob)->type_name;
3152764a2aaSMatthew G. Knepley   }
3169566063dSJacob Faibussowitsch   PetscCall(PetscDSRegisterAll());
3172764a2aaSMatthew G. Knepley 
318d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)prob);
319f1fd5e65SToby Isaac   for (b = prob->boundary; b; b = b->next) {
320f1fd5e65SToby Isaac     char      optname[1024];
321f1fd5e65SToby Isaac     PetscInt  ids[1024], len = 1024;
322f1fd5e65SToby Isaac     PetscBool flg;
323f1fd5e65SToby Isaac 
3249566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name));
3259566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg));
327f1fd5e65SToby Isaac     if (flg) {
32845480ffeSMatthew G. Knepley       b->Nv = len;
3299566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->values));
3309566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->values));
3319566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->values, ids, len));
3329566063dSJacob Faibussowitsch       PetscCall(PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values));
333f1fd5e65SToby Isaac     }
334e7b0402cSSander Arens     len = 1024;
3359566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name));
3369566063dSJacob Faibussowitsch     PetscCall(PetscMemzero(ids, sizeof(ids)));
3379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg));
338f1fd5e65SToby Isaac     if (flg) {
33945480ffeSMatthew G. Knepley       b->Nc = len;
3409566063dSJacob Faibussowitsch       PetscCall(PetscFree(b->comps));
3419566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(len, &b->comps));
3429566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(b->comps, ids, len));
343f1fd5e65SToby Isaac     }
344f1fd5e65SToby Isaac   }
3459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg));
3462764a2aaSMatthew G. Knepley   if (flg) {
3479566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, name));
3482764a2aaSMatthew G. Knepley   } else if (!((PetscObject)prob)->type_name) {
3499566063dSJacob Faibussowitsch     PetscCall(PetscDSSetType(prob, defaultType));
3502764a2aaSMatthew G. Knepley   }
3519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg));
35212fc5b22SMatthew G. Knepley   PetscCall(PetscOptionsBool("-petscds_force_quad", "Discrete System", "PetscDSSetForceQuad", prob->forceQuad, &prob->forceQuad, &flg));
353dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setfromoptions);
3542764a2aaSMatthew G. Knepley   /* process any options handlers added with PetscObjectAddOptionsHandler() */
355dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)prob, PetscOptionsObject));
356d0609cedSBarry Smith   PetscOptionsEnd();
3579566063dSJacob Faibussowitsch   if (prob->Nf) PetscCall(PetscDSViewFromOptions(prob, NULL, "-petscds_view"));
3583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3592764a2aaSMatthew G. Knepley }
3602764a2aaSMatthew G. Knepley 
3612764a2aaSMatthew G. Knepley /*@C
362dce8aebaSBarry Smith   PetscDSSetUp - Construct data structures for the `PetscDS`
3632764a2aaSMatthew G. Knepley 
36420f4b53cSBarry Smith   Collective
3652764a2aaSMatthew G. Knepley 
3662764a2aaSMatthew G. Knepley   Input Parameter:
367dce8aebaSBarry Smith . prob - the `PetscDS` object to setup
3682764a2aaSMatthew G. Knepley 
3692764a2aaSMatthew G. Knepley   Level: developer
3702764a2aaSMatthew G. Knepley 
371dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSView()`, `PetscDSDestroy()`
3722764a2aaSMatthew G. Knepley @*/
373d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetUp(PetscDS prob)
374d71ae5a4SJacob Faibussowitsch {
3752764a2aaSMatthew G. Knepley   const PetscInt Nf          = prob->Nf;
376f9244615SMatthew G. Knepley   PetscBool      hasH        = PETSC_FALSE;
37707218a29SMatthew G. Knepley   PetscInt       maxOrder[4] = {-1, -1, -1, -1};
3784bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
3792764a2aaSMatthew G. Knepley 
3802764a2aaSMatthew G. Knepley   PetscFunctionBegin;
3812764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3823ba16761SJacob Faibussowitsch   if (prob->setup) PetscFunctionReturn(PETSC_SUCCESS);
3832764a2aaSMatthew G. Knepley   /* Calculate sizes */
3849566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
3859566063dSJacob Faibussowitsch   PetscCall(PetscDSGetCoordinateDimension(prob, &dimEmbed));
386f744cafaSSander Arens   prob->totDim = prob->totComp = 0;
3879566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->Nc, Nf, &prob->Nb));
3889566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(Nf + 1, &prob->off, Nf + 1, &prob->offDer));
3899566063dSJacob Faibussowitsch   PetscCall(PetscCalloc6(Nf + 1, &prob->offCohesive[0], Nf + 1, &prob->offCohesive[1], Nf + 1, &prob->offCohesive[2], Nf + 1, &prob->offDerCohesive[0], Nf + 1, &prob->offDerCohesive[1], Nf + 1, &prob->offDerCohesive[2]));
3909566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(Nf, &prob->T, Nf, &prob->Tf));
39112fc5b22SMatthew G. Knepley   if (prob->forceQuad) {
39207218a29SMatthew G. Knepley     // Note: This assumes we have one kind of cell at each dimension.
39307218a29SMatthew G. Knepley     //       We can fix this by having quadrature hold the celltype
39407218a29SMatthew G. Knepley     PetscQuadrature maxQuad[4] = {NULL, NULL, NULL, NULL};
39512fc5b22SMatthew G. Knepley 
39612fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
39712fc5b22SMatthew G. Knepley       PetscObject     obj;
39812fc5b22SMatthew G. Knepley       PetscClassId    id;
39912fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
40007218a29SMatthew G. Knepley       PetscInt        dim = -1, order = -1, forder = -1;
40112fc5b22SMatthew G. Knepley 
40212fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40312fc5b22SMatthew G. Knepley       if (!obj) continue;
40412fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
40512fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
40612fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
40712fc5b22SMatthew G. Knepley 
40812fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
40912fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
41012fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
41112fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
41212fc5b22SMatthew G. Knepley 
41312fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
41412fc5b22SMatthew G. Knepley       }
41507218a29SMatthew G. Knepley       if (q) {
41607218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
41707218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(q, &order));
41807218a29SMatthew G. Knepley         if (order > maxOrder[dim]) {
41907218a29SMatthew G. Knepley           maxOrder[dim] = order;
42007218a29SMatthew G. Knepley           maxQuad[dim]  = q;
42112fc5b22SMatthew G. Knepley         }
42207218a29SMatthew G. Knepley       }
42307218a29SMatthew G. Knepley       if (fq) {
42407218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
42507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetOrder(fq, &forder));
42607218a29SMatthew G. Knepley         if (forder > maxOrder[dim]) {
42707218a29SMatthew G. Knepley           maxOrder[dim] = forder;
42807218a29SMatthew G. Knepley           maxQuad[dim]  = fq;
42907218a29SMatthew G. Knepley         }
43012fc5b22SMatthew G. Knepley       }
43112fc5b22SMatthew G. Knepley     }
43212fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
43312fc5b22SMatthew G. Knepley       PetscObject     obj;
43412fc5b22SMatthew G. Knepley       PetscClassId    id;
43507218a29SMatthew G. Knepley       PetscQuadrature q;
43607218a29SMatthew G. Knepley       PetscInt        dim;
43712fc5b22SMatthew G. Knepley 
43812fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
43912fc5b22SMatthew G. Knepley       if (!obj) continue;
44012fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
44112fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
44212fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
44312fc5b22SMatthew G. Knepley 
44407218a29SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
44507218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
44607218a29SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, maxQuad[dim]));
44707218a29SMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, maxQuad[dim - 1]));
44812fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
44912fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
45012fc5b22SMatthew G. Knepley 
45107218a29SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
45207218a29SMatthew G. Knepley         PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
45307218a29SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, maxQuad[dim]));
45412fc5b22SMatthew G. Knepley       }
45512fc5b22SMatthew G. Knepley     }
45612fc5b22SMatthew G. Knepley   }
4572764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4589de99aefSMatthew G. Knepley     PetscObject     obj;
4599de99aefSMatthew G. Knepley     PetscClassId    id;
460665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4619de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4622764a2aaSMatthew G. Knepley 
4639566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
464f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
465665f567fSMatthew G. Knepley     if (!obj) {
466665f567fSMatthew G. Knepley       /* Empty mesh */
467665f567fSMatthew G. Knepley       Nb = Nc    = 0;
468665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
469665f567fSMatthew G. Knepley     } else {
4709566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4719de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4729de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4739de99aefSMatthew G. Knepley 
4749566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
47549ae0b56SMatthew G. Knepley         {
47649ae0b56SMatthew G. Knepley           PetscQuadrature fq;
47707218a29SMatthew G. Knepley           PetscInt        dim, order;
47849ae0b56SMatthew G. Knepley 
47907218a29SMatthew G. Knepley           PetscCall(PetscQuadratureGetData(q, &dim, NULL, NULL, NULL, NULL));
48049ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
48107218a29SMatthew G. Knepley           if (maxOrder[dim] < 0) maxOrder[dim] = order;
48207218a29SMatthew G. Knepley           PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " cell quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS cell quadrature order", f, order, maxOrder[dim]);
48349ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
48449ae0b56SMatthew G. Knepley           if (fq) {
48507218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetData(fq, &dim, NULL, NULL, NULL, NULL));
48607218a29SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &order));
48707218a29SMatthew G. Knepley             if (maxOrder[dim] < 0) maxOrder[dim] = order;
48807218a29SMatthew G. Knepley             PetscCheck(order == maxOrder[dim], PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " face quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS face quadrature order", f, order, maxOrder[dim]);
48949ae0b56SMatthew G. Knepley           }
49049ae0b56SMatthew G. Knepley         }
4919566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4929566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4939566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4949566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4959de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4969de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4979de99aefSMatthew G. Knepley 
4989566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4999566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
5009c3cf19fSMatthew G. Knepley         Nb = Nc;
5019566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
5024d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
50363a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
504665f567fSMatthew G. Knepley     }
50547e57110SSander Arens     prob->Nc[f]                    = Nc;
50647e57110SSander Arens     prob->Nb[f]                    = Nb;
507194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
508194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
5099ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
5109ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
5119ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
5129ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
5139ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
5149ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5159566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5162764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5174bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5182764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5199c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5202764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5215fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5225fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5232764a2aaSMatthew G. Knepley   }
5249ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5259ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5262764a2aaSMatthew G. Knepley   /* Allocate works space */
5275fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(NsMax * prob->totComp, &prob->u, NsMax * prob->totComp, &prob->u_t, NsMax * prob->totComp * dimEmbed + (hasH ? NsMax * prob->totComp * dimEmbed * dimEmbed : 0), &prob->u_x));
5299566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5309371c9d4SSatish Balay   PetscCall(PetscMalloc6(NsMax * NqMax * NcMax, &prob->f0, NsMax * NqMax * NcMax * dimEmbed, &prob->f1, NsMax * NsMax * NqMax * NcMax * NcMax, &prob->g0, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed, &prob->g1, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed,
5319371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
532dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5332764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5352764a2aaSMatthew G. Knepley }
5362764a2aaSMatthew G. Knepley 
537d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
538d71ae5a4SJacob Faibussowitsch {
5392764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5409566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5419566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5429566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5439566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5449566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5459566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5469566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5482764a2aaSMatthew G. Knepley }
5492764a2aaSMatthew G. Knepley 
550d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
551d71ae5a4SJacob Faibussowitsch {
552f744cafaSSander Arens   PetscObject          *tmpd;
55334aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
554f9244615SMatthew G. Knepley   PetscInt             *tmpk;
5555fedec97SMatthew G. Knepley   PetscBool            *tmpc;
5566528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
557f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
558f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
5590c2f2876SMatthew G. Knepley   void                **tmpctx;
56034aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
5612764a2aaSMatthew G. Knepley 
5622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5633ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5642764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5659566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5669566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5679371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5689371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5699371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5709371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5719371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5729371c9d4SSatish Balay   }
5739371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5749371c9d4SSatish Balay     tmpd[f] = NULL;
5759371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5769371c9d4SSatish Balay     tmpk[f] = 1;
5779371c9d4SSatish Balay   }
5789566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5802764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5812764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
582249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5835fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
584f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5859566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
58632d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5870c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
58832d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5890c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5909566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
59132d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5920c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5939566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
594c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
59595cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
596f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
597f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
598c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
59995cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
600f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
601f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
6029566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
603c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
60495cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
605f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
606f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
6073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6082764a2aaSMatthew G. Knepley }
6092764a2aaSMatthew G. Knepley 
6102764a2aaSMatthew G. Knepley /*@
61120f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
6122764a2aaSMatthew G. Knepley 
61320f4b53cSBarry Smith   Collective
6142764a2aaSMatthew G. Knepley 
6152764a2aaSMatthew G. Knepley   Input Parameter:
61620f4b53cSBarry Smith . prob - the `PetscDS` object to destroy
6172764a2aaSMatthew G. Knepley 
6182764a2aaSMatthew G. Knepley   Level: developer
6192764a2aaSMatthew G. Knepley 
620dce8aebaSBarry Smith .seealso: `PetscDSView()`
6212764a2aaSMatthew G. Knepley @*/
622d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
623d71ae5a4SJacob Faibussowitsch {
6242764a2aaSMatthew G. Knepley   PetscInt f;
6252764a2aaSMatthew G. Knepley 
6262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6273ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
6286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
6292764a2aaSMatthew G. Knepley 
6309371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
6319371c9d4SSatish Balay     *ds = NULL;
6323ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6339371c9d4SSatish Balay   }
6346528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
6356528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
636df3a45bdSMatthew G. Knepley     PetscInt dim, d;
637df3a45bdSMatthew G. Knepley 
6389566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6399566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
640df3a45bdSMatthew G. Knepley   }
6419566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6429566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
64348a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6449566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6469566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6479566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
648dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
6499566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6509566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6514366bac7SMatthew G. Knepley   for (PetscInt c = 0; c < DM_NUM_POLYTOPES; ++c) {
6524366bac7SMatthew G. Knepley     const PetscInt Na = DMPolytopeTypeGetNumArrangments((DMPolytopeType)c);
6534366bac7SMatthew G. Knepley     if ((*ds)->quadPerm[c])
6544366bac7SMatthew G. Knepley       for (PetscInt o = 0; o < Na; ++o) PetscCall(ISDestroy(&(*ds)->quadPerm[c][o]));
6554366bac7SMatthew G. Knepley     PetscCall(PetscFree((*ds)->quadPerm[c]));
6564366bac7SMatthew G. Knepley     (*ds)->quadPerm[c] = NULL;
6574366bac7SMatthew G. Knepley   }
6589566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6602764a2aaSMatthew G. Knepley }
6612764a2aaSMatthew G. Knepley 
6622764a2aaSMatthew G. Knepley /*@
663dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6642764a2aaSMatthew G. Knepley 
665d083f849SBarry Smith   Collective
6662764a2aaSMatthew G. Knepley 
6672764a2aaSMatthew G. Knepley   Input Parameter:
668dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6692764a2aaSMatthew G. Knepley 
6702764a2aaSMatthew G. Knepley   Output Parameter:
671dce8aebaSBarry Smith . ds   - The `PetscDS` object
6722764a2aaSMatthew G. Knepley 
6732764a2aaSMatthew G. Knepley   Level: beginner
6742764a2aaSMatthew G. Knepley 
675dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6762764a2aaSMatthew G. Knepley @*/
677d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
678d71ae5a4SJacob Faibussowitsch {
6792764a2aaSMatthew G. Knepley   PetscDS p;
6802764a2aaSMatthew G. Knepley 
6812764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6826528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
6836528b96dSMatthew G. Knepley   *ds = NULL;
6849566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6852764a2aaSMatthew G. Knepley 
6869566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6872764a2aaSMatthew G. Knepley 
6882764a2aaSMatthew G. Knepley   p->Nf           = 0;
6892764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
69097b6e6e8SMatthew G. Knepley   p->numConstants = 0;
69197b6e6e8SMatthew G. Knepley   p->constants    = NULL;
692a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
69355c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
69412fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6959566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6964366bac7SMatthew G. Knepley   PetscCall(PetscArrayzero(p->quadPerm, DM_NUM_POLYTOPES));
6972764a2aaSMatthew G. Knepley 
6986528b96dSMatthew G. Knepley   *ds = p;
6993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7002764a2aaSMatthew G. Knepley }
7012764a2aaSMatthew G. Knepley 
702bc4ae4beSMatthew G. Knepley /*@
703dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
704bc4ae4beSMatthew G. Knepley 
70520f4b53cSBarry Smith   Not Collective
706bc4ae4beSMatthew G. Knepley 
707bc4ae4beSMatthew G. Knepley   Input Parameter:
70820f4b53cSBarry Smith . prob - The `PetscDS` object
709bc4ae4beSMatthew G. Knepley 
710bc4ae4beSMatthew G. Knepley   Output Parameter:
711bc4ae4beSMatthew G. Knepley . Nf - The number of fields
712bc4ae4beSMatthew G. Knepley 
713bc4ae4beSMatthew G. Knepley   Level: beginner
714bc4ae4beSMatthew G. Knepley 
715dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
716bc4ae4beSMatthew G. Knepley @*/
717d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
718d71ae5a4SJacob Faibussowitsch {
7192764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7202764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
721dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
7222764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7242764a2aaSMatthew G. Knepley }
7252764a2aaSMatthew G. Knepley 
726bc4ae4beSMatthew G. Knepley /*@
727dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
728bc4ae4beSMatthew G. Knepley 
72920f4b53cSBarry Smith   Not Collective
730bc4ae4beSMatthew G. Knepley 
731bc4ae4beSMatthew G. Knepley   Input Parameter:
732dce8aebaSBarry Smith . prob - The `PetscDS` object
733bc4ae4beSMatthew G. Knepley 
734bc4ae4beSMatthew G. Knepley   Output Parameter:
735bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
736bc4ae4beSMatthew G. Knepley 
737bc4ae4beSMatthew G. Knepley   Level: beginner
738bc4ae4beSMatthew G. Knepley 
739dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
740bc4ae4beSMatthew G. Knepley @*/
741d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
742d71ae5a4SJacob Faibussowitsch {
7432764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7442764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
745dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
7462764a2aaSMatthew G. Knepley   *dim = 0;
7479de99aefSMatthew G. Knepley   if (prob->Nf) {
7489de99aefSMatthew G. Knepley     PetscObject  obj;
7499de99aefSMatthew G. Knepley     PetscClassId id;
7509de99aefSMatthew G. Knepley 
7519566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
752665f567fSMatthew G. Knepley     if (obj) {
7539566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7549566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7559566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
75698921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7579de99aefSMatthew G. Knepley     }
758665f567fSMatthew G. Knepley   }
7593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7602764a2aaSMatthew G. Knepley }
7612764a2aaSMatthew G. Knepley 
762bc4ae4beSMatthew G. Knepley /*@
763dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
764a859676bSMatthew G. Knepley 
76520f4b53cSBarry Smith   Not Collective
766a859676bSMatthew G. Knepley 
767a859676bSMatthew G. Knepley   Input Parameter:
768dce8aebaSBarry Smith . prob - The `PetscDS` object
769a859676bSMatthew G. Knepley 
770a859676bSMatthew G. Knepley   Output Parameter:
771a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
772a859676bSMatthew G. Knepley 
773a859676bSMatthew G. Knepley   Level: beginner
774a859676bSMatthew G. Knepley 
775dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
776a859676bSMatthew G. Knepley @*/
777d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
778d71ae5a4SJacob Faibussowitsch {
779a859676bSMatthew G. Knepley   PetscFunctionBegin;
780a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
781dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
78208401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
783a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785a859676bSMatthew G. Knepley }
786a859676bSMatthew G. Knepley 
787a859676bSMatthew G. Knepley /*@
788dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
789a859676bSMatthew G. Knepley 
79020f4b53cSBarry Smith   Logically Collective
791a859676bSMatthew G. Knepley 
792a859676bSMatthew G. Knepley   Input Parameters:
793dce8aebaSBarry Smith + prob - The `PetscDS` object
794a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
795a859676bSMatthew G. Knepley 
796a859676bSMatthew G. Knepley   Level: beginner
797a859676bSMatthew G. Knepley 
798dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
799a859676bSMatthew G. Knepley @*/
800d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
801d71ae5a4SJacob Faibussowitsch {
802a859676bSMatthew G. Knepley   PetscFunctionBegin;
803a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
80463a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
805a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
8063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
807a859676bSMatthew G. Knepley }
808a859676bSMatthew G. Knepley 
809a859676bSMatthew G. Knepley /*@
81012fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
81112fc5b22SMatthew G. Knepley 
81212fc5b22SMatthew G. Knepley   Not collective
81312fc5b22SMatthew G. Knepley 
81412fc5b22SMatthew G. Knepley   Input Parameter:
81512fc5b22SMatthew G. Knepley . prob - The `PetscDS` object
81612fc5b22SMatthew G. Knepley 
81712fc5b22SMatthew G. Knepley   Output Parameter:
81812fc5b22SMatthew G. Knepley . forceQuad - The flag
81912fc5b22SMatthew G. Knepley 
82012fc5b22SMatthew G. Knepley   Level: intermediate
82112fc5b22SMatthew G. Knepley 
82212fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
82312fc5b22SMatthew G. Knepley @*/
82412fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
82512fc5b22SMatthew G. Knepley {
82612fc5b22SMatthew G. Knepley   PetscFunctionBegin;
82712fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
828f87a0b54SStefano Zampini   PetscValidBoolPointer(forceQuad, 2);
82912fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
83012fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
83112fc5b22SMatthew G. Knepley }
83212fc5b22SMatthew G. Knepley 
83312fc5b22SMatthew G. Knepley /*@
83412fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
83512fc5b22SMatthew G. Knepley 
83612fc5b22SMatthew G. Knepley   Logically collective on ds
83712fc5b22SMatthew G. Knepley 
83812fc5b22SMatthew G. Knepley   Input Parameters:
83912fc5b22SMatthew G. Knepley + ds - The `PetscDS` object
84012fc5b22SMatthew G. Knepley - forceQuad - The flag
84112fc5b22SMatthew G. Knepley 
84212fc5b22SMatthew G. Knepley   Level: intermediate
84312fc5b22SMatthew G. Knepley 
84412fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
84512fc5b22SMatthew G. Knepley @*/
84612fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
84712fc5b22SMatthew G. Knepley {
84812fc5b22SMatthew G. Knepley   PetscFunctionBegin;
84912fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
85012fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
85112fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
85212fc5b22SMatthew G. Knepley }
85312fc5b22SMatthew G. Knepley 
85412fc5b22SMatthew G. Knepley /*@
855dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8568edf6225SMatthew G. Knepley 
85720f4b53cSBarry Smith   Not Collective
8588edf6225SMatthew G. Knepley 
8598edf6225SMatthew G. Knepley   Input Parameter:
860dce8aebaSBarry Smith . ds - The `PetscDS` object
8618edf6225SMatthew G. Knepley 
8628edf6225SMatthew G. Knepley   Output Parameter:
8635fedec97SMatthew G. Knepley . isCohesive - The flag
8648edf6225SMatthew G. Knepley 
8658edf6225SMatthew G. Knepley   Level: developer
8668edf6225SMatthew G. Knepley 
867dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8688edf6225SMatthew G. Knepley @*/
869d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
870d71ae5a4SJacob Faibussowitsch {
8718edf6225SMatthew G. Knepley   PetscFunctionBegin;
8725fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
873dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
8745fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8768edf6225SMatthew G. Knepley }
8778edf6225SMatthew G. Knepley 
8788edf6225SMatthew G. Knepley /*@
879*be87f6c0SPierre Jolivet   PetscDSGetNumCohesive - Returns the number of cohesive fields, meaning those defined on the interior of a cohesive cell
8805fedec97SMatthew G. Knepley 
88120f4b53cSBarry Smith   Not Collective
8825fedec97SMatthew G. Knepley 
8835fedec97SMatthew G. Knepley   Input Parameter:
884dce8aebaSBarry Smith . ds - The `PetscDS` object
8855fedec97SMatthew G. Knepley 
8865fedec97SMatthew G. Knepley   Output Parameter:
8875fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8885fedec97SMatthew G. Knepley 
8895fedec97SMatthew G. Knepley   Level: developer
8905fedec97SMatthew G. Knepley 
891dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8925fedec97SMatthew G. Knepley @*/
893d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
894d71ae5a4SJacob Faibussowitsch {
8955fedec97SMatthew G. Knepley   PetscInt f;
8965fedec97SMatthew G. Knepley 
8975fedec97SMatthew G. Knepley   PetscFunctionBegin;
8985fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
899dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
9005fedec97SMatthew G. Knepley   *numCohesive = 0;
9015fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
9023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9035fedec97SMatthew G. Knepley }
9045fedec97SMatthew G. Knepley 
9055fedec97SMatthew G. Knepley /*@
9065fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9075fedec97SMatthew G. Knepley 
90820f4b53cSBarry Smith   Not Collective
9095fedec97SMatthew G. Knepley 
910f1a722f8SMatthew G. Knepley   Input Parameters:
911dce8aebaSBarry Smith + ds - The `PetscDS` object
9125fedec97SMatthew G. Knepley - f  - The field index
9135fedec97SMatthew G. Knepley 
9145fedec97SMatthew G. Knepley   Output Parameter:
9155fedec97SMatthew G. Knepley . isCohesive - The flag
9165fedec97SMatthew G. Knepley 
9175fedec97SMatthew G. Knepley   Level: developer
9185fedec97SMatthew G. Knepley 
919dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9205fedec97SMatthew G. Knepley @*/
921d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
922d71ae5a4SJacob Faibussowitsch {
9235fedec97SMatthew G. Knepley   PetscFunctionBegin;
9245fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
925dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
92663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9275fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9295fedec97SMatthew G. Knepley }
9305fedec97SMatthew G. Knepley 
9315fedec97SMatthew G. Knepley /*@
9325fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9338edf6225SMatthew G. Knepley 
93420f4b53cSBarry Smith   Not Collective
9358edf6225SMatthew G. Knepley 
9368edf6225SMatthew G. Knepley   Input Parameters:
937dce8aebaSBarry Smith + ds - The `PetscDS` object
9385fedec97SMatthew G. Knepley . f  - The field index
9395fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9408edf6225SMatthew G. Knepley 
9418edf6225SMatthew G. Knepley   Level: developer
9428edf6225SMatthew G. Knepley 
943dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9448edf6225SMatthew G. Knepley @*/
945d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
946d71ae5a4SJacob Faibussowitsch {
9475fedec97SMatthew G. Knepley   PetscInt i;
9485fedec97SMatthew G. Knepley 
9498edf6225SMatthew G. Knepley   PetscFunctionBegin;
9505fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
95163a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
9525fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9535fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9545fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9568edf6225SMatthew G. Knepley }
9578edf6225SMatthew G. Knepley 
9588edf6225SMatthew G. Knepley /*@
959bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
960bc4ae4beSMatthew G. Knepley 
96120f4b53cSBarry Smith   Not Collective
962bc4ae4beSMatthew G. Knepley 
963bc4ae4beSMatthew G. Knepley   Input Parameter:
964dce8aebaSBarry Smith . prob - The `PetscDS` object
965bc4ae4beSMatthew G. Knepley 
966bc4ae4beSMatthew G. Knepley   Output Parameter:
967bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
968bc4ae4beSMatthew G. Knepley 
969bc4ae4beSMatthew G. Knepley   Level: beginner
970bc4ae4beSMatthew G. Knepley 
971dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
972bc4ae4beSMatthew G. Knepley @*/
973d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
974d71ae5a4SJacob Faibussowitsch {
9752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9762764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9779566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
978dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
9792764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9812764a2aaSMatthew G. Knepley }
9822764a2aaSMatthew G. Knepley 
983bc4ae4beSMatthew G. Knepley /*@
984bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
985bc4ae4beSMatthew G. Knepley 
98620f4b53cSBarry Smith   Not Collective
987bc4ae4beSMatthew G. Knepley 
988bc4ae4beSMatthew G. Knepley   Input Parameter:
989dce8aebaSBarry Smith . prob - The `PetscDS` object
990bc4ae4beSMatthew G. Knepley 
991bc4ae4beSMatthew G. Knepley   Output Parameter:
992bc4ae4beSMatthew G. Knepley . dim - The total number of components
993bc4ae4beSMatthew G. Knepley 
994bc4ae4beSMatthew G. Knepley   Level: beginner
995bc4ae4beSMatthew G. Knepley 
996dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
997bc4ae4beSMatthew G. Knepley @*/
998d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
999d71ae5a4SJacob Faibussowitsch {
10002764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10012764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10029566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
1003dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
10042764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
10053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10062764a2aaSMatthew G. Knepley }
10072764a2aaSMatthew G. Knepley 
1008bc4ae4beSMatthew G. Knepley /*@
1009bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
1010bc4ae4beSMatthew G. Knepley 
101120f4b53cSBarry Smith   Not Collective
1012bc4ae4beSMatthew G. Knepley 
1013bc4ae4beSMatthew G. Knepley   Input Parameters:
1014dce8aebaSBarry Smith + prob - The `PetscDS` object
1015bc4ae4beSMatthew G. Knepley - f - The field number
1016bc4ae4beSMatthew G. Knepley 
1017bc4ae4beSMatthew G. Knepley   Output Parameter:
1018bc4ae4beSMatthew G. Knepley . disc - The discretization object
1019bc4ae4beSMatthew G. Knepley 
1020bc4ae4beSMatthew G. Knepley   Level: beginner
1021bc4ae4beSMatthew G. Knepley 
1022dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1023bc4ae4beSMatthew G. Knepley @*/
1024d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1025d71ae5a4SJacob Faibussowitsch {
10266528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10272764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10282764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
102963a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
10302764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10322764a2aaSMatthew G. Knepley }
10332764a2aaSMatthew G. Knepley 
1034bc4ae4beSMatthew G. Knepley /*@
1035bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1036bc4ae4beSMatthew G. Knepley 
103720f4b53cSBarry Smith   Not Collective
1038bc4ae4beSMatthew G. Knepley 
1039bc4ae4beSMatthew G. Knepley   Input Parameters:
1040dce8aebaSBarry Smith + prob - The `PetscDS` object
1041bc4ae4beSMatthew G. Knepley . f - The field number
1042bc4ae4beSMatthew G. Knepley - disc - The discretization object
1043bc4ae4beSMatthew G. Knepley 
1044bc4ae4beSMatthew G. Knepley   Level: beginner
1045bc4ae4beSMatthew G. Knepley 
1046dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1047bc4ae4beSMatthew G. Knepley @*/
1048d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1049d71ae5a4SJacob Faibussowitsch {
10502764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10512764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1052665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
105363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10549566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10559566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10562764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10579566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1058665f567fSMatthew G. Knepley   if (disc) {
1059249df284SMatthew G. Knepley     PetscClassId id;
1060249df284SMatthew G. Knepley 
10619566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10621cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10639566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10641cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10659566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1066a6cbbb48SMatthew G. Knepley     }
10679566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1068249df284SMatthew G. Knepley   }
10693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10702764a2aaSMatthew G. Knepley }
10712764a2aaSMatthew G. Knepley 
1072bc4ae4beSMatthew G. Knepley /*@
10736528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10746528b96dSMatthew G. Knepley 
107520f4b53cSBarry Smith   Not Collective
10766528b96dSMatthew G. Knepley 
10776528b96dSMatthew G. Knepley   Input Parameter:
1078dce8aebaSBarry Smith . ds - The `PetscDS` object
10796528b96dSMatthew G. Knepley 
10806528b96dSMatthew G. Knepley   Output Parameter:
10816528b96dSMatthew G. Knepley . wf - The weak form object
10826528b96dSMatthew G. Knepley 
10836528b96dSMatthew G. Knepley   Level: beginner
10846528b96dSMatthew G. Knepley 
1085dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10866528b96dSMatthew G. Knepley @*/
1087d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1088d71ae5a4SJacob Faibussowitsch {
10896528b96dSMatthew G. Knepley   PetscFunctionBegin;
10906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10916528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
10926528b96dSMatthew G. Knepley   *wf = ds->wf;
10933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10946528b96dSMatthew G. Knepley }
10956528b96dSMatthew G. Knepley 
10966528b96dSMatthew G. Knepley /*@
10976528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10986528b96dSMatthew G. Knepley 
109920f4b53cSBarry Smith   Not Collective
11006528b96dSMatthew G. Knepley 
11016528b96dSMatthew G. Knepley   Input Parameters:
1102dce8aebaSBarry Smith + ds - The `PetscDS` object
11036528b96dSMatthew G. Knepley - wf - The weak form object
11046528b96dSMatthew G. Knepley 
11056528b96dSMatthew G. Knepley   Level: beginner
11066528b96dSMatthew G. Knepley 
1107dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
11086528b96dSMatthew G. Knepley @*/
1109d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1110d71ae5a4SJacob Faibussowitsch {
11116528b96dSMatthew G. Knepley   PetscFunctionBegin;
11126528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
11136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
11149566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
11156528b96dSMatthew G. Knepley   ds->wf = wf;
11169566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
11179566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
11183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11196528b96dSMatthew G. Knepley }
11206528b96dSMatthew G. Knepley 
11216528b96dSMatthew G. Knepley /*@
1122bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1123bc4ae4beSMatthew G. Knepley 
112420f4b53cSBarry Smith   Not Collective
1125bc4ae4beSMatthew G. Knepley 
1126bc4ae4beSMatthew G. Knepley   Input Parameters:
1127dce8aebaSBarry Smith + prob - The `PetscDS` object
1128bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1129bc4ae4beSMatthew G. Knepley 
1130bc4ae4beSMatthew G. Knepley   Level: beginner
1131bc4ae4beSMatthew G. Knepley 
1132dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1133bc4ae4beSMatthew G. Knepley @*/
1134d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1135d71ae5a4SJacob Faibussowitsch {
11362764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11379566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11392764a2aaSMatthew G. Knepley }
11402764a2aaSMatthew G. Knepley 
1141249df284SMatthew G. Knepley /*@
1142dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1143083401c6SMatthew G. Knepley 
114420f4b53cSBarry Smith   Not Collective
1145083401c6SMatthew G. Knepley 
1146083401c6SMatthew G. Knepley   Input Parameter:
1147dce8aebaSBarry Smith . prob - The `PetscDS` object
1148083401c6SMatthew G. Knepley 
1149083401c6SMatthew G. Knepley   Output Parameter:
1150083401c6SMatthew G. Knepley . q - The quadrature object
1151083401c6SMatthew G. Knepley 
1152083401c6SMatthew G. Knepley   Level: intermediate
1153083401c6SMatthew G. Knepley 
1154dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1155083401c6SMatthew G. Knepley @*/
1156d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1157d71ae5a4SJacob Faibussowitsch {
1158083401c6SMatthew G. Knepley   PetscObject  obj;
1159083401c6SMatthew G. Knepley   PetscClassId id;
1160083401c6SMatthew G. Knepley 
1161083401c6SMatthew G. Knepley   PetscFunctionBegin;
1162083401c6SMatthew G. Knepley   *q = NULL;
11633ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11659566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11669566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11679566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
116898921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1170083401c6SMatthew G. Knepley }
1171083401c6SMatthew G. Knepley 
1172083401c6SMatthew G. Knepley /*@
1173dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1174249df284SMatthew G. Knepley 
117520f4b53cSBarry Smith   Not Collective
1176249df284SMatthew G. Knepley 
1177249df284SMatthew G. Knepley   Input Parameters:
1178dce8aebaSBarry Smith + prob - The `PetscDS` object
1179249df284SMatthew G. Knepley - f - The field number
1180249df284SMatthew G. Knepley 
1181249df284SMatthew G. Knepley   Output Parameter:
1182249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1183249df284SMatthew G. Knepley 
1184249df284SMatthew G. Knepley   Level: developer
1185249df284SMatthew G. Knepley 
1186dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1187249df284SMatthew G. Knepley @*/
1188d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1189d71ae5a4SJacob Faibussowitsch {
1190249df284SMatthew G. Knepley   PetscFunctionBegin;
1191249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1192dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
119363a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1194249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1196249df284SMatthew G. Knepley }
1197249df284SMatthew G. Knepley 
1198249df284SMatthew G. Knepley /*@
1199dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1200249df284SMatthew G. Knepley 
120120f4b53cSBarry Smith   Not Collective
1202249df284SMatthew G. Knepley 
1203249df284SMatthew G. Knepley   Input Parameters:
1204dce8aebaSBarry Smith + prob - The `PetscDS` object
1205249df284SMatthew G. Knepley . f - The field number
1206249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1207249df284SMatthew G. Knepley 
1208249df284SMatthew G. Knepley   Level: developer
1209249df284SMatthew G. Knepley 
1210dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1211249df284SMatthew G. Knepley @*/
1212d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1213d71ae5a4SJacob Faibussowitsch {
1214249df284SMatthew G. Knepley   PetscFunctionBegin;
1215249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
121663a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= prob->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, prob->Nf);
1217249df284SMatthew G. Knepley   prob->implicit[f] = implicit;
12183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1219249df284SMatthew G. Knepley }
1220249df284SMatthew G. Knepley 
1221f9244615SMatthew G. Knepley /*@
1222f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1223f9244615SMatthew G. Knepley 
122420f4b53cSBarry Smith   Not Collective
1225f9244615SMatthew G. Knepley 
1226f9244615SMatthew G. Knepley   Input Parameters:
1227dce8aebaSBarry Smith + ds - The `PetscDS` object
1228f9244615SMatthew G. Knepley - f  - The field number
1229f9244615SMatthew G. Knepley 
1230f9244615SMatthew G. Knepley   Output Parameter:
1231f9244615SMatthew G. Knepley . k  - The highest derivative we need to tabulate
1232f9244615SMatthew G. Knepley 
1233f9244615SMatthew G. Knepley   Level: developer
1234f9244615SMatthew G. Knepley 
1235dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1236f9244615SMatthew G. Knepley @*/
1237d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1238d71ae5a4SJacob Faibussowitsch {
1239f9244615SMatthew G. Knepley   PetscFunctionBegin;
1240f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1241dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
124263a3b9bcSJacob Faibussowitsch   PetscCheck(!(f < 0) && !(f >= ds->Nf), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, ds->Nf);
1243f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1245f9244615SMatthew G. Knepley }
1246f9244615SMatthew G. Knepley 
1247f9244615SMatthew G. Knepley /*@
1248f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1249f9244615SMatthew G. Knepley 
125020f4b53cSBarry Smith   Not Collective
1251f9244615SMatthew G. Knepley 
1252f9244615SMatthew G. Knepley   Input Parameters:
1253dce8aebaSBarry Smith + ds - The `PetscDS` object
1254f9244615SMatthew G. Knepley . f  - The field number
1255f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1256f9244615SMatthew G. Knepley 
1257f9244615SMatthew G. Knepley   Level: developer
1258f9244615SMatthew G. Knepley 
1259dce8aebaSBarry Smith .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 
1270d71ae5a4SJacob 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[]))
1271d71ae5a4SJacob Faibussowitsch {
12726528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
12736528b96dSMatthew G. Knepley   PetscInt        n;
12746528b96dSMatthew G. Knepley 
12752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12776528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
127863a3b9bcSJacob 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);
12799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
12806528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
12813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12822764a2aaSMatthew G. Knepley }
12832764a2aaSMatthew G. Knepley 
1284d71ae5a4SJacob 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[]))
1285d71ae5a4SJacob Faibussowitsch {
12862764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12876528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12886528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
128963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
12909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
12913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12922764a2aaSMatthew G. Knepley }
12932764a2aaSMatthew G. Knepley 
1294194d53e6SMatthew G. Knepley /*@C
1295194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1296194d53e6SMatthew G. Knepley 
129720f4b53cSBarry Smith   Not Collective
1298194d53e6SMatthew G. Knepley 
1299194d53e6SMatthew G. Knepley   Input Parameters:
1300dce8aebaSBarry Smith + ds - The `PetscDS`
1301194d53e6SMatthew G. Knepley - f  - The test field number
1302194d53e6SMatthew G. Knepley 
1303194d53e6SMatthew G. Knepley   Output Parameters:
1304194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1305194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1306194d53e6SMatthew G. Knepley 
130720f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1308dce8aebaSBarry Smith .vb
130920f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1310dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1311dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1312dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1313dce8aebaSBarry Smith .ve
1314194d53e6SMatthew G. Knepley + dim - the spatial dimension
1315194d53e6SMatthew G. Knepley . Nf - the number of fields
1316194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1317194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1318194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1319194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1320194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1321194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1322194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1323194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1324194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1325194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1326194d53e6SMatthew G. Knepley . t - current time
1327194d53e6SMatthew G. Knepley . x - coordinates of the current point
132897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
132997b6e6e8SMatthew G. Knepley . constants - constant parameters
1330194d53e6SMatthew G. Knepley - f0 - output values at the current point
1331194d53e6SMatthew G. Knepley 
1332194d53e6SMatthew G. Knepley   Level: intermediate
1333194d53e6SMatthew G. Knepley 
1334dce8aebaSBarry Smith   Note:
1335dce8aebaSBarry 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)
1336dce8aebaSBarry Smith 
1337dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1338194d53e6SMatthew G. Knepley @*/
1339d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1340d71ae5a4SJacob Faibussowitsch {
13416528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
13426528b96dSMatthew G. Knepley   PetscInt        n0, n1;
13436528b96dSMatthew G. Knepley 
13442764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13456528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
134663a3b9bcSJacob 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);
13479566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
13486528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
13496528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
13503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13512764a2aaSMatthew G. Knepley }
13522764a2aaSMatthew G. Knepley 
1353194d53e6SMatthew G. Knepley /*@C
1354194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1355194d53e6SMatthew G. Knepley 
135620f4b53cSBarry Smith   Not Collective
1357194d53e6SMatthew G. Knepley 
1358194d53e6SMatthew G. Knepley   Input Parameters:
1359dce8aebaSBarry Smith + ds - The `PetscDS`
1360194d53e6SMatthew G. Knepley . f  - The test field number
1361194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1362194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1363194d53e6SMatthew G. Knepley 
136420f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1365dce8aebaSBarry Smith .vb
136620f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1367dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1368dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1369dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1370dce8aebaSBarry Smith .ve
1371194d53e6SMatthew G. Knepley + dim - the spatial dimension
1372194d53e6SMatthew G. Knepley . Nf - the number of fields
1373194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1374194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1375194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1376194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1377194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1378194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1379194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1380194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1381194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1382194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1383194d53e6SMatthew G. Knepley . t - current time
1384194d53e6SMatthew G. Knepley . x - coordinates of the current point
138597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
138697b6e6e8SMatthew G. Knepley . constants - constant parameters
1387194d53e6SMatthew G. Knepley - f0 - output values at the current point
1388194d53e6SMatthew G. Knepley 
1389194d53e6SMatthew G. Knepley   Level: intermediate
1390194d53e6SMatthew G. Knepley 
1391dce8aebaSBarry Smith   Note:
1392dce8aebaSBarry 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)
1393dce8aebaSBarry Smith 
1394dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1395194d53e6SMatthew G. Knepley @*/
1396d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1397d71ae5a4SJacob Faibussowitsch {
13982764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13996528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1400f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1401f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
140263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
14043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14052764a2aaSMatthew G. Knepley }
14062764a2aaSMatthew G. Knepley 
14073e75805dSMatthew G. Knepley /*@C
1408cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1409cb36c0f9SMatthew G. Knepley 
141020f4b53cSBarry Smith   Not Collective
1411cb36c0f9SMatthew G. Knepley 
1412cb36c0f9SMatthew G. Knepley   Input Parameters:
1413dce8aebaSBarry Smith + ds - The `PetscDS`
1414cb36c0f9SMatthew G. Knepley - f  - The test field number
1415cb36c0f9SMatthew G. Knepley 
1416cb36c0f9SMatthew G. Knepley   Output Parameters:
1417cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1418cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1419cb36c0f9SMatthew G. Knepley 
142020f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1421dce8aebaSBarry Smith .vb
142220f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1423dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1424dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1425dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1426dce8aebaSBarry Smith .ve
1427cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1428cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1429cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1430cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1431cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1432cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1433cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1434cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1435cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1436cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1437cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1438cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1439cb36c0f9SMatthew G. Knepley . t - current time
1440cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1441cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1442cb36c0f9SMatthew G. Knepley . constants - constant parameters
1443cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1444cb36c0f9SMatthew G. Knepley 
1445cb36c0f9SMatthew G. Knepley   Level: intermediate
1446cb36c0f9SMatthew G. Knepley 
1447dce8aebaSBarry Smith   Note:
1448dce8aebaSBarry 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)
1449dce8aebaSBarry Smith 
1450dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1451cb36c0f9SMatthew G. Knepley @*/
1452d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1453d71ae5a4SJacob Faibussowitsch {
1454cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1455cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1456cb36c0f9SMatthew G. Knepley 
1457cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1458cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
145963a3b9bcSJacob 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);
14609566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1461cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1462cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1464cb36c0f9SMatthew G. Knepley }
1465cb36c0f9SMatthew G. Knepley 
1466cb36c0f9SMatthew G. Knepley /*@C
1467cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1468cb36c0f9SMatthew G. Knepley 
146920f4b53cSBarry Smith   Not Collective
1470cb36c0f9SMatthew G. Knepley 
1471cb36c0f9SMatthew G. Knepley   Input Parameters:
1472dce8aebaSBarry Smith + ds - The `PetscDS`
1473cb36c0f9SMatthew G. Knepley . f  - The test field number
1474cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1475cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1476cb36c0f9SMatthew G. Knepley 
1477dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1478dce8aebaSBarry Smith .vb
1479dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1480dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1481dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1482dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1483dce8aebaSBarry Smith .ve
1484cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1485cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1486cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1487cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1488cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1489cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1490cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1491cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1492cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1493cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1494cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1495cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1496cb36c0f9SMatthew G. Knepley . t - current time
1497cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1498cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1499cb36c0f9SMatthew G. Knepley . constants - constant parameters
1500cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1501cb36c0f9SMatthew G. Knepley 
1502cb36c0f9SMatthew G. Knepley   Level: intermediate
1503cb36c0f9SMatthew G. Knepley 
1504dce8aebaSBarry Smith   Note:
1505dce8aebaSBarry 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)
1506dce8aebaSBarry Smith 
1507dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1508cb36c0f9SMatthew G. Knepley @*/
1509d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1510d71ae5a4SJacob Faibussowitsch {
1511cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1512cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1513cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1514cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
151563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
15169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
15173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1518cb36c0f9SMatthew G. Knepley }
1519cb36c0f9SMatthew G. Knepley 
1520cb36c0f9SMatthew G. Knepley /*@C
1521dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
15223e75805dSMatthew G. Knepley 
152320f4b53cSBarry Smith   Not Collective
15243e75805dSMatthew G. Knepley 
15253e75805dSMatthew G. Knepley   Input Parameter:
1526dce8aebaSBarry Smith . prob - The `PetscDS`
15273e75805dSMatthew G. Knepley 
15283e75805dSMatthew G. Knepley   Output Parameter:
15293e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15303e75805dSMatthew G. Knepley 
15313e75805dSMatthew G. Knepley   Level: intermediate
15323e75805dSMatthew G. Knepley 
1533dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15343e75805dSMatthew G. Knepley @*/
1535d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1536d71ae5a4SJacob Faibussowitsch {
15373e75805dSMatthew G. Knepley   PetscFunctionBegin;
15386528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15399566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
15403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15413e75805dSMatthew G. Knepley }
15423e75805dSMatthew G. Knepley 
1543194d53e6SMatthew G. Knepley /*@C
1544194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1545194d53e6SMatthew G. Knepley 
154620f4b53cSBarry Smith   Not Collective
1547194d53e6SMatthew G. Knepley 
1548194d53e6SMatthew G. Knepley   Input Parameters:
1549dce8aebaSBarry Smith + ds - The `PetscDS`
1550194d53e6SMatthew G. Knepley . f  - The test field number
1551194d53e6SMatthew G. Knepley - g  - The field number
1552194d53e6SMatthew G. Knepley 
1553194d53e6SMatthew G. Knepley   Output Parameters:
1554194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1555194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1556194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1557194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1558194d53e6SMatthew G. Knepley 
155920f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1560dce8aebaSBarry Smith .vb
156120f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1562dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1563dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1564dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1565dce8aebaSBarry Smith .ve
1566194d53e6SMatthew G. Knepley + dim - the spatial dimension
1567194d53e6SMatthew G. Knepley . Nf - the number of fields
1568194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1569194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1570194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1571194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1572194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1573194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1574194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1575194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1576194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1577194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1578194d53e6SMatthew G. Knepley . t - current time
15792aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1580194d53e6SMatthew G. Knepley . x - coordinates of the current point
158197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
158297b6e6e8SMatthew G. Knepley . constants - constant parameters
1583194d53e6SMatthew G. Knepley - g0 - output values at the current point
1584194d53e6SMatthew G. Knepley 
1585194d53e6SMatthew G. Knepley   Level: intermediate
1586194d53e6SMatthew G. Knepley 
1587dce8aebaSBarry Smith   Note:
1588dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1589dce8aebaSBarry 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
1590dce8aebaSBarry Smith 
1591dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1592194d53e6SMatthew G. Knepley @*/
1593d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1594d71ae5a4SJacob Faibussowitsch {
15956528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
15966528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
15976528b96dSMatthew G. Knepley 
15982764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15996528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
160063a3b9bcSJacob 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);
160163a3b9bcSJacob 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);
16029566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
16036528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
16046528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
16056528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
16066528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
16073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16082764a2aaSMatthew G. Knepley }
16092764a2aaSMatthew G. Knepley 
1610194d53e6SMatthew G. Knepley /*@C
1611194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1612194d53e6SMatthew G. Knepley 
161320f4b53cSBarry Smith   Not Collective
1614194d53e6SMatthew G. Knepley 
1615194d53e6SMatthew G. Knepley   Input Parameters:
1616dce8aebaSBarry Smith + ds - The `PetscDS`
1617194d53e6SMatthew G. Knepley . f  - The test field number
1618194d53e6SMatthew G. Knepley . g  - The field number
1619194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1620194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1621194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1622194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1623194d53e6SMatthew G. Knepley 
162420f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1625dce8aebaSBarry Smith .vb
162620f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1627dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1628dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1629dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar g0[])
1630dce8aebaSBarry Smith .ve
1631194d53e6SMatthew G. Knepley + dim - the spatial dimension
1632194d53e6SMatthew G. Knepley . Nf - the number of fields
1633194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1634194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1635194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1636194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1637194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1638194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1639194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1640194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1641194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1642194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1643194d53e6SMatthew G. Knepley . t - current time
16442aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1645194d53e6SMatthew G. Knepley . x - coordinates of the current point
164697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
164797b6e6e8SMatthew G. Knepley . constants - constant parameters
1648194d53e6SMatthew G. Knepley - g0 - output values at the current point
1649194d53e6SMatthew G. Knepley 
1650194d53e6SMatthew G. Knepley   Level: intermediate
1651194d53e6SMatthew G. Knepley 
1652dce8aebaSBarry Smith   Note:
1653dce8aebaSBarry Smith    We are using a first order FEM model for the weak form:
1654dce8aebaSBarry 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
1655dce8aebaSBarry Smith 
1656dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1657194d53e6SMatthew G. Knepley @*/
1658d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1659d71ae5a4SJacob Faibussowitsch {
16602764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16616528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16622764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
16632764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
16642764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
16652764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
166663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
166763a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
16689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
16693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16702764a2aaSMatthew G. Knepley }
16712764a2aaSMatthew G. Knepley 
1672475e0ac9SMatthew G. Knepley /*@C
1673dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
167455c1f793SMatthew G. Knepley 
167520f4b53cSBarry Smith   Not Collective
167655c1f793SMatthew G. Knepley 
167755c1f793SMatthew G. Knepley   Input Parameters:
1678dce8aebaSBarry Smith + prob - The `PetscDS`
167955c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
168055c1f793SMatthew G. Knepley 
168155c1f793SMatthew G. Knepley   Level: intermediate
168255c1f793SMatthew G. Knepley 
1683dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
168455c1f793SMatthew G. Knepley @*/
1685d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1686d71ae5a4SJacob Faibussowitsch {
168755c1f793SMatthew G. Knepley   PetscFunctionBegin;
168855c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
168955c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
16903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
169155c1f793SMatthew G. Knepley }
169255c1f793SMatthew G. Knepley 
169355c1f793SMatthew G. Knepley /*@C
1694dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1695475e0ac9SMatthew G. Knepley 
169620f4b53cSBarry Smith   Not Collective
1697475e0ac9SMatthew G. Knepley 
1698475e0ac9SMatthew G. Knepley   Input Parameter:
1699dce8aebaSBarry Smith . prob - The `PetscDS`
1700475e0ac9SMatthew G. Knepley 
1701475e0ac9SMatthew G. Knepley   Output Parameter:
1702475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1703475e0ac9SMatthew G. Knepley 
1704475e0ac9SMatthew G. Knepley   Level: intermediate
1705475e0ac9SMatthew G. Knepley 
1706dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1707475e0ac9SMatthew G. Knepley @*/
1708d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1709d71ae5a4SJacob Faibussowitsch {
1710475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17116528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1712475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
17133ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
17149566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
17153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1716475e0ac9SMatthew G. Knepley }
1717475e0ac9SMatthew G. Knepley 
1718475e0ac9SMatthew G. Knepley /*@C
1719dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1720dce8aebaSBarry Smith    the system matrix is used to build the preconditioner.
1721475e0ac9SMatthew G. Knepley 
172220f4b53cSBarry Smith   Not Collective
1723475e0ac9SMatthew G. Knepley 
1724475e0ac9SMatthew G. Knepley   Input Parameters:
1725dce8aebaSBarry Smith + ds - The `PetscDS`
1726475e0ac9SMatthew G. Knepley . f  - The test field number
1727475e0ac9SMatthew G. Knepley - g  - The field number
1728475e0ac9SMatthew G. Knepley 
1729475e0ac9SMatthew G. Knepley   Output Parameters:
1730475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1731475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1732475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1733475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1734475e0ac9SMatthew G. Knepley 
173520f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1736dce8aebaSBarry Smith .vb
173720f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1738dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1739dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1740dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1741dce8aebaSBarry Smith .ve
1742475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1743475e0ac9SMatthew G. Knepley . Nf - the number of fields
1744475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1745475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1746475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1747475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1748475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1749475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1750475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1751475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1752475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1753475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1754475e0ac9SMatthew G. Knepley . t - current time
1755475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1756475e0ac9SMatthew G. Knepley . x - coordinates of the current point
175797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
175897b6e6e8SMatthew G. Knepley . constants - constant parameters
1759475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1760475e0ac9SMatthew G. Knepley 
1761475e0ac9SMatthew G. Knepley   Level: intermediate
1762475e0ac9SMatthew G. Knepley 
1763dce8aebaSBarry Smith   Note:
1764dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1765dce8aebaSBarry 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
1766dce8aebaSBarry Smith 
1767dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1768475e0ac9SMatthew G. Knepley @*/
1769d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1770d71ae5a4SJacob Faibussowitsch {
17716528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
17726528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
17736528b96dSMatthew G. Knepley 
1774475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17756528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
177663a3b9bcSJacob 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);
177763a3b9bcSJacob 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);
17789566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17796528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17806528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17816528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
17826528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
17833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1784475e0ac9SMatthew G. Knepley }
1785475e0ac9SMatthew G. Knepley 
1786475e0ac9SMatthew G. Knepley /*@C
1787dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1788dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1789475e0ac9SMatthew G. Knepley 
179020f4b53cSBarry Smith   Not Collective
1791475e0ac9SMatthew G. Knepley 
1792475e0ac9SMatthew G. Knepley   Input Parameters:
1793dce8aebaSBarry Smith + ds - The `PetscDS`
1794475e0ac9SMatthew G. Knepley . f  - The test field number
1795475e0ac9SMatthew G. Knepley . g  - The field number
1796475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1797475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1798475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1799475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1800475e0ac9SMatthew G. Knepley 
180120f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1802dce8aebaSBarry Smith .vb
180320f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1804dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1805dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1806dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar g0[])
1807dce8aebaSBarry Smith .ve
1808475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1809475e0ac9SMatthew G. Knepley . Nf - the number of fields
1810475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1811475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1812475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1813475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1814475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1815475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1816475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1817475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1818475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1819475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1820475e0ac9SMatthew G. Knepley . t - current time
1821475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1822475e0ac9SMatthew G. Knepley . x - coordinates of the current point
182397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
182497b6e6e8SMatthew G. Knepley . constants - constant parameters
1825475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1826475e0ac9SMatthew G. Knepley 
1827475e0ac9SMatthew G. Knepley   Level: intermediate
1828475e0ac9SMatthew G. Knepley 
1829dce8aebaSBarry Smith   Note:
1830dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1831dce8aebaSBarry 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
1832dce8aebaSBarry Smith 
1833dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1834475e0ac9SMatthew G. Knepley @*/
1835d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1836d71ae5a4SJacob Faibussowitsch {
1837475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18386528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1839475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1840475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1841475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1842475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
184363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
184463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
18463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1847475e0ac9SMatthew G. Knepley }
1848475e0ac9SMatthew G. Knepley 
1849b7e05686SMatthew G. Knepley /*@C
1850b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1851b7e05686SMatthew G. Knepley 
185220f4b53cSBarry Smith   Not Collective
1853b7e05686SMatthew G. Knepley 
1854b7e05686SMatthew G. Knepley   Input Parameter:
1855dce8aebaSBarry Smith . ds - The `PetscDS`
1856b7e05686SMatthew G. Knepley 
1857b7e05686SMatthew G. Knepley   Output Parameter:
1858b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1859b7e05686SMatthew G. Knepley 
1860b7e05686SMatthew G. Knepley   Level: intermediate
1861b7e05686SMatthew G. Knepley 
1862dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1863b7e05686SMatthew G. Knepley @*/
1864d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1865d71ae5a4SJacob Faibussowitsch {
1866b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
18689566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
18693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1870b7e05686SMatthew G. Knepley }
1871b7e05686SMatthew G. Knepley 
1872b7e05686SMatthew G. Knepley /*@C
1873b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1874b7e05686SMatthew G. Knepley 
187520f4b53cSBarry Smith   Not Collective
1876b7e05686SMatthew G. Knepley 
1877b7e05686SMatthew G. Knepley   Input Parameters:
1878dce8aebaSBarry Smith + ds - The `PetscDS`
1879b7e05686SMatthew G. Knepley . f  - The test field number
1880b7e05686SMatthew G. Knepley - g  - The field number
1881b7e05686SMatthew G. Knepley 
1882b7e05686SMatthew G. Knepley   Output Parameters:
1883b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1884b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1885b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1886b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1887b7e05686SMatthew G. Knepley 
188820f4b53cSBarry Smith    Calling sequence of `g0`, `g1`, `g2` and `g3`:
1889dce8aebaSBarry Smith .vb
189020f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1891dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1892dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1893dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1894dce8aebaSBarry Smith .ve
1895b7e05686SMatthew G. Knepley + dim - the spatial dimension
1896b7e05686SMatthew G. Knepley . Nf - the number of fields
1897b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1898b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1899b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1900b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1901b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1902b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1903b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1904b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1905b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1906b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1907b7e05686SMatthew G. Knepley . t - current time
1908b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1909b7e05686SMatthew G. Knepley . x - coordinates of the current point
191097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
191197b6e6e8SMatthew G. Knepley . constants - constant parameters
1912b7e05686SMatthew G. Knepley - g0 - output values at the current point
1913b7e05686SMatthew G. Knepley 
1914b7e05686SMatthew G. Knepley   Level: intermediate
1915b7e05686SMatthew G. Knepley 
1916dce8aebaSBarry Smith   Note:
1917dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1918dce8aebaSBarry 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
1919dce8aebaSBarry Smith 
1920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1921b7e05686SMatthew G. Knepley @*/
1922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1923d71ae5a4SJacob Faibussowitsch {
19246528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19256528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19266528b96dSMatthew G. Knepley 
1927b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19286528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
192963a3b9bcSJacob 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);
193063a3b9bcSJacob 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);
19319566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19326528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19336528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19346528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19356528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1937b7e05686SMatthew G. Knepley }
1938b7e05686SMatthew G. Knepley 
1939b7e05686SMatthew G. Knepley /*@C
1940b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1941b7e05686SMatthew G. Knepley 
194220f4b53cSBarry Smith   Not Collective
1943b7e05686SMatthew G. Knepley 
1944b7e05686SMatthew G. Knepley   Input Parameters:
1945dce8aebaSBarry Smith + ds - The `PetscDS`
1946b7e05686SMatthew G. Knepley . f  - The test field number
1947b7e05686SMatthew G. Knepley . g  - The field number
1948b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
1949b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1950b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1951b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1952b7e05686SMatthew G. Knepley 
195320f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1954dce8aebaSBarry Smith .vb
195520f4b53cSBarry Smith    void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1956dce8aebaSBarry Smith            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1957dce8aebaSBarry Smith            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1958dce8aebaSBarry Smith            PetscReal t, const PetscReal x[], PetscScalar g0[])
1959dce8aebaSBarry Smith .ve
1960b7e05686SMatthew G. Knepley + dim - the spatial dimension
1961b7e05686SMatthew G. Knepley . Nf - the number of fields
1962b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1963b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1964b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1965b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1966b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1967b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1968b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1969b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1970b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1971b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1972b7e05686SMatthew G. Knepley . t - current time
1973b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1974b7e05686SMatthew G. Knepley . x - coordinates of the current point
197597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
197697b6e6e8SMatthew G. Knepley . constants - constant parameters
1977b7e05686SMatthew G. Knepley - g0 - output values at the current point
1978b7e05686SMatthew G. Knepley 
1979b7e05686SMatthew G. Knepley   Level: intermediate
1980b7e05686SMatthew G. Knepley 
1981dce8aebaSBarry Smith   Note:
1982dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1983dce8aebaSBarry 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
1984dce8aebaSBarry Smith 
1985dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1986b7e05686SMatthew G. Knepley @*/
1987d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1988d71ae5a4SJacob Faibussowitsch {
1989b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1991b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1992b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1993b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1994b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
199563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
199663a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19979566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1999b7e05686SMatthew G. Knepley }
2000b7e05686SMatthew G. Knepley 
20010c2f2876SMatthew G. Knepley /*@C
20020c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
20030c2f2876SMatthew G. Knepley 
200420f4b53cSBarry Smith   Not Collective
20050c2f2876SMatthew G. Knepley 
20064165533cSJose E. Roman   Input Parameters:
2007dce8aebaSBarry Smith + ds - The `PetscDS` object
20080c2f2876SMatthew G. Knepley - f  - The field number
20090c2f2876SMatthew G. Knepley 
20104165533cSJose E. Roman   Output Parameter:
20110c2f2876SMatthew G. Knepley . r    - Riemann solver
20120c2f2876SMatthew G. Knepley 
201320f4b53cSBarry Smith   Calling sequence of `r`:
2014dce8aebaSBarry Smith .vb
201520f4b53cSBarry Smith   void r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2016dce8aebaSBarry Smith .ve
20175db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20185db36cf9SMatthew G. Knepley . Nf   - The number of fields
20195db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20200c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20210c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20220c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20230c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
202497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
202597b6e6e8SMatthew G. Knepley . constants - constant parameters
20260c2f2876SMatthew G. Knepley - ctx  - optional user context
20270c2f2876SMatthew G. Knepley 
20280c2f2876SMatthew G. Knepley   Level: intermediate
20290c2f2876SMatthew G. Knepley 
2030dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20310c2f2876SMatthew G. Knepley @*/
2032d71ae5a4SJacob 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))
2033d71ae5a4SJacob Faibussowitsch {
20346528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20356528b96dSMatthew G. Knepley   PetscInt          n;
20366528b96dSMatthew G. Knepley 
20370c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20386528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20390c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
204063a3b9bcSJacob 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);
20419566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20426528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20440c2f2876SMatthew G. Knepley }
20450c2f2876SMatthew G. Knepley 
20460c2f2876SMatthew G. Knepley /*@C
20470c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20480c2f2876SMatthew G. Knepley 
204920f4b53cSBarry Smith   Not Collective
20500c2f2876SMatthew G. Knepley 
20514165533cSJose E. Roman   Input Parameters:
2052dce8aebaSBarry Smith + ds - The `PetscDS` object
20530c2f2876SMatthew G. Knepley . f  - The field number
20540c2f2876SMatthew G. Knepley - r  - Riemann solver
20550c2f2876SMatthew G. Knepley 
205620f4b53cSBarry Smith   Calling sequence of `r`:
2057dce8aebaSBarry Smith .vb
205820f4b53cSBarry Smith    void r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2059dce8aebaSBarry Smith .ve
20605db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20615db36cf9SMatthew G. Knepley . Nf   - The number of fields
20625db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20630c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20640c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20650c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20660c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
206797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
206897b6e6e8SMatthew G. Knepley . constants - constant parameters
20690c2f2876SMatthew G. Knepley - ctx  - optional user context
20700c2f2876SMatthew G. Knepley 
20710c2f2876SMatthew G. Knepley   Level: intermediate
20720c2f2876SMatthew G. Knepley 
2073dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
20740c2f2876SMatthew G. Knepley @*/
2075d71ae5a4SJacob 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))
2076d71ae5a4SJacob Faibussowitsch {
20770c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20786528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2079de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
208063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20819566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
20823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20830c2f2876SMatthew G. Knepley }
20840c2f2876SMatthew G. Knepley 
208532d2bbc9SMatthew G. Knepley /*@C
208632d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
208732d2bbc9SMatthew G. Knepley 
208820f4b53cSBarry Smith   Not Collective
208932d2bbc9SMatthew G. Knepley 
209032d2bbc9SMatthew G. Knepley   Input Parameters:
2091dce8aebaSBarry Smith + ds - The `PetscDS`
209232d2bbc9SMatthew G. Knepley - f  - The field number
209332d2bbc9SMatthew G. Knepley 
2094f899ff85SJose E. Roman   Output Parameter:
2095a2b725a8SWilliam Gropp . update - update function
209632d2bbc9SMatthew G. Knepley 
209720f4b53cSBarry Smith   Calling sequence of `update`:
2098dce8aebaSBarry Smith .vb
209920f4b53cSBarry Smith   void update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2100dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2101dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2102dce8aebaSBarry Smith               PetscReal t, const PetscReal x[], PetscScalar uNew[])
2103dce8aebaSBarry Smith .ve
210432d2bbc9SMatthew G. Knepley + dim - the spatial dimension
210532d2bbc9SMatthew G. Knepley . Nf - the number of fields
210632d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
210732d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
210832d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
210932d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
211032d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
211132d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
211232d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
211332d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
211432d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
211532d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
211632d2bbc9SMatthew G. Knepley . t - current time
211732d2bbc9SMatthew G. Knepley . x - coordinates of the current point
211832d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
211932d2bbc9SMatthew G. Knepley 
212032d2bbc9SMatthew G. Knepley   Level: intermediate
212132d2bbc9SMatthew G. Knepley 
2122dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
212332d2bbc9SMatthew G. Knepley @*/
2124d71ae5a4SJacob 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[]))
2125d71ae5a4SJacob Faibussowitsch {
212632d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21276528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
212863a3b9bcSJacob 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);
21299371c9d4SSatish Balay   if (update) {
21309371c9d4SSatish Balay     PetscValidPointer(update, 3);
21319371c9d4SSatish Balay     *update = ds->update[f];
21329371c9d4SSatish Balay   }
21333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
213432d2bbc9SMatthew G. Knepley }
213532d2bbc9SMatthew G. Knepley 
213632d2bbc9SMatthew G. Knepley /*@C
21373fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
213832d2bbc9SMatthew G. Knepley 
213920f4b53cSBarry Smith   Not Collective
214032d2bbc9SMatthew G. Knepley 
214132d2bbc9SMatthew G. Knepley   Input Parameters:
2142dce8aebaSBarry Smith + ds     - The `PetscDS`
214332d2bbc9SMatthew G. Knepley . f      - The field number
214432d2bbc9SMatthew G. Knepley - update - update function
214532d2bbc9SMatthew G. Knepley 
214620f4b53cSBarry Smith   Calling sequence of `update`:
2147dce8aebaSBarry Smith .vb
214820f4b53cSBarry Smith   void update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2149dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2150dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2151dce8aebaSBarry Smith               PetscReal t, const PetscReal x[], PetscScalar uNew[])
2152dce8aebaSBarry Smith .ve
215332d2bbc9SMatthew G. Knepley + dim - the spatial dimension
215432d2bbc9SMatthew G. Knepley . Nf - the number of fields
215532d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
215632d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
215732d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
215832d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
215932d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
216032d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
216132d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
216232d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
216332d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
216432d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
216532d2bbc9SMatthew G. Knepley . t - current time
216632d2bbc9SMatthew G. Knepley . x - coordinates of the current point
216732d2bbc9SMatthew G. Knepley - uNew - new field values at the current point
216832d2bbc9SMatthew G. Knepley 
216932d2bbc9SMatthew G. Knepley   Level: intermediate
217032d2bbc9SMatthew G. Knepley 
2171dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
217232d2bbc9SMatthew G. Knepley @*/
2173d71ae5a4SJacob 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[]))
2174d71ae5a4SJacob Faibussowitsch {
217532d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
217732d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
217863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21799566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21806528b96dSMatthew G. Knepley   ds->update[f] = update;
21813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
218232d2bbc9SMatthew G. Knepley }
218332d2bbc9SMatthew G. Knepley 
2184d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2185d71ae5a4SJacob Faibussowitsch {
21860c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21876528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
218863a3b9bcSJacob 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);
21890c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
21903ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
21913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21920c2f2876SMatthew G. Knepley }
21930c2f2876SMatthew G. Knepley 
2194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2195d71ae5a4SJacob Faibussowitsch {
21960c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21976528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
219863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21999566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
22006528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
22013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22020c2f2876SMatthew G. Knepley }
22030c2f2876SMatthew G. Knepley 
2204194d53e6SMatthew G. Knepley /*@C
2205194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2206194d53e6SMatthew G. Knepley 
220720f4b53cSBarry Smith   Not Collective
2208194d53e6SMatthew G. Knepley 
2209194d53e6SMatthew G. Knepley   Input Parameters:
22106528b96dSMatthew G. Knepley + ds - The PetscDS
2211194d53e6SMatthew G. Knepley - f  - The test field number
2212194d53e6SMatthew G. Knepley 
2213194d53e6SMatthew G. Knepley   Output Parameters:
2214194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2215194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2216194d53e6SMatthew G. Knepley 
221720f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
2218dce8aebaSBarry Smith .vb
221920f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2220dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2221dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2222dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2223dce8aebaSBarry Smith .ve
2224194d53e6SMatthew G. Knepley + dim - the spatial dimension
2225194d53e6SMatthew G. Knepley . Nf - the number of fields
2226194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2227194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2228194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2229194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2230194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2231194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2232194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2233194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2234194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2235194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2236194d53e6SMatthew G. Knepley . t - current time
2237194d53e6SMatthew G. Knepley . x - coordinates of the current point
2238194d53e6SMatthew G. Knepley . n - unit normal at the current point
223997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
224097b6e6e8SMatthew G. Knepley . constants - constant parameters
2241194d53e6SMatthew G. Knepley - f0 - output values at the current point
2242194d53e6SMatthew G. Knepley 
2243194d53e6SMatthew G. Knepley   Level: intermediate
2244194d53e6SMatthew G. Knepley 
2245dce8aebaSBarry Smith   Note:
2246dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2247dce8aebaSBarry 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
2248dce8aebaSBarry Smith 
2249dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2250194d53e6SMatthew G. Knepley @*/
2251d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f, void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2252d71ae5a4SJacob Faibussowitsch {
22536528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22546528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22556528b96dSMatthew G. Knepley 
22562764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22576528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
225863a3b9bcSJacob 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);
22599566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22606528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22616528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22632764a2aaSMatthew G. Knepley }
22642764a2aaSMatthew G. Knepley 
2265194d53e6SMatthew G. Knepley /*@C
2266194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2267194d53e6SMatthew G. Knepley 
226820f4b53cSBarry Smith   Not Collective
2269194d53e6SMatthew G. Knepley 
2270194d53e6SMatthew G. Knepley   Input Parameters:
2271dce8aebaSBarry Smith + ds - The `PetscDS`
2272194d53e6SMatthew G. Knepley . f  - The test field number
2273194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2274194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2275194d53e6SMatthew G. Knepley 
227620f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
2277dce8aebaSBarry Smith .vb
227820f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2279dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2280dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2281dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2282dce8aebaSBarry Smith .ve
2283194d53e6SMatthew G. Knepley + dim - the spatial dimension
2284194d53e6SMatthew G. Knepley . Nf - the number of fields
2285194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2286194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2287194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2288194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2289194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2290194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2291194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2292194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2293194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2294194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2295194d53e6SMatthew G. Knepley . t - current time
2296194d53e6SMatthew G. Knepley . x - coordinates of the current point
2297194d53e6SMatthew G. Knepley . n - unit normal at the current point
229897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
229997b6e6e8SMatthew G. Knepley . constants - constant parameters
2300194d53e6SMatthew G. Knepley - f0 - output values at the current point
2301194d53e6SMatthew G. Knepley 
2302194d53e6SMatthew G. Knepley   Level: intermediate
2303194d53e6SMatthew G. Knepley 
2304dce8aebaSBarry Smith   Note:
2305dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2306dce8aebaSBarry 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
2307dce8aebaSBarry Smith 
2308dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2309194d53e6SMatthew G. Knepley @*/
2310d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f, void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]), void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2311d71ae5a4SJacob Faibussowitsch {
23122764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
231463a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
23159566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
23163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23172764a2aaSMatthew G. Knepley }
23182764a2aaSMatthew G. Knepley 
231927f02ce8SMatthew G. Knepley /*@
2320dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
232127f02ce8SMatthew G. Knepley 
232220f4b53cSBarry Smith   Not Collective
232327f02ce8SMatthew G. Knepley 
232427f02ce8SMatthew G. Knepley   Input Parameter:
2325dce8aebaSBarry Smith . ds - The `PetscDS`
232627f02ce8SMatthew G. Knepley 
232727f02ce8SMatthew G. Knepley   Output Parameter:
232827f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
232927f02ce8SMatthew G. Knepley 
233027f02ce8SMatthew G. Knepley   Level: intermediate
233127f02ce8SMatthew G. Knepley 
2332dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
233327f02ce8SMatthew G. Knepley @*/
2334d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2335d71ae5a4SJacob Faibussowitsch {
233627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23376528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23386528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
23399566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
234127f02ce8SMatthew G. Knepley }
234227f02ce8SMatthew G. Knepley 
2343194d53e6SMatthew G. Knepley /*@C
2344194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2345194d53e6SMatthew G. Knepley 
234620f4b53cSBarry Smith   Not Collective
2347194d53e6SMatthew G. Knepley 
2348194d53e6SMatthew G. Knepley   Input Parameters:
2349dce8aebaSBarry Smith + ds - The `PetscDS`
2350194d53e6SMatthew G. Knepley . f  - The test field number
2351194d53e6SMatthew G. Knepley - g  - The field number
2352194d53e6SMatthew G. Knepley 
2353194d53e6SMatthew G. Knepley   Output Parameters:
2354194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2355194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2356194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2357194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2358194d53e6SMatthew G. Knepley 
235920f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2360dce8aebaSBarry Smith .vb
236120f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2362dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2363dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2364dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2365dce8aebaSBarry Smith .ve
2366194d53e6SMatthew G. Knepley + dim - the spatial dimension
2367194d53e6SMatthew G. Knepley . Nf - the number of fields
2368194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2369194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2370194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2371194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2372194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2373194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2374194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2375194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2376194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2377194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2378194d53e6SMatthew G. Knepley . t - current time
23792aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2380194d53e6SMatthew G. Knepley . x - coordinates of the current point
2381194d53e6SMatthew G. Knepley . n - normal at the current point
238297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
238397b6e6e8SMatthew G. Knepley . constants - constant parameters
2384194d53e6SMatthew G. Knepley - g0 - output values at the current point
2385194d53e6SMatthew G. Knepley 
2386194d53e6SMatthew G. Knepley   Level: intermediate
2387194d53e6SMatthew G. Knepley 
2388dce8aebaSBarry Smith   Note:
2389dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2390dce8aebaSBarry 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
2391dce8aebaSBarry Smith 
2392dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2393194d53e6SMatthew G. Knepley @*/
2394d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2395d71ae5a4SJacob Faibussowitsch {
23966528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
23976528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
23986528b96dSMatthew G. Knepley 
23992764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24006528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
240163a3b9bcSJacob 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);
240263a3b9bcSJacob 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);
24039566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
24046528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
24056528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
24066528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
24076528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
24083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24092764a2aaSMatthew G. Knepley }
24102764a2aaSMatthew G. Knepley 
2411194d53e6SMatthew G. Knepley /*@C
2412194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2413194d53e6SMatthew G. Knepley 
241420f4b53cSBarry Smith   Not Collective
2415194d53e6SMatthew G. Knepley 
2416194d53e6SMatthew G. Knepley   Input Parameters:
24176528b96dSMatthew G. Knepley + ds - The PetscDS
2418194d53e6SMatthew G. Knepley . f  - The test field number
2419194d53e6SMatthew G. Knepley . g  - The field number
2420194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2421194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2422194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2423194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2424194d53e6SMatthew G. Knepley 
242520f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2426dce8aebaSBarry Smith .vb
242720f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2428dce8aebaSBarry Smith        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2429dce8aebaSBarry Smith        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2430dce8aebaSBarry Smith        PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2431dce8aebaSBarry Smith .ve
2432194d53e6SMatthew G. Knepley + dim - the spatial dimension
2433194d53e6SMatthew G. Knepley . Nf - the number of fields
2434194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2435194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2436194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2437194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2438194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2439194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2440194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2441194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2442194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2443194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2444194d53e6SMatthew G. Knepley . t - current time
24452aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2446194d53e6SMatthew G. Knepley . x - coordinates of the current point
2447194d53e6SMatthew G. Knepley . n - normal at the current point
244897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
244997b6e6e8SMatthew G. Knepley . constants - constant parameters
2450194d53e6SMatthew G. Knepley - g0 - output values at the current point
2451194d53e6SMatthew G. Knepley 
2452194d53e6SMatthew G. Knepley   Level: intermediate
2453194d53e6SMatthew G. Knepley 
2454dce8aebaSBarry Smith   Note:
2455dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2456dce8aebaSBarry 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
2457dce8aebaSBarry Smith 
2458dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2459194d53e6SMatthew G. Knepley @*/
2460d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2461d71ae5a4SJacob Faibussowitsch {
24622764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24636528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24642764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24652764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24662764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24672764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
246863a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
246963a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24709566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24722764a2aaSMatthew G. Knepley }
24732764a2aaSMatthew G. Knepley 
247427f02ce8SMatthew G. Knepley /*@
247527f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
247627f02ce8SMatthew G. Knepley 
247720f4b53cSBarry Smith   Not Collective
247827f02ce8SMatthew G. Knepley 
247927f02ce8SMatthew G. Knepley   Input Parameter:
2480dce8aebaSBarry Smith . ds - The `PetscDS`
248127f02ce8SMatthew G. Knepley 
248227f02ce8SMatthew G. Knepley   Output Parameter:
248327f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
248427f02ce8SMatthew G. Knepley 
248527f02ce8SMatthew G. Knepley   Level: intermediate
248627f02ce8SMatthew G. Knepley 
2487dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
248827f02ce8SMatthew G. Knepley @*/
2489d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2490d71ae5a4SJacob Faibussowitsch {
249127f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24926528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24936528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
24949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
24953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
249627f02ce8SMatthew G. Knepley }
249727f02ce8SMatthew G. Knepley 
249827f02ce8SMatthew G. Knepley /*@C
249927f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
250027f02ce8SMatthew G. Knepley 
250120f4b53cSBarry Smith   Not Collective; No Fortran Support
250227f02ce8SMatthew G. Knepley 
250327f02ce8SMatthew G. Knepley   Input Parameters:
2504dce8aebaSBarry Smith + ds - The `PetscDS`
250527f02ce8SMatthew G. Knepley . f  - The test field number
250627f02ce8SMatthew G. Knepley - g  - The field number
250727f02ce8SMatthew G. Knepley 
250827f02ce8SMatthew G. Knepley   Output Parameters:
250927f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
251027f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
251127f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
251227f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
251327f02ce8SMatthew G. Knepley 
251420f4b53cSBarry Smith    Calling sequence of `g0`, `g1`, `g2` and `g3`:
2515dce8aebaSBarry Smith .vb
251620f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2517dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2518dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2519dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2520dce8aebaSBarry Smith .ve
252127f02ce8SMatthew G. Knepley + dim - the spatial dimension
252227f02ce8SMatthew G. Knepley . Nf - the number of fields
252327f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
252427f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
252527f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
252627f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
252727f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
252827f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
252927f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
253027f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
253127f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
253227f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
253327f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
253427f02ce8SMatthew G. Knepley . t - current time
253527f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
253627f02ce8SMatthew G. Knepley . x - coordinates of the current point
253727f02ce8SMatthew G. Knepley . n - normal at the current point
253827f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
253927f02ce8SMatthew G. Knepley . constants - constant parameters
254027f02ce8SMatthew G. Knepley - g0 - output values at the current point
254127f02ce8SMatthew G. Knepley 
254227f02ce8SMatthew G. Knepley   Level: intermediate
254327f02ce8SMatthew G. Knepley 
2544dce8aebaSBarry Smith   Note:
2545dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2546dce8aebaSBarry 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
2547dce8aebaSBarry Smith 
2548dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
254927f02ce8SMatthew G. Knepley @*/
2550d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2551d71ae5a4SJacob Faibussowitsch {
25526528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25536528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25546528b96dSMatthew G. Knepley 
255527f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25566528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
255763a3b9bcSJacob 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);
255863a3b9bcSJacob 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);
25599566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25606528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25616528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25626528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25636528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
256527f02ce8SMatthew G. Knepley }
256627f02ce8SMatthew G. Knepley 
256727f02ce8SMatthew G. Knepley /*@C
256827f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
256927f02ce8SMatthew G. Knepley 
257020f4b53cSBarry Smith   Not Collective; No Fortran Support
257127f02ce8SMatthew G. Knepley 
257227f02ce8SMatthew G. Knepley   Input Parameters:
2573dce8aebaSBarry Smith + ds - The `PetscDS`
257427f02ce8SMatthew G. Knepley . f  - The test field number
257527f02ce8SMatthew G. Knepley . g  - The field number
257627f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
257727f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
257827f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
257927f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
258027f02ce8SMatthew G. Knepley 
258120f4b53cSBarry Smith    Calling sequence of `g0`, `g1`, `g2` and `g3`:
2582dce8aebaSBarry Smith .vb
258320f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2584dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2585dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2586dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2587dce8aebaSBarry Smith .ve
258827f02ce8SMatthew G. Knepley + dim - the spatial dimension
258927f02ce8SMatthew G. Knepley . Nf - the number of fields
259027f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
259127f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
259227f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
259327f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
259427f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
259527f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
259627f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
259727f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
259827f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
259927f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
260027f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
260127f02ce8SMatthew G. Knepley . t - current time
260227f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
260327f02ce8SMatthew G. Knepley . x - coordinates of the current point
260427f02ce8SMatthew G. Knepley . n - normal at the current point
260527f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
260627f02ce8SMatthew G. Knepley . constants - constant parameters
260727f02ce8SMatthew G. Knepley - g0 - output values at the current point
260827f02ce8SMatthew G. Knepley 
260927f02ce8SMatthew G. Knepley   Level: intermediate
261027f02ce8SMatthew G. Knepley 
2611dce8aebaSBarry Smith   Note:
2612dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2613dce8aebaSBarry 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
2614dce8aebaSBarry Smith 
2615dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
261627f02ce8SMatthew G. Knepley @*/
2617d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g, void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]), void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]), void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]), void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2618d71ae5a4SJacob Faibussowitsch {
261927f02ce8SMatthew G. Knepley   PetscFunctionBegin;
26206528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
262127f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
262227f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
262327f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
262427f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
262563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
262663a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
262927f02ce8SMatthew G. Knepley }
263027f02ce8SMatthew G. Knepley 
26310d3e9b51SMatthew G. Knepley /*@C
2632c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2633c371a6d1SMatthew G. Knepley 
263420f4b53cSBarry Smith   Not Collective
2635c371a6d1SMatthew G. Knepley 
2636c371a6d1SMatthew G. Knepley   Input Parameters:
2637c371a6d1SMatthew G. Knepley + prob - The PetscDS
2638c371a6d1SMatthew G. Knepley - f    - The test field number
2639c371a6d1SMatthew G. Knepley 
2640d8d19677SJose E. Roman   Output Parameters:
264195cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
264295cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2643c371a6d1SMatthew G. Knepley 
264420f4b53cSBarry Smith   Calling sequence of `exactSol`:
2645dce8aebaSBarry Smith .vb
264620f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2647dce8aebaSBarry Smith .ve
2648c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2649c371a6d1SMatthew G. Knepley . t - current time
2650c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2651c371a6d1SMatthew G. Knepley . Nc - the number of field components
2652c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2653c371a6d1SMatthew G. Knepley - ctx - a user context
2654c371a6d1SMatthew G. Knepley 
2655c371a6d1SMatthew G. Knepley   Level: intermediate
2656c371a6d1SMatthew G. Knepley 
2657dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2658c371a6d1SMatthew G. Knepley @*/
2659d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2660d71ae5a4SJacob Faibussowitsch {
2661c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2662c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
266363a3b9bcSJacob 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);
26649371c9d4SSatish Balay   if (sol) {
26659371c9d4SSatish Balay     PetscValidPointer(sol, 3);
26669371c9d4SSatish Balay     *sol = prob->exactSol[f];
26679371c9d4SSatish Balay   }
26689371c9d4SSatish Balay   if (ctx) {
26699371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
26709371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26719371c9d4SSatish Balay   }
26723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2673c371a6d1SMatthew G. Knepley }
2674c371a6d1SMatthew G. Knepley 
2675c371a6d1SMatthew G. Knepley /*@C
2676578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2677c371a6d1SMatthew G. Knepley 
267820f4b53cSBarry Smith   Not Collective
2679c371a6d1SMatthew G. Knepley 
2680c371a6d1SMatthew G. Knepley   Input Parameters:
2681dce8aebaSBarry Smith + prob - The `PetscDS`
2682c371a6d1SMatthew G. Knepley . f    - The test field number
268395cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
268420f4b53cSBarry Smith - ctx  - solution context or `NULL`
2685c371a6d1SMatthew G. Knepley 
268620f4b53cSBarry Smith   Calling sequence of `sol`:
2687dce8aebaSBarry Smith .vb
268820f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2689dce8aebaSBarry Smith .ve
2690c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2691c371a6d1SMatthew G. Knepley . t - current time
2692c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2693c371a6d1SMatthew G. Knepley . Nc - the number of field components
2694c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2695c371a6d1SMatthew G. Knepley - ctx - a user context
2696c371a6d1SMatthew G. Knepley 
2697c371a6d1SMatthew G. Knepley   Level: intermediate
2698c371a6d1SMatthew G. Knepley 
2699dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2700c371a6d1SMatthew G. Knepley @*/
2701d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2702d71ae5a4SJacob Faibussowitsch {
2703c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2704c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
270563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27069566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27079371c9d4SSatish Balay   if (sol) {
27089371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27099371c9d4SSatish Balay     prob->exactSol[f] = sol;
27109371c9d4SSatish Balay   }
27119371c9d4SSatish Balay   if (ctx) {
27129371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27139371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
27149371c9d4SSatish Balay   }
27153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2716c371a6d1SMatthew G. Knepley }
2717c371a6d1SMatthew G. Knepley 
27185638fd0eSMatthew G. Knepley /*@C
2719f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2720f2cacb80SMatthew G. Knepley 
272120f4b53cSBarry Smith   Not Collective
2722f2cacb80SMatthew G. Knepley 
2723f2cacb80SMatthew G. Knepley   Input Parameters:
2724dce8aebaSBarry Smith + prob - The `PetscDS`
2725f2cacb80SMatthew G. Knepley - f    - The test field number
2726f2cacb80SMatthew G. Knepley 
2727d8d19677SJose E. Roman   Output Parameters:
2728f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2729f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2730f2cacb80SMatthew G. Knepley 
273120f4b53cSBarry Smith   Calling sequence of `exactSol`:
2732dce8aebaSBarry Smith .vb
273320f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2734dce8aebaSBarry Smith .ve
2735f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2736f2cacb80SMatthew G. Knepley . t - current time
2737f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2738f2cacb80SMatthew G. Knepley . Nc - the number of field components
2739f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2740f2cacb80SMatthew G. Knepley - ctx - a user context
2741f2cacb80SMatthew G. Knepley 
2742f2cacb80SMatthew G. Knepley   Level: intermediate
2743f2cacb80SMatthew G. Knepley 
2744dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2745f2cacb80SMatthew G. Knepley @*/
2746d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2747d71ae5a4SJacob Faibussowitsch {
2748f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2749f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
275063a3b9bcSJacob 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);
27519371c9d4SSatish Balay   if (sol) {
27529371c9d4SSatish Balay     PetscValidPointer(sol, 3);
27539371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27549371c9d4SSatish Balay   }
27559371c9d4SSatish Balay   if (ctx) {
27569371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
27579371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27589371c9d4SSatish Balay   }
27593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2760f2cacb80SMatthew G. Knepley }
2761f2cacb80SMatthew G. Knepley 
2762f2cacb80SMatthew G. Knepley /*@C
2763f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2764f2cacb80SMatthew G. Knepley 
276520f4b53cSBarry Smith   Not Collective
2766f2cacb80SMatthew G. Knepley 
2767f2cacb80SMatthew G. Knepley   Input Parameters:
2768dce8aebaSBarry Smith + prob - The `PetscDS`
2769f2cacb80SMatthew G. Knepley . f    - The test field number
2770f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
277120f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2772f2cacb80SMatthew G. Knepley 
277320f4b53cSBarry Smith   Calling sequence of `sol`:
2774dce8aebaSBarry Smith .vb
277520f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2776dce8aebaSBarry Smith .ve
2777f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2778f2cacb80SMatthew G. Knepley . t - current time
2779f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2780f2cacb80SMatthew G. Knepley . Nc - the number of field components
2781f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2782f2cacb80SMatthew G. Knepley - ctx - a user context
2783f2cacb80SMatthew G. Knepley 
2784f2cacb80SMatthew G. Knepley   Level: intermediate
2785f2cacb80SMatthew G. Knepley 
2786dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2787f2cacb80SMatthew G. Knepley @*/
2788d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2789d71ae5a4SJacob Faibussowitsch {
2790f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2791f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
279263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27939566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27949371c9d4SSatish Balay   if (sol) {
27959371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27969371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
27979371c9d4SSatish Balay   }
27989371c9d4SSatish Balay   if (ctx) {
27999371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
28009371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
28019371c9d4SSatish Balay   }
28023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2803f2cacb80SMatthew G. Knepley }
2804f2cacb80SMatthew G. Knepley 
2805f2cacb80SMatthew G. Knepley /*@C
280697b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
280797b6e6e8SMatthew G. Knepley 
280820f4b53cSBarry Smith   Not Collective
280997b6e6e8SMatthew G. Knepley 
281097b6e6e8SMatthew G. Knepley   Input Parameter:
2811dce8aebaSBarry Smith . prob - The `PetscDS` object
281297b6e6e8SMatthew G. Knepley 
281397b6e6e8SMatthew G. Knepley   Output Parameters:
281497b6e6e8SMatthew G. Knepley + numConstants - The number of constants
281597b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
281697b6e6e8SMatthew G. Knepley 
281797b6e6e8SMatthew G. Knepley   Level: intermediate
281897b6e6e8SMatthew G. Knepley 
2819dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
282097b6e6e8SMatthew G. Knepley @*/
2821d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2822d71ae5a4SJacob Faibussowitsch {
282397b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
282497b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28259371c9d4SSatish Balay   if (numConstants) {
28269371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
28279371c9d4SSatish Balay     *numConstants = prob->numConstants;
28289371c9d4SSatish Balay   }
28299371c9d4SSatish Balay   if (constants) {
28309371c9d4SSatish Balay     PetscValidPointer(constants, 3);
28319371c9d4SSatish Balay     *constants = prob->constants;
28329371c9d4SSatish Balay   }
28333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
283497b6e6e8SMatthew G. Knepley }
283597b6e6e8SMatthew G. Knepley 
28360d3e9b51SMatthew G. Knepley /*@C
283797b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
283897b6e6e8SMatthew G. Knepley 
283920f4b53cSBarry Smith   Not Collective
284097b6e6e8SMatthew G. Knepley 
284197b6e6e8SMatthew G. Knepley   Input Parameters:
2842dce8aebaSBarry Smith + prob         - The `PetscDS` object
284397b6e6e8SMatthew G. Knepley . numConstants - The number of constants
284497b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
284597b6e6e8SMatthew G. Knepley 
284697b6e6e8SMatthew G. Knepley   Level: intermediate
284797b6e6e8SMatthew G. Knepley 
2848dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
284997b6e6e8SMatthew G. Knepley @*/
2850d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2851d71ae5a4SJacob Faibussowitsch {
285297b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
285397b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
285497b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28559566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
285697b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
285797b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28589566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
285920be0f5bSMatthew G. Knepley     } else {
286020be0f5bSMatthew G. Knepley       prob->constants = NULL;
286120be0f5bSMatthew G. Knepley     }
286220be0f5bSMatthew G. Knepley   }
286320be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2864dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
28659566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
286697b6e6e8SMatthew G. Knepley   }
28673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
286897b6e6e8SMatthew G. Knepley }
286997b6e6e8SMatthew G. Knepley 
28704cd1e086SMatthew G. Knepley /*@
28714cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28724cd1e086SMatthew G. Knepley 
287320f4b53cSBarry Smith   Not Collective
28744cd1e086SMatthew G. Knepley 
28754cd1e086SMatthew G. Knepley   Input Parameters:
2876dce8aebaSBarry Smith + prob - The `PetscDS` object
28774cd1e086SMatthew G. Knepley - disc - The discretization object
28784cd1e086SMatthew G. Knepley 
28794cd1e086SMatthew G. Knepley   Output Parameter:
28804cd1e086SMatthew G. Knepley . f - The field number
28814cd1e086SMatthew G. Knepley 
28824cd1e086SMatthew G. Knepley   Level: beginner
28834cd1e086SMatthew G. Knepley 
2884dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28854cd1e086SMatthew G. Knepley @*/
2886d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2887d71ae5a4SJacob Faibussowitsch {
28884cd1e086SMatthew G. Knepley   PetscInt g;
28894cd1e086SMatthew G. Knepley 
28904cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28914cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2892dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
28934cd1e086SMatthew G. Knepley   *f = -1;
28949371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
28959371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
28969371c9d4SSatish Balay   }
289708401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
28984cd1e086SMatthew G. Knepley   *f = g;
28993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29004cd1e086SMatthew G. Knepley }
29014cd1e086SMatthew G. Knepley 
29024cd1e086SMatthew G. Knepley /*@
29034cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
29044cd1e086SMatthew G. Knepley 
290520f4b53cSBarry Smith   Not Collective
29064cd1e086SMatthew G. Knepley 
29074cd1e086SMatthew G. Knepley   Input Parameters:
2908dce8aebaSBarry Smith + prob - The `PetscDS` object
29094cd1e086SMatthew G. Knepley - f - The field number
29104cd1e086SMatthew G. Knepley 
29114cd1e086SMatthew G. Knepley   Output Parameter:
29124cd1e086SMatthew G. Knepley . size - The size
29134cd1e086SMatthew G. Knepley 
29144cd1e086SMatthew G. Knepley   Level: beginner
29154cd1e086SMatthew G. Knepley 
2916dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29174cd1e086SMatthew G. Knepley @*/
2918d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2919d71ae5a4SJacob Faibussowitsch {
29204cd1e086SMatthew G. Knepley   PetscFunctionBegin;
29214cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2922dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
292363a3b9bcSJacob 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);
29249566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2925d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29274cd1e086SMatthew G. Knepley }
29284cd1e086SMatthew G. Knepley 
2929bc4ae4beSMatthew G. Knepley /*@
2930bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2931bc4ae4beSMatthew G. Knepley 
293220f4b53cSBarry Smith   Not Collective
2933bc4ae4beSMatthew G. Knepley 
2934bc4ae4beSMatthew G. Knepley   Input Parameters:
2935dce8aebaSBarry Smith + prob - The `PetscDS` object
2936bc4ae4beSMatthew G. Knepley - f - The field number
2937bc4ae4beSMatthew G. Knepley 
2938bc4ae4beSMatthew G. Knepley   Output Parameter:
2939bc4ae4beSMatthew G. Knepley . off - The offset
2940bc4ae4beSMatthew G. Knepley 
2941bc4ae4beSMatthew G. Knepley   Level: beginner
2942bc4ae4beSMatthew G. Knepley 
2943dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2944bc4ae4beSMatthew G. Knepley @*/
2945d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2946d71ae5a4SJacob Faibussowitsch {
29474cd1e086SMatthew G. Knepley   PetscInt size, g;
29482764a2aaSMatthew G. Knepley 
29492764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29502764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2951dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
295263a3b9bcSJacob 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);
29532764a2aaSMatthew G. Knepley   *off = 0;
29542764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29559566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29564cd1e086SMatthew G. Knepley     *off += size;
29572764a2aaSMatthew G. Knepley   }
29583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29592764a2aaSMatthew G. Knepley }
29602764a2aaSMatthew G. Knepley 
2961bc4ae4beSMatthew G. Knepley /*@
29625fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29635fedec97SMatthew G. Knepley 
296420f4b53cSBarry Smith   Not Collective
29655fedec97SMatthew G. Knepley 
29665fedec97SMatthew G. Knepley   Input Parameters:
2967dce8aebaSBarry Smith + prob - The `PetscDS` object
29685fedec97SMatthew G. Knepley - f - The field number
29695fedec97SMatthew G. Knepley 
29705fedec97SMatthew G. Knepley   Output Parameter:
29715fedec97SMatthew G. Knepley . off - The offset
29725fedec97SMatthew G. Knepley 
29735fedec97SMatthew G. Knepley   Level: beginner
29745fedec97SMatthew G. Knepley 
2975dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29765fedec97SMatthew G. Knepley @*/
2977d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2978d71ae5a4SJacob Faibussowitsch {
29795fedec97SMatthew G. Knepley   PetscInt size, g;
29805fedec97SMatthew G. Knepley 
29815fedec97SMatthew G. Knepley   PetscFunctionBegin;
29825fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2983dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
298463a3b9bcSJacob 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);
29855fedec97SMatthew G. Knepley   *off = 0;
29865fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29875fedec97SMatthew G. Knepley     PetscBool cohesive;
29885fedec97SMatthew G. Knepley 
29899566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29909566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29915fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29925fedec97SMatthew G. Knepley   }
29933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29945fedec97SMatthew G. Knepley }
29955fedec97SMatthew G. Knepley 
29965fedec97SMatthew G. Knepley /*@
299747e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2998bc4ae4beSMatthew G. Knepley 
299920f4b53cSBarry Smith   Not Collective
3000bc4ae4beSMatthew G. Knepley 
300147e57110SSander Arens   Input Parameter:
3002dce8aebaSBarry Smith . prob - The `PetscDS` object
3003bc4ae4beSMatthew G. Knepley 
3004bc4ae4beSMatthew G. Knepley   Output Parameter:
300547e57110SSander Arens . dimensions - The number of dimensions
3006bc4ae4beSMatthew G. Knepley 
3007bc4ae4beSMatthew G. Knepley   Level: beginner
3008bc4ae4beSMatthew G. Knepley 
3009dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3010bc4ae4beSMatthew G. Knepley @*/
3011d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
3012d71ae5a4SJacob Faibussowitsch {
30132764a2aaSMatthew G. Knepley   PetscFunctionBegin;
30142764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30159566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
301647e57110SSander Arens   PetscValidPointer(dimensions, 2);
301747e57110SSander Arens   *dimensions = prob->Nb;
30183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30196ce16762SMatthew G. Knepley }
302047e57110SSander Arens 
302147e57110SSander Arens /*@
302247e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
302347e57110SSander Arens 
302420f4b53cSBarry Smith   Not Collective
302547e57110SSander Arens 
302647e57110SSander Arens   Input Parameter:
3027dce8aebaSBarry Smith . prob - The `PetscDS` object
302847e57110SSander Arens 
302947e57110SSander Arens   Output Parameter:
303047e57110SSander Arens . components - The number of components
303147e57110SSander Arens 
303247e57110SSander Arens   Level: beginner
303347e57110SSander Arens 
3034dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
303547e57110SSander Arens @*/
3036d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3037d71ae5a4SJacob Faibussowitsch {
303847e57110SSander Arens   PetscFunctionBegin;
303947e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30409566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
304147e57110SSander Arens   PetscValidPointer(components, 2);
304247e57110SSander Arens   *components = prob->Nc;
30433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30446ce16762SMatthew G. Knepley }
30456ce16762SMatthew G. Knepley 
30466ce16762SMatthew G. Knepley /*@
30476ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30486ce16762SMatthew G. Knepley 
304920f4b53cSBarry Smith   Not Collective
30506ce16762SMatthew G. Knepley 
30516ce16762SMatthew G. Knepley   Input Parameters:
3052dce8aebaSBarry Smith + prob - The `PetscDS` object
30536ce16762SMatthew G. Knepley - f - The field number
30546ce16762SMatthew G. Knepley 
30556ce16762SMatthew G. Knepley   Output Parameter:
30566ce16762SMatthew G. Knepley . off - The offset
30576ce16762SMatthew G. Knepley 
30586ce16762SMatthew G. Knepley   Level: beginner
30596ce16762SMatthew G. Knepley 
3060dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30616ce16762SMatthew G. Knepley @*/
3062d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3063d71ae5a4SJacob Faibussowitsch {
30646ce16762SMatthew G. Knepley   PetscFunctionBegin;
30656ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3066dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
306763a3b9bcSJacob 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);
30689566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
306947e57110SSander Arens   *off = prob->off[f];
30703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30712764a2aaSMatthew G. Knepley }
30722764a2aaSMatthew G. Knepley 
3073194d53e6SMatthew G. Knepley /*@
3074194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3075194d53e6SMatthew G. Knepley 
307620f4b53cSBarry Smith   Not Collective
3077194d53e6SMatthew G. Knepley 
3078194d53e6SMatthew G. Knepley   Input Parameter:
3079dce8aebaSBarry Smith . prob - The `PetscDS` object
3080194d53e6SMatthew G. Knepley 
3081194d53e6SMatthew G. Knepley   Output Parameter:
3082194d53e6SMatthew G. Knepley . offsets - The offsets
3083194d53e6SMatthew G. Knepley 
3084194d53e6SMatthew G. Knepley   Level: beginner
3085194d53e6SMatthew G. Knepley 
3086dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3087194d53e6SMatthew G. Knepley @*/
3088d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3089d71ae5a4SJacob Faibussowitsch {
3090194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3091194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3092194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
30939566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3094194d53e6SMatthew G. Knepley   *offsets = prob->off;
30953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3096194d53e6SMatthew G. Knepley }
3097194d53e6SMatthew G. Knepley 
3098194d53e6SMatthew G. Knepley /*@
3099194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3100194d53e6SMatthew G. Knepley 
310120f4b53cSBarry Smith   Not Collective
3102194d53e6SMatthew G. Knepley 
3103194d53e6SMatthew G. Knepley   Input Parameter:
3104dce8aebaSBarry Smith . prob - The `PetscDS` object
3105194d53e6SMatthew G. Knepley 
3106194d53e6SMatthew G. Knepley   Output Parameter:
3107194d53e6SMatthew G. Knepley . offsets - The offsets
3108194d53e6SMatthew G. Knepley 
3109194d53e6SMatthew G. Knepley   Level: beginner
3110194d53e6SMatthew G. Knepley 
3111dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3112194d53e6SMatthew G. Knepley @*/
3113d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3114d71ae5a4SJacob Faibussowitsch {
3115194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3116194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3117194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
31189566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3119194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
31203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3121194d53e6SMatthew G. Knepley }
3122194d53e6SMatthew G. Knepley 
31239ee2af8cSMatthew G. Knepley /*@
31249ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31259ee2af8cSMatthew G. Knepley 
312620f4b53cSBarry Smith   Not Collective
31279ee2af8cSMatthew G. Knepley 
31289ee2af8cSMatthew G. Knepley   Input Parameters:
3129dce8aebaSBarry Smith + ds - The `PetscDS` object
31309ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31319ee2af8cSMatthew G. Knepley 
31329ee2af8cSMatthew G. Knepley   Output Parameter:
31339ee2af8cSMatthew G. Knepley . offsets - The offsets
31349ee2af8cSMatthew G. Knepley 
31359ee2af8cSMatthew G. Knepley   Level: beginner
31369ee2af8cSMatthew G. Knepley 
3137dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31389ee2af8cSMatthew G. Knepley @*/
3139d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3140d71ae5a4SJacob Faibussowitsch {
31419ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31429ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31439ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
314428b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
314563a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31469566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31479ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31499ee2af8cSMatthew G. Knepley }
31509ee2af8cSMatthew G. Knepley 
31519ee2af8cSMatthew G. Knepley /*@
31529ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31539ee2af8cSMatthew G. Knepley 
315420f4b53cSBarry Smith   Not Collective
31559ee2af8cSMatthew G. Knepley 
31569ee2af8cSMatthew G. Knepley   Input Parameters:
3157dce8aebaSBarry Smith + ds - The `PetscDS` object
31589ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31599ee2af8cSMatthew G. Knepley 
31609ee2af8cSMatthew G. Knepley   Output Parameter:
31619ee2af8cSMatthew G. Knepley . offsets - The offsets
31629ee2af8cSMatthew G. Knepley 
31639ee2af8cSMatthew G. Knepley   Level: beginner
31649ee2af8cSMatthew G. Knepley 
3165dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31669ee2af8cSMatthew G. Knepley @*/
3167d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3168d71ae5a4SJacob Faibussowitsch {
31699ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31709ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31719ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
317228b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
317363a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31749566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31759ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31779ee2af8cSMatthew G. Knepley }
31789ee2af8cSMatthew G. Knepley 
317968c9edb9SMatthew G. Knepley /*@C
318068c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
318168c9edb9SMatthew G. Knepley 
318220f4b53cSBarry Smith   Not Collective
318368c9edb9SMatthew G. Knepley 
318468c9edb9SMatthew G. Knepley   Input Parameter:
3185dce8aebaSBarry Smith . prob - The `PetscDS` object
318668c9edb9SMatthew G. Knepley 
3187ef0bb6c7SMatthew G. Knepley   Output Parameter:
3188ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
318968c9edb9SMatthew G. Knepley 
319068c9edb9SMatthew G. Knepley   Level: intermediate
319168c9edb9SMatthew G. Knepley 
3192dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
319368c9edb9SMatthew G. Knepley @*/
3194d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3195d71ae5a4SJacob Faibussowitsch {
31962764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31972764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3198ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
31999566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3200ef0bb6c7SMatthew G. Knepley   *T = prob->T;
32013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32022764a2aaSMatthew G. Knepley }
32032764a2aaSMatthew G. Knepley 
320468c9edb9SMatthew G. Knepley /*@C
32054d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
320668c9edb9SMatthew G. Knepley 
320720f4b53cSBarry Smith   Not Collective
320868c9edb9SMatthew G. Knepley 
320968c9edb9SMatthew G. Knepley   Input Parameter:
3210dce8aebaSBarry Smith . prob - The `PetscDS` object
321168c9edb9SMatthew G. Knepley 
3212ef0bb6c7SMatthew G. Knepley   Output Parameter:
3213a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
321468c9edb9SMatthew G. Knepley 
321568c9edb9SMatthew G. Knepley   Level: intermediate
321668c9edb9SMatthew G. Knepley 
3217dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
321868c9edb9SMatthew G. Knepley @*/
3219d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3220d71ae5a4SJacob Faibussowitsch {
32212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32222764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3223ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
32249566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3225ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32272764a2aaSMatthew G. Knepley }
32282764a2aaSMatthew G. Knepley 
3229d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3230d71ae5a4SJacob Faibussowitsch {
32312764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32322764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32339566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32349371c9d4SSatish Balay   if (u) {
32359371c9d4SSatish Balay     PetscValidPointer(u, 2);
32369371c9d4SSatish Balay     *u = prob->u;
32379371c9d4SSatish Balay   }
32389371c9d4SSatish Balay   if (u_t) {
32399371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
32409371c9d4SSatish Balay     *u_t = prob->u_t;
32419371c9d4SSatish Balay   }
32429371c9d4SSatish Balay   if (u_x) {
32439371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
32449371c9d4SSatish Balay     *u_x = prob->u_x;
32459371c9d4SSatish Balay   }
32463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32472764a2aaSMatthew G. Knepley }
32482764a2aaSMatthew G. Knepley 
3249d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3250d71ae5a4SJacob Faibussowitsch {
32512764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32522764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32539566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32549371c9d4SSatish Balay   if (f0) {
32559371c9d4SSatish Balay     PetscValidPointer(f0, 2);
32569371c9d4SSatish Balay     *f0 = prob->f0;
32579371c9d4SSatish Balay   }
32589371c9d4SSatish Balay   if (f1) {
32599371c9d4SSatish Balay     PetscValidPointer(f1, 3);
32609371c9d4SSatish Balay     *f1 = prob->f1;
32619371c9d4SSatish Balay   }
32629371c9d4SSatish Balay   if (g0) {
32639371c9d4SSatish Balay     PetscValidPointer(g0, 4);
32649371c9d4SSatish Balay     *g0 = prob->g0;
32659371c9d4SSatish Balay   }
32669371c9d4SSatish Balay   if (g1) {
32679371c9d4SSatish Balay     PetscValidPointer(g1, 5);
32689371c9d4SSatish Balay     *g1 = prob->g1;
32699371c9d4SSatish Balay   }
32709371c9d4SSatish Balay   if (g2) {
32719371c9d4SSatish Balay     PetscValidPointer(g2, 6);
32729371c9d4SSatish Balay     *g2 = prob->g2;
32739371c9d4SSatish Balay   }
32749371c9d4SSatish Balay   if (g3) {
32759371c9d4SSatish Balay     PetscValidPointer(g3, 7);
32769371c9d4SSatish Balay     *g3 = prob->g3;
32779371c9d4SSatish Balay   }
32783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32792764a2aaSMatthew G. Knepley }
32802764a2aaSMatthew G. Knepley 
3281d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3282d71ae5a4SJacob Faibussowitsch {
32832764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32842764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32859566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32869371c9d4SSatish Balay   if (x) {
32879371c9d4SSatish Balay     PetscValidPointer(x, 2);
32889371c9d4SSatish Balay     *x = prob->x;
32899371c9d4SSatish Balay   }
32909371c9d4SSatish Balay   if (basisReal) {
32919371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
32929371c9d4SSatish Balay     *basisReal = prob->basisReal;
32939371c9d4SSatish Balay   }
32949371c9d4SSatish Balay   if (basisDerReal) {
32959371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
32969371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
32979371c9d4SSatish Balay   }
32989371c9d4SSatish Balay   if (testReal) {
32999371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
33009371c9d4SSatish Balay     *testReal = prob->testReal;
33019371c9d4SSatish Balay   }
33029371c9d4SSatish Balay   if (testDerReal) {
33039371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
33049371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
33059371c9d4SSatish Balay   }
33063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33072764a2aaSMatthew G. Knepley }
33082764a2aaSMatthew G. Knepley 
330958ebd649SToby Isaac /*@C
3310dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3311dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary
3312dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
331358ebd649SToby Isaac 
331420f4b53cSBarry Smith   Collective
3315783e2ec8SMatthew G. Knepley 
331658ebd649SToby Isaac   Input Parameters:
331758ebd649SToby Isaac + ds       - The PetscDS object
3318dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
331958ebd649SToby Isaac . name     - The BC name
332045480ffeSMatthew G. Knepley . label    - The label defining constrained points
3321dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
332245480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
332358ebd649SToby Isaac . field    - The field to constrain
332445480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
332558ebd649SToby Isaac . comps    - An array of constrained component numbers
332658ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3327a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
332858ebd649SToby Isaac - ctx      - An optional user context for bcFunc
332958ebd649SToby Isaac 
33302fe279fdSBarry Smith   Output Parameter:
333145480ffeSMatthew G. Knepley - bd       - The boundary number
333245480ffeSMatthew G. Knepley 
333358ebd649SToby Isaac   Options Database Keys:
333458ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
333558ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
333658ebd649SToby Isaac 
3337dce8aebaSBarry Smith   Level: developer
3338dce8aebaSBarry Smith 
333956cf3b9cSMatthew G. Knepley   Note:
334020f4b53cSBarry Smith   Both `bcFunc` and `bcFunc_t` will depend on the boundary condition type. If the type if `DM_BC_ESSENTIAL`, Then the calling sequence is:
334156cf3b9cSMatthew G. Knepley 
334220f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
334356cf3b9cSMatthew G. Knepley 
3344dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3345dce8aebaSBarry Smith .vb
334620f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3347dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3348dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3349dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3350dce8aebaSBarry Smith .ve
335156cf3b9cSMatthew G. Knepley + dim - the spatial dimension
335256cf3b9cSMatthew G. Knepley . Nf - the number of fields
335356cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
335456cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
335556cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
335656cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
335756cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
335856cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
335956cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
336056cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
336156cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
336256cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
336356cf3b9cSMatthew G. Knepley . t - current time
336456cf3b9cSMatthew G. Knepley . x - coordinates of the current point
336556cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
336656cf3b9cSMatthew G. Knepley . constants - constant parameters
336756cf3b9cSMatthew G. Knepley - bcval - output values at the current point
336856cf3b9cSMatthew G. Knepley 
3369dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
337058ebd649SToby Isaac @*/
3371d71ae5a4SJacob 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)
3372d71ae5a4SJacob Faibussowitsch {
337345480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
337445480ffeSMatthew G. Knepley   PetscInt    n    = 0;
337545480ffeSMatthew G. Knepley   const char *lname;
337658ebd649SToby Isaac 
337758ebd649SToby Isaac   PetscFunctionBegin;
337858ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3379783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
338045480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
338145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
338245480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
338345480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
338445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3385dce9da9cSMatthew 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);
3386d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3387d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3388d57bb9dbSMatthew G. Knepley     PetscInt  c;
3389d57bb9dbSMatthew G. Knepley 
33909566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
339163a3b9bcSJacob 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);
3392d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
33931dca8a05SBarry 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);
3394d57bb9dbSMatthew G. Knepley     }
3395d57bb9dbSMatthew G. Knepley   }
33969566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33989566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33999566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34009566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34019566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34029566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34039566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34049566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
34059566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3406f971fd6bSMatthew G. Knepley   b->type   = type;
340745480ffeSMatthew G. Knepley   b->label  = label;
340845480ffeSMatthew G. Knepley   b->Nv     = Nv;
340958ebd649SToby Isaac   b->field  = field;
341045480ffeSMatthew G. Knepley   b->Nc     = Nc;
341158ebd649SToby Isaac   b->func   = bcFunc;
341256cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
341358ebd649SToby Isaac   b->ctx    = ctx;
341445480ffeSMatthew G. Knepley   b->next   = NULL;
341545480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
341645480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
341745480ffeSMatthew G. Knepley   while (head) {
341845480ffeSMatthew G. Knepley     if (!head->next) {
341945480ffeSMatthew G. Knepley       head->next = b;
342045480ffeSMatthew G. Knepley       head       = b;
342145480ffeSMatthew G. Knepley     }
342245480ffeSMatthew G. Knepley     head = head->next;
342345480ffeSMatthew G. Knepley     ++n;
342445480ffeSMatthew G. Knepley   }
34259371c9d4SSatish Balay   if (bd) {
34269371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
34279371c9d4SSatish Balay     *bd = n;
34289371c9d4SSatish Balay   }
34293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
343045480ffeSMatthew G. Knepley }
343145480ffeSMatthew G. Knepley 
343245480ffeSMatthew G. Knepley /*@C
3433dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3434dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that
3435dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
343645480ffeSMatthew G. Knepley 
343720f4b53cSBarry Smith   Collective
343845480ffeSMatthew G. Knepley 
343945480ffeSMatthew G. Knepley   Input Parameters:
3440dce8aebaSBarry Smith + ds       - The `PetscDS` object
3441dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
344245480ffeSMatthew G. Knepley . name     - The BC name
344345480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3444dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
344545480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
344645480ffeSMatthew G. Knepley . field    - The field to constrain
344745480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
344845480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
344945480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3450a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
345145480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
345245480ffeSMatthew G. Knepley 
34532fe279fdSBarry Smith   Output Parameter:
345445480ffeSMatthew G. Knepley - bd       - The boundary number
345545480ffeSMatthew G. Knepley 
345645480ffeSMatthew G. Knepley   Options Database Keys:
345745480ffeSMatthew G. Knepley + -bc_<boundary name> <num> - Overrides the boundary ids
345845480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
345945480ffeSMatthew G. Knepley 
346020f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3461dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3462dce8aebaSBarry Smith .vb
346320f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3464dce8aebaSBarry Smith .ve
3465dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3466dce8aebaSBarry Smith .vb
346720f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3468dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3469dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3470dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3471dce8aebaSBarry Smith .ve
347245480ffeSMatthew G. Knepley + dim - the spatial dimension
347345480ffeSMatthew G. Knepley . Nf - the number of fields
347445480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
347545480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
347645480ffeSMatthew G. Knepley . u - each field evaluated at the current point
347745480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
347845480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
347945480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
348045480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
348145480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
348245480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
348345480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
348445480ffeSMatthew G. Knepley . t - current time
348545480ffeSMatthew G. Knepley . x - coordinates of the current point
348645480ffeSMatthew G. Knepley . numConstants - number of constant parameters
348745480ffeSMatthew G. Knepley . constants - constant parameters
348845480ffeSMatthew G. Knepley - bcval - output values at the current point
348945480ffeSMatthew G. Knepley 
349045480ffeSMatthew G. Knepley   Level: developer
349145480ffeSMatthew G. Knepley 
3492dce8aebaSBarry Smith   Note:
3493dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3494dce8aebaSBarry Smith 
3495dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
349645480ffeSMatthew G. Knepley @*/
3497d71ae5a4SJacob 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)
3498d71ae5a4SJacob Faibussowitsch {
349945480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
350045480ffeSMatthew G. Knepley   PetscInt   n    = 0;
350145480ffeSMatthew G. Knepley 
350245480ffeSMatthew G. Knepley   PetscFunctionBegin;
350345480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
350445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
350545480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
350645480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
350745480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
350845480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
350945480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
35109566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
35119566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
35129566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
35139566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
35149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
35159566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
35169566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
35179566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
35189566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
351945480ffeSMatthew G. Knepley   b->type   = type;
352045480ffeSMatthew G. Knepley   b->label  = NULL;
352145480ffeSMatthew G. Knepley   b->Nv     = Nv;
352245480ffeSMatthew G. Knepley   b->field  = field;
352345480ffeSMatthew G. Knepley   b->Nc     = Nc;
352445480ffeSMatthew G. Knepley   b->func   = bcFunc;
352545480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
352645480ffeSMatthew G. Knepley   b->ctx    = ctx;
352745480ffeSMatthew G. Knepley   b->next   = NULL;
352845480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
352945480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
353045480ffeSMatthew G. Knepley   while (head) {
353145480ffeSMatthew G. Knepley     if (!head->next) {
353245480ffeSMatthew G. Knepley       head->next = b;
353345480ffeSMatthew G. Knepley       head       = b;
353445480ffeSMatthew G. Knepley     }
353545480ffeSMatthew G. Knepley     head = head->next;
353645480ffeSMatthew G. Knepley     ++n;
353745480ffeSMatthew G. Knepley   }
35389371c9d4SSatish Balay   if (bd) {
35399371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
35409371c9d4SSatish Balay     *bd = n;
35419371c9d4SSatish Balay   }
35423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
354358ebd649SToby Isaac }
354458ebd649SToby Isaac 
3545b67eacb3SMatthew G. Knepley /*@C
3546dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3547dce8aebaSBarry Smith   In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals
3548dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3549b67eacb3SMatthew G. Knepley 
3550b67eacb3SMatthew G. Knepley   Input Parameters:
3551dce8aebaSBarry Smith + ds       - The `PetscDS` object
3552b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3553dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3554b67eacb3SMatthew G. Knepley . name     - The BC name
355545480ffeSMatthew G. Knepley . label    - The label defining constrained points
3556dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
355745480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3558b67eacb3SMatthew G. Knepley . field    - The field to constrain
355945480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3560b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3561b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3562a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3563b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3564b67eacb3SMatthew G. Knepley 
3565b67eacb3SMatthew G. Knepley   Level: developer
3566b67eacb3SMatthew G. Knepley 
3567dce8aebaSBarry Smith   Note:
3568dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3569dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3570dce8aebaSBarry Smith 
3571dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3572b67eacb3SMatthew G. Knepley @*/
3573d71ae5a4SJacob 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)
3574d71ae5a4SJacob Faibussowitsch {
3575b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3576b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3577b67eacb3SMatthew G. Knepley 
3578b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3579b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3580b67eacb3SMatthew G. Knepley   while (b) {
3581b67eacb3SMatthew G. Knepley     if (n == bd) break;
3582b67eacb3SMatthew G. Knepley     b = b->next;
3583b67eacb3SMatthew G. Knepley     ++n;
3584b67eacb3SMatthew G. Knepley   }
358563a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3586b67eacb3SMatthew G. Knepley   if (name) {
35879566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
35889566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3589b67eacb3SMatthew G. Knepley   }
3590b67eacb3SMatthew G. Knepley   b->type = type;
359145480ffeSMatthew G. Knepley   if (label) {
359245480ffeSMatthew G. Knepley     const char *name;
359345480ffeSMatthew G. Knepley 
359445480ffeSMatthew G. Knepley     b->label = label;
35959566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
35969566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
35979566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
359845480ffeSMatthew G. Knepley   }
359945480ffeSMatthew G. Knepley   if (Nv >= 0) {
360045480ffeSMatthew G. Knepley     b->Nv = Nv;
36019566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
36029566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
36039566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
360445480ffeSMatthew G. Knepley   }
360545480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
360645480ffeSMatthew G. Knepley   if (Nc >= 0) {
360745480ffeSMatthew G. Knepley     b->Nc = Nc;
36089566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
36099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
36109566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
361145480ffeSMatthew G. Knepley   }
361245480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
361345480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
361445480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
36153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3616b67eacb3SMatthew G. Knepley }
3617b67eacb3SMatthew G. Knepley 
361858ebd649SToby Isaac /*@
361958ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
362058ebd649SToby Isaac 
36212fe279fdSBarry Smith   Input Parameter:
3622dce8aebaSBarry Smith . ds - The `PetscDS` object
362358ebd649SToby Isaac 
36242fe279fdSBarry Smith   Output Parameter:
362558ebd649SToby Isaac . numBd - The number of BC
362658ebd649SToby Isaac 
362758ebd649SToby Isaac   Level: intermediate
362858ebd649SToby Isaac 
3629dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
363058ebd649SToby Isaac @*/
3631d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3632d71ae5a4SJacob Faibussowitsch {
363358ebd649SToby Isaac   DSBoundary b = ds->boundary;
363458ebd649SToby Isaac 
363558ebd649SToby Isaac   PetscFunctionBegin;
363658ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3637dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
363858ebd649SToby Isaac   *numBd = 0;
36399371c9d4SSatish Balay   while (b) {
36409371c9d4SSatish Balay     ++(*numBd);
36419371c9d4SSatish Balay     b = b->next;
36429371c9d4SSatish Balay   }
36433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
364458ebd649SToby Isaac }
364558ebd649SToby Isaac 
364658ebd649SToby Isaac /*@C
36479a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
364858ebd649SToby Isaac 
364958ebd649SToby Isaac   Input Parameters:
3650dce8aebaSBarry Smith + ds          - The `PetscDS` object
365158ebd649SToby Isaac - bd          - The BC number
365258ebd649SToby Isaac 
365358ebd649SToby Isaac   Output Parameters:
3654dce8aebaSBarry Smith + wf       - The `PetscWeakForm` holding the pointwise functions
3655dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
365658ebd649SToby Isaac . name     - The BC name
365745480ffeSMatthew G. Knepley . label    - The label defining constrained points
3658dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
365945480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
366058ebd649SToby Isaac . field    - The field to constrain
366145480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
366258ebd649SToby Isaac . comps    - An array of constrained component numbers
366358ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3664a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values
366558ebd649SToby Isaac - ctx      - An optional user context for bcFunc
366658ebd649SToby Isaac 
366758ebd649SToby Isaac   Options Database Keys:
366858ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
366958ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
367058ebd649SToby Isaac 
367158ebd649SToby Isaac   Level: developer
367258ebd649SToby Isaac 
3673dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
367458ebd649SToby Isaac @*/
3675d71ae5a4SJacob 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)
3676d71ae5a4SJacob Faibussowitsch {
367758ebd649SToby Isaac   DSBoundary b = ds->boundary;
367858ebd649SToby Isaac   PetscInt   n = 0;
367958ebd649SToby Isaac 
368058ebd649SToby Isaac   PetscFunctionBegin;
368158ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
368258ebd649SToby Isaac   while (b) {
368358ebd649SToby Isaac     if (n == bd) break;
368458ebd649SToby Isaac     b = b->next;
368558ebd649SToby Isaac     ++n;
368658ebd649SToby Isaac   }
368763a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
368845480ffeSMatthew G. Knepley   if (wf) {
368945480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
369045480ffeSMatthew G. Knepley     *wf = b->wf;
369145480ffeSMatthew G. Knepley   }
3692f971fd6bSMatthew G. Knepley   if (type) {
369345480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3694f971fd6bSMatthew G. Knepley     *type = b->type;
369558ebd649SToby Isaac   }
369658ebd649SToby Isaac   if (name) {
369745480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
369858ebd649SToby Isaac     *name = b->name;
369958ebd649SToby Isaac   }
370045480ffeSMatthew G. Knepley   if (label) {
370145480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
370245480ffeSMatthew G. Knepley     *label = b->label;
370345480ffeSMatthew G. Knepley   }
370445480ffeSMatthew G. Knepley   if (Nv) {
370545480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
370645480ffeSMatthew G. Knepley     *Nv = b->Nv;
370745480ffeSMatthew G. Knepley   }
370845480ffeSMatthew G. Knepley   if (values) {
370945480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
371045480ffeSMatthew G. Knepley     *values = b->values;
371158ebd649SToby Isaac   }
371258ebd649SToby Isaac   if (field) {
371345480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
371458ebd649SToby Isaac     *field = b->field;
371558ebd649SToby Isaac   }
371645480ffeSMatthew G. Knepley   if (Nc) {
371745480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
371845480ffeSMatthew G. Knepley     *Nc = b->Nc;
371958ebd649SToby Isaac   }
372058ebd649SToby Isaac   if (comps) {
372145480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
372258ebd649SToby Isaac     *comps = b->comps;
372358ebd649SToby Isaac   }
372458ebd649SToby Isaac   if (func) {
372545480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
372658ebd649SToby Isaac     *func = b->func;
372758ebd649SToby Isaac   }
372856cf3b9cSMatthew G. Knepley   if (func_t) {
372945480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
373056cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
373156cf3b9cSMatthew G. Knepley   }
373258ebd649SToby Isaac   if (ctx) {
373345480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
373458ebd649SToby Isaac     *ctx = b->ctx;
373558ebd649SToby Isaac   }
37363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
373758ebd649SToby Isaac }
373858ebd649SToby Isaac 
3739d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3740d71ae5a4SJacob Faibussowitsch {
374145480ffeSMatthew G. Knepley   PetscFunctionBegin;
37429566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37439566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37449566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37459566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37469566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
374745480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
374845480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
374945480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37509566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37519566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
375245480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
375345480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37549566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37559566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
375645480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
375745480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
375845480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
37593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
376045480ffeSMatthew G. Knepley }
376145480ffeSMatthew G. Knepley 
37629252d075SMatthew G. Knepley /*@
37639252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
37649252d075SMatthew G. Knepley 
376520f4b53cSBarry Smith   Not Collective
37669252d075SMatthew G. Knepley 
376736951cb5SMatthew G. Knepley   Input Parameters:
3768dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3769dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
377036951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
37719252d075SMatthew G. Knepley 
37729252d075SMatthew G. Knepley   Output Parameter:
3773dce8aebaSBarry Smith . newds     - The target `PetscDS`, now with a copy of the boundary conditions
37749252d075SMatthew G. Knepley 
37759252d075SMatthew G. Knepley   Level: intermediate
37769252d075SMatthew G. Knepley 
3777dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37789252d075SMatthew G. Knepley @*/
3779d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3780d71ae5a4SJacob Faibussowitsch {
378145480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3782dff059c6SToby Isaac 
3783dff059c6SToby Isaac   PetscFunctionBegin;
378436951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
378536951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
37863ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
37879566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
378836951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
378936951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3790dff059c6SToby Isaac     DSBoundary bNew;
379136951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3792dff059c6SToby Isaac 
379336951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
379436951cb5SMatthew G. Knepley       PetscInt f;
379536951cb5SMatthew G. Knepley 
37969371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
37979371c9d4SSatish Balay         if (b->field == fields[f]) break;
379836951cb5SMatthew G. Knepley       if (f == numFields) continue;
379936951cb5SMatthew G. Knepley       fieldNew = f;
380036951cb5SMatthew G. Knepley     }
38019566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
380236951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3803dff059c6SToby Isaac     *lastnext   = bNew;
3804dff059c6SToby Isaac     lastnext    = &(bNew->next);
3805dff059c6SToby Isaac   }
38063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3807dff059c6SToby Isaac }
3808dff059c6SToby Isaac 
38096c1eb96dSMatthew G. Knepley /*@
3810dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
381145480ffeSMatthew G. Knepley 
381220f4b53cSBarry Smith   Not Collective
381345480ffeSMatthew G. Knepley 
381445480ffeSMatthew G. Knepley   Input Parameter:
3815dce8aebaSBarry Smith . ds - The `PetscDS` object
381645480ffeSMatthew G. Knepley 
381745480ffeSMatthew G. Knepley   Level: intermediate
381845480ffeSMatthew G. Knepley 
3819dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
382045480ffeSMatthew G. Knepley @*/
3821d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3822d71ae5a4SJacob Faibussowitsch {
382345480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
382445480ffeSMatthew G. Knepley 
382545480ffeSMatthew G. Knepley   PetscFunctionBegin;
382645480ffeSMatthew G. Knepley   while (next) {
382745480ffeSMatthew G. Knepley     DSBoundary b = next;
382845480ffeSMatthew G. Knepley 
382945480ffeSMatthew G. Knepley     next = b->next;
38309566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38319566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38329566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38339566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38349566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38359566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
383645480ffeSMatthew G. Knepley   }
38373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
383845480ffeSMatthew G. Knepley }
383945480ffeSMatthew G. Knepley 
384045480ffeSMatthew G. Knepley /*@
38416c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38426c1eb96dSMatthew G. Knepley 
384320f4b53cSBarry Smith   Not Collective
38446c1eb96dSMatthew G. Knepley 
3845d8d19677SJose E. Roman   Input Parameters:
3846dce8aebaSBarry Smith + prob - The `PetscDS` object
38476c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38486c1eb96dSMatthew G. Knepley - fields - Old field number for each new field
38496c1eb96dSMatthew G. Knepley 
38506c1eb96dSMatthew G. Knepley   Output Parameter:
3851dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38526c1eb96dSMatthew G. Knepley 
38536c1eb96dSMatthew G. Knepley   Level: intermediate
38546c1eb96dSMatthew G. Knepley 
3855dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38566c1eb96dSMatthew G. Knepley @*/
3857d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3858d71ae5a4SJacob Faibussowitsch {
38596c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
38606c1eb96dSMatthew G. Knepley 
38616c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
38626c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3863dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38646c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38669566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
386745480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
38686c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38696c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
38706c1eb96dSMatthew G. Knepley     PetscObject    disc;
38716c1eb96dSMatthew G. Knepley 
38726c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
38739566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
38749566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
38756c1eb96dSMatthew G. Knepley   }
38763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38776c1eb96dSMatthew G. Knepley }
38786c1eb96dSMatthew G. Knepley 
38796c1eb96dSMatthew G. Knepley /*@
38809252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
38819252d075SMatthew G. Knepley 
388220f4b53cSBarry Smith   Not Collective
38839252d075SMatthew G. Knepley 
3884d8d19677SJose E. Roman   Input Parameters:
3885dce8aebaSBarry Smith + prob - The `PetscDS` object
38869252d075SMatthew G. Knepley . numFields - Number of new fields
38879252d075SMatthew G. Knepley - fields - Old field number for each new field
38889252d075SMatthew G. Knepley 
38899252d075SMatthew G. Knepley   Output Parameter:
3890dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38919252d075SMatthew G. Knepley 
38929252d075SMatthew G. Knepley   Level: intermediate
38939252d075SMatthew G. Knepley 
3894dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38959252d075SMatthew G. Knepley @*/
3896d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3897d71ae5a4SJacob Faibussowitsch {
38989252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
38999252d075SMatthew G. Knepley 
39009252d075SMatthew G. Knepley   PetscFunctionBegin;
39019252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3902dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
39039252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
39049566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39059566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
390663a3b9bcSJacob 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);
39079252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
39089252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
39099252d075SMatthew G. Knepley     PetscPointFunc   obj;
39109252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
39119252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
39129252d075SMatthew G. Knepley     PetscRiemannFunc r;
39139252d075SMatthew G. Knepley 
3914c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
39159566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
39169566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
39179566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
39189566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
39199566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
39209566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
39219566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
39229566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39239252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39249252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39259252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39269252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39279252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39289252d075SMatthew G. Knepley 
3929c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39309566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39319566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39329566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39339566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39349566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39359566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39369252d075SMatthew G. Knepley     }
39379252d075SMatthew G. Knepley   }
39383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39399252d075SMatthew G. Knepley }
39409252d075SMatthew G. Knepley 
3941da51fcedSMatthew G. Knepley /*@
3942dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3943da51fcedSMatthew G. Knepley 
394420f4b53cSBarry Smith   Not Collective
3945da51fcedSMatthew G. Knepley 
3946da51fcedSMatthew G. Knepley   Input Parameter:
3947dce8aebaSBarry Smith . prob - The `PetscDS` object
3948da51fcedSMatthew G. Knepley 
3949da51fcedSMatthew G. Knepley   Output Parameter:
3950dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3951da51fcedSMatthew G. Knepley 
3952da51fcedSMatthew G. Knepley   Level: intermediate
3953da51fcedSMatthew G. Knepley 
3954dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3955da51fcedSMatthew G. Knepley @*/
3956d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3957d71ae5a4SJacob Faibussowitsch {
3958b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
39599252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3960da51fcedSMatthew G. Knepley 
3961da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3962da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3963da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39649566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39659566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
396663a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
39679566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
39689566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
39699566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
39703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39719252d075SMatthew G. Knepley }
397245480ffeSMatthew G. Knepley 
39739252d075SMatthew G. Knepley /*@
3974dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
3975da51fcedSMatthew G. Knepley 
397620f4b53cSBarry Smith   Not Collective
39779252d075SMatthew G. Knepley 
39789252d075SMatthew G. Knepley   Input Parameter:
3979dce8aebaSBarry Smith . prob - The `PetscDS` object
39809252d075SMatthew G. Knepley 
39819252d075SMatthew G. Knepley   Output Parameter:
3982dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39839252d075SMatthew G. Knepley 
39849252d075SMatthew G. Knepley   Level: intermediate
39859252d075SMatthew G. Knepley 
3986dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39879252d075SMatthew G. Knepley @*/
3988d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3989d71ae5a4SJacob Faibussowitsch {
39909252d075SMatthew G. Knepley   PetscInt           Nc;
39919252d075SMatthew G. Knepley   const PetscScalar *constants;
39929252d075SMatthew G. Knepley 
39939252d075SMatthew G. Knepley   PetscFunctionBegin;
39949252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39959252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39969566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
39979566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
39983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3999da51fcedSMatthew G. Knepley }
4000da51fcedSMatthew G. Knepley 
400145480ffeSMatthew G. Knepley /*@
4002dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
400345480ffeSMatthew G. Knepley 
400420f4b53cSBarry Smith   Not Collective
400545480ffeSMatthew G. Knepley 
400645480ffeSMatthew G. Knepley   Input Parameter:
4007dce8aebaSBarry Smith . ds - The `PetscDS` object
400845480ffeSMatthew G. Knepley 
400945480ffeSMatthew G. Knepley   Output Parameter:
4010dce8aebaSBarry Smith . newds - The `PetscDS` copy
401145480ffeSMatthew G. Knepley 
401245480ffeSMatthew G. Knepley   Level: intermediate
401345480ffeSMatthew G. Knepley 
4014dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
401545480ffeSMatthew G. Knepley @*/
4016d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
4017d71ae5a4SJacob Faibussowitsch {
401845480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
401945480ffeSMatthew G. Knepley   void                *ctx;
402045480ffeSMatthew G. Knepley   PetscInt             Nf, f;
402145480ffeSMatthew G. Knepley 
402245480ffeSMatthew G. Knepley   PetscFunctionBegin;
402345480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
402445480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40259566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
402645480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40279566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40289566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40299566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40309566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
403145480ffeSMatthew G. Knepley   }
40323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
403345480ffeSMatthew G. Knepley }
403445480ffeSMatthew G. Knepley 
403507218a29SMatthew G. Knepley PetscErrorCode PetscDSCopy(PetscDS ds, DM dmNew, PetscDS dsNew)
403607218a29SMatthew G. Knepley {
403707218a29SMatthew G. Knepley   DSBoundary b;
403807218a29SMatthew G. Knepley   PetscInt   cdim, Nf, f, d;
403907218a29SMatthew G. Knepley   PetscBool  isCohesive;
404007218a29SMatthew G. Knepley   void      *ctx;
404107218a29SMatthew G. Knepley 
404207218a29SMatthew G. Knepley   PetscFunctionBegin;
404307218a29SMatthew G. Knepley   PetscCall(PetscDSCopyConstants(ds, dsNew));
404407218a29SMatthew G. Knepley   PetscCall(PetscDSCopyExactSolutions(ds, dsNew));
404507218a29SMatthew G. Knepley   PetscCall(PetscDSSelectDiscretizations(ds, PETSC_DETERMINE, NULL, dsNew));
404607218a29SMatthew G. Knepley   PetscCall(PetscDSCopyEquations(ds, dsNew));
404707218a29SMatthew G. Knepley   PetscCall(PetscDSGetNumFields(ds, &Nf));
404807218a29SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
404907218a29SMatthew G. Knepley     PetscCall(PetscDSGetContext(ds, f, &ctx));
405007218a29SMatthew G. Knepley     PetscCall(PetscDSSetContext(dsNew, f, ctx));
405107218a29SMatthew G. Knepley     PetscCall(PetscDSGetCohesive(ds, f, &isCohesive));
405207218a29SMatthew G. Knepley     PetscCall(PetscDSSetCohesive(dsNew, f, isCohesive));
405307218a29SMatthew G. Knepley     PetscCall(PetscDSGetJetDegree(ds, f, &d));
405407218a29SMatthew G. Knepley     PetscCall(PetscDSSetJetDegree(dsNew, f, d));
405507218a29SMatthew G. Knepley   }
405607218a29SMatthew G. Knepley   if (Nf) {
405707218a29SMatthew G. Knepley     PetscCall(PetscDSGetCoordinateDimension(ds, &cdim));
405807218a29SMatthew G. Knepley     PetscCall(PetscDSSetCoordinateDimension(dsNew, cdim));
405907218a29SMatthew G. Knepley   }
406007218a29SMatthew G. Knepley   PetscCall(PetscDSCopyBoundary(ds, PETSC_DETERMINE, NULL, dsNew));
406107218a29SMatthew G. Knepley   for (b = dsNew->boundary; b; b = b->next) {
406207218a29SMatthew G. Knepley     PetscCall(DMGetLabel(dmNew, b->lname, &b->label));
406307218a29SMatthew G. Knepley     /* Do not check if label exists here, since p4est calls this for the reference tree which does not have the labels */
406407218a29SMatthew G. Knepley     //PetscCheck(b->label,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Label %s missing in new DM", name);
406507218a29SMatthew G. Knepley   }
406607218a29SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
406707218a29SMatthew G. Knepley }
406807218a29SMatthew G. Knepley 
4069d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4070d71ae5a4SJacob Faibussowitsch {
4071df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4072b1353e8eSMatthew G. Knepley 
4073b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4074b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4075b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
40769371c9d4SSatish Balay   if (height == 0) {
40779371c9d4SSatish Balay     *subprob = prob;
40783ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
40799371c9d4SSatish Balay   }
40809566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40819566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
408263a3b9bcSJacob 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);
40839566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4084df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4085b1353e8eSMatthew G. Knepley     PetscInt cdim;
4086b1353e8eSMatthew G. Knepley 
40879566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
40889566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
40899566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4090b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4091b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4092b1353e8eSMatthew G. Knepley       PetscObject  obj;
4093b1353e8eSMatthew G. Knepley       PetscClassId id;
4094b1353e8eSMatthew G. Knepley 
40959566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40969566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
40979566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
409863a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
40999566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4100b1353e8eSMatthew G. Knepley     }
4101b1353e8eSMatthew G. Knepley   }
4102df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
41033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4104b1353e8eSMatthew G. Knepley }
4105b1353e8eSMatthew G. Knepley 
41064366bac7SMatthew G. Knepley PetscErrorCode PetscDSPermuteQuadPoint(PetscDS ds, PetscInt ornt, PetscInt field, PetscInt q, PetscInt *qperm)
41074366bac7SMatthew G. Knepley {
41084366bac7SMatthew G. Knepley   IS              permIS;
41094366bac7SMatthew G. Knepley   PetscQuadrature quad;
41104366bac7SMatthew G. Knepley   DMPolytopeType  ct;
41114366bac7SMatthew G. Knepley   const PetscInt *perm;
41124366bac7SMatthew G. Knepley   PetscInt        Na, Nq;
41134366bac7SMatthew G. Knepley 
41144366bac7SMatthew G. Knepley   PetscFunctionBeginHot;
41154366bac7SMatthew G. Knepley   PetscCall(PetscFEGetQuadrature((PetscFE)ds->disc[field], &quad));
41164366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetData(quad, NULL, NULL, &Nq, NULL, NULL));
41174366bac7SMatthew G. Knepley   PetscCall(PetscQuadratureGetCellType(quad, &ct));
41184366bac7SMatthew 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);
41194366bac7SMatthew G. Knepley   Na = DMPolytopeTypeGetNumArrangments(ct) / 2;
41204366bac7SMatthew 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);
41214366bac7SMatthew G. Knepley   if (!ds->quadPerm[(PetscInt)ct]) PetscCall(PetscQuadratureComputePermutations(quad, NULL, &ds->quadPerm[(PetscInt)ct]));
41224366bac7SMatthew G. Knepley   permIS = ds->quadPerm[(PetscInt)ct][ornt + Na];
41234366bac7SMatthew G. Knepley   PetscCall(ISGetIndices(permIS, &perm));
41244366bac7SMatthew G. Knepley   *qperm = perm[q];
41254366bac7SMatthew G. Knepley   PetscCall(ISRestoreIndices(permIS, &perm));
41264366bac7SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
41274366bac7SMatthew G. Knepley }
41284366bac7SMatthew G. Knepley 
4129d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4130d71ae5a4SJacob Faibussowitsch {
4131c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4132c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4133c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4134c7bd5f0bSMatthew G. Knepley 
4135c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4136c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4137665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
4138665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
41399566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
414063a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
41419566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4142665f567fSMatthew G. Knepley   if (obj) {
41439566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4144665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4145665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4146665f567fSMatthew G. Knepley   }
41473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4148c7bd5f0bSMatthew G. Knepley }
4149c7bd5f0bSMatthew G. Knepley 
4150d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4151d71ae5a4SJacob Faibussowitsch {
41522764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41539566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
41543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41552764a2aaSMatthew G. Knepley }
41562764a2aaSMatthew G. Knepley 
4157d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4158d71ae5a4SJacob Faibussowitsch {
41592764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41606528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
41616528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
41626528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
41636528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
41643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41652764a2aaSMatthew G. Knepley }
41662764a2aaSMatthew G. Knepley 
41672764a2aaSMatthew G. Knepley /*MC
41682764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
41692764a2aaSMatthew G. Knepley 
41702764a2aaSMatthew G. Knepley   Level: intermediate
41712764a2aaSMatthew G. Knepley 
4172db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
41732764a2aaSMatthew G. Knepley M*/
41742764a2aaSMatthew G. Knepley 
4175d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4176d71ae5a4SJacob Faibussowitsch {
41772764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
41782764a2aaSMatthew G. Knepley 
41792764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41806528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41814dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
41826528b96dSMatthew G. Knepley   ds->data = b;
41832764a2aaSMatthew G. Knepley 
41849566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
41853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41862764a2aaSMatthew G. Knepley }
4187