xref: /petsc/src/dm/dt/interface/dtds.c (revision 20f4b53cbb5e9bd9ef12b76a8697d60d197cda17)
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 
24*20f4b53cSBarry Smith   Not Collective; No Fortran Support
252764a2aaSMatthew G. Knepley 
262764a2aaSMatthew G. Knepley   Input Parameters:
27*20f4b53cSBarry Smith + sname        - The name of a new user-defined creation routine
28*20f4b53cSBarry 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 
62*20f4b53cSBarry 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 
100*20f4b53cSBarry 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 
237*20f4b53cSBarry Smith    Collective
238fe2efc57SMark 
239fe2efc57SMark    Input Parameters:
240dce8aebaSBarry Smith +  A - the `PetscDS` object
241*20f4b53cSBarry 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 
259*20f4b53cSBarry 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 
267*20f4b53cSBarry 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 
286*20f4b53cSBarry 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 
364*20f4b53cSBarry 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;
3774bee2e38SMatthew G. Knepley   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
37849ae0b56SMatthew G. Knepley   PetscInt       gorder = -1, fgorder = -1;
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) {
39212fc5b22SMatthew G. Knepley     PetscQuadrature mq = NULL, mfq = NULL;
39312fc5b22SMatthew G. Knepley     PetscInt        maxOrder = -1, maxFOrder = -1;
39412fc5b22SMatthew G. Knepley 
39512fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
39612fc5b22SMatthew G. Knepley       PetscObject     obj;
39712fc5b22SMatthew G. Knepley       PetscClassId    id;
39812fc5b22SMatthew G. Knepley       PetscQuadrature q = NULL, fq = NULL;
39912fc5b22SMatthew G. Knepley       PetscInt        order = -1, forder = -1;
40012fc5b22SMatthew G. Knepley 
40112fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40212fc5b22SMatthew G. Knepley       if (!obj) continue;
40312fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
40412fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
40512fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
40612fc5b22SMatthew G. Knepley 
40712fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetQuadrature(fe, &q));
40812fc5b22SMatthew G. Knepley         PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
40912fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
41012fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
41112fc5b22SMatthew G. Knepley 
41212fc5b22SMatthew G. Knepley         PetscCall(PetscFVGetQuadrature(fv, &q));
41312fc5b22SMatthew G. Knepley       }
41412fc5b22SMatthew G. Knepley       if (q) PetscCall(PetscQuadratureGetOrder(q, &order));
41512fc5b22SMatthew G. Knepley       if (fq) PetscCall(PetscQuadratureGetOrder(fq, &forder));
41612fc5b22SMatthew G. Knepley       if (order > maxOrder) {
41712fc5b22SMatthew G. Knepley         maxOrder = order;
41812fc5b22SMatthew G. Knepley         mq       = q;
41912fc5b22SMatthew G. Knepley       }
42012fc5b22SMatthew G. Knepley       if (forder > maxFOrder) {
42112fc5b22SMatthew G. Knepley         maxFOrder = forder;
42212fc5b22SMatthew G. Knepley         mfq       = fq;
42312fc5b22SMatthew G. Knepley       }
42412fc5b22SMatthew G. Knepley     }
42512fc5b22SMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
42612fc5b22SMatthew G. Knepley       PetscObject  obj;
42712fc5b22SMatthew G. Knepley       PetscClassId id;
42812fc5b22SMatthew G. Knepley 
42912fc5b22SMatthew G. Knepley       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
43012fc5b22SMatthew G. Knepley       if (!obj) continue;
43112fc5b22SMatthew G. Knepley       PetscCall(PetscObjectGetClassId(obj, &id));
43212fc5b22SMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
43312fc5b22SMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
43412fc5b22SMatthew G. Knepley 
43512fc5b22SMatthew G. Knepley         PetscCall(PetscFESetQuadrature(fe, mq));
43612fc5b22SMatthew G. Knepley         PetscCall(PetscFESetFaceQuadrature(fe, mfq));
43712fc5b22SMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
43812fc5b22SMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
43912fc5b22SMatthew G. Knepley 
44012fc5b22SMatthew G. Knepley         PetscCall(PetscFVSetQuadrature(fv, mq));
44112fc5b22SMatthew G. Knepley       }
44212fc5b22SMatthew G. Knepley     }
44312fc5b22SMatthew G. Knepley   }
4442764a2aaSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
4459de99aefSMatthew G. Knepley     PetscObject     obj;
4469de99aefSMatthew G. Knepley     PetscClassId    id;
447665f567fSMatthew G. Knepley     PetscQuadrature q  = NULL;
4489de99aefSMatthew G. Knepley     PetscInt        Nq = 0, Nb, Nc;
4492764a2aaSMatthew G. Knepley 
4509566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &obj));
451f9244615SMatthew G. Knepley     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
452665f567fSMatthew G. Knepley     if (!obj) {
453665f567fSMatthew G. Knepley       /* Empty mesh */
454665f567fSMatthew G. Knepley       Nb = Nc    = 0;
455665f567fSMatthew G. Knepley       prob->T[f] = prob->Tf[f] = NULL;
456665f567fSMatthew G. Knepley     } else {
4579566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
4589de99aefSMatthew G. Knepley       if (id == PETSCFE_CLASSID) {
4599de99aefSMatthew G. Knepley         PetscFE fe = (PetscFE)obj;
4609de99aefSMatthew G. Knepley 
4619566063dSJacob Faibussowitsch         PetscCall(PetscFEGetQuadrature(fe, &q));
46249ae0b56SMatthew G. Knepley         {
46349ae0b56SMatthew G. Knepley           PetscQuadrature fq;
46449ae0b56SMatthew G. Knepley           PetscInt        order, forder;
46549ae0b56SMatthew G. Knepley 
46649ae0b56SMatthew G. Knepley           PetscCall(PetscQuadratureGetOrder(q, &order));
46749ae0b56SMatthew G. Knepley           if (gorder < 0) gorder = order;
46849ae0b56SMatthew G. Knepley           PetscCheck(order == gorder, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " cell quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS cell quadrature order", f, order, gorder);
46949ae0b56SMatthew G. Knepley           PetscCall(PetscFEGetFaceQuadrature(fe, &fq));
47049ae0b56SMatthew G. Knepley           if (fq) {
47149ae0b56SMatthew G. Knepley             PetscCall(PetscQuadratureGetOrder(fq, &forder));
47249ae0b56SMatthew G. Knepley             if (fgorder < 0) fgorder = forder;
47349ae0b56SMatthew G. Knepley             PetscCheck(forder == fgorder, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Field %" PetscInt_FMT " face quadrature order %" PetscInt_FMT " != %" PetscInt_FMT " DS face quadrature order", f, forder, fgorder);
47449ae0b56SMatthew G. Knepley           }
47549ae0b56SMatthew G. Knepley         }
4769566063dSJacob Faibussowitsch         PetscCall(PetscFEGetDimension(fe, &Nb));
4779566063dSJacob Faibussowitsch         PetscCall(PetscFEGetNumComponents(fe, &Nc));
4789566063dSJacob Faibussowitsch         PetscCall(PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]));
4799566063dSJacob Faibussowitsch         PetscCall(PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]));
4809de99aefSMatthew G. Knepley       } else if (id == PETSCFV_CLASSID) {
4819de99aefSMatthew G. Knepley         PetscFV fv = (PetscFV)obj;
4829de99aefSMatthew G. Knepley 
4839566063dSJacob Faibussowitsch         PetscCall(PetscFVGetQuadrature(fv, &q));
4849566063dSJacob Faibussowitsch         PetscCall(PetscFVGetNumComponents(fv, &Nc));
4859c3cf19fSMatthew G. Knepley         Nb = Nc;
4869566063dSJacob Faibussowitsch         PetscCall(PetscFVGetCellTabulation(fv, &prob->T[f]));
4874d0b9603SSander Arens         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
48863a3b9bcSJacob Faibussowitsch       } else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %" PetscInt_FMT, f);
489665f567fSMatthew G. Knepley     }
49047e57110SSander Arens     prob->Nc[f]                    = Nc;
49147e57110SSander Arens     prob->Nb[f]                    = Nb;
492194d53e6SMatthew G. Knepley     prob->off[f + 1]               = Nc + prob->off[f];
493194d53e6SMatthew G. Knepley     prob->offDer[f + 1]            = Nc * dim + prob->offDer[f];
4949ee2af8cSMatthew G. Knepley     prob->offCohesive[0][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[0][f];
4959ee2af8cSMatthew G. Knepley     prob->offDerCohesive[0][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[0][f];
4969ee2af8cSMatthew G. Knepley     prob->offCohesive[1][f]        = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
4979ee2af8cSMatthew G. Knepley     prob->offDerCohesive[1][f]     = (prob->cohesive[f] ? 0 : Nc) * dimEmbed + prob->offDerCohesive[0][f];
4989ee2af8cSMatthew G. Knepley     prob->offCohesive[2][f + 1]    = (prob->cohesive[f] ? Nc : Nc * 2) + prob->offCohesive[2][f];
4999ee2af8cSMatthew G. Knepley     prob->offDerCohesive[2][f + 1] = (prob->cohesive[f] ? Nc : Nc * 2) * dimEmbed + prob->offDerCohesive[2][f];
5009566063dSJacob Faibussowitsch     if (q) PetscCall(PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL));
5012764a2aaSMatthew G. Knepley     NqMax = PetscMax(NqMax, Nq);
5024bee2e38SMatthew G. Knepley     NbMax = PetscMax(NbMax, Nb);
5032764a2aaSMatthew G. Knepley     NcMax = PetscMax(NcMax, Nc);
5049c3cf19fSMatthew G. Knepley     prob->totDim += Nb;
5052764a2aaSMatthew G. Knepley     prob->totComp += Nc;
5065fedec97SMatthew G. Knepley     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
5075fedec97SMatthew G. Knepley     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
5082764a2aaSMatthew G. Knepley   }
5099ee2af8cSMatthew G. Knepley   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
5109ee2af8cSMatthew G. Knepley   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
5112764a2aaSMatthew G. Knepley   /* Allocate works space */
5125fedec97SMatthew G. Knepley   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
5139566063dSJacob 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));
5149566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dimEmbed, &prob->x, NbMax * NcMax, &prob->basisReal, NbMax * NcMax * dimEmbed, &prob->basisDerReal, NbMax * NcMax, &prob->testReal, NbMax * NcMax * dimEmbed, &prob->testDerReal));
5159371c9d4SSatish 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,
5169371c9d4SSatish Balay                          &prob->g2, NsMax * NsMax * NqMax * NcMax * NcMax * dimEmbed * dimEmbed, &prob->g3));
517dbbe0bcdSBarry Smith   PetscTryTypeMethod(prob, setup);
5182764a2aaSMatthew G. Knepley   prob->setup = PETSC_TRUE;
5193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5202764a2aaSMatthew G. Knepley }
5212764a2aaSMatthew G. Knepley 
522d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
523d71ae5a4SJacob Faibussowitsch {
5242764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5259566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->Nc, prob->Nb));
5269566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->off, prob->offDer));
5279566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->offCohesive[0], prob->offCohesive[1], prob->offCohesive[2], prob->offDerCohesive[0], prob->offDerCohesive[1], prob->offDerCohesive[2]));
5289566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->T, prob->Tf));
5299566063dSJacob Faibussowitsch   PetscCall(PetscFree3(prob->u, prob->u_t, prob->u_x));
5309566063dSJacob Faibussowitsch   PetscCall(PetscFree5(prob->x, prob->basisReal, prob->basisDerReal, prob->testReal, prob->testDerReal));
5319566063dSJacob Faibussowitsch   PetscCall(PetscFree6(prob->f0, prob->f1, prob->g0, prob->g1, prob->g2, prob->g3));
5323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5332764a2aaSMatthew G. Knepley }
5342764a2aaSMatthew G. Knepley 
535d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
536d71ae5a4SJacob Faibussowitsch {
537f744cafaSSander Arens   PetscObject          *tmpd;
53834aa8a36SMatthew G. Knepley   PetscBool            *tmpi;
539f9244615SMatthew G. Knepley   PetscInt             *tmpk;
5405fedec97SMatthew G. Knepley   PetscBool            *tmpc;
5416528b96dSMatthew G. Knepley   PetscPointFunc       *tmpup;
542f2cacb80SMatthew G. Knepley   PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
543f2cacb80SMatthew G. Knepley   void                **tmpexactCtx, **tmpexactCtx_t;
5440c2f2876SMatthew G. Knepley   void                **tmpctx;
54534aa8a36SMatthew G. Knepley   PetscInt              Nf = prob->Nf, f;
5462764a2aaSMatthew G. Knepley 
5472764a2aaSMatthew G. Knepley   PetscFunctionBegin;
5483ba16761SJacob Faibussowitsch   if (Nf >= NfNew) PetscFunctionReturn(PETSC_SUCCESS);
5492764a2aaSMatthew G. Knepley   prob->setup = PETSC_FALSE;
5509566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(prob));
5519566063dSJacob Faibussowitsch   PetscCall(PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk));
5529371c9d4SSatish Balay   for (f = 0; f < Nf; ++f) {
5539371c9d4SSatish Balay     tmpd[f] = prob->disc[f];
5549371c9d4SSatish Balay     tmpi[f] = prob->implicit[f];
5559371c9d4SSatish Balay     tmpc[f] = prob->cohesive[f];
5569371c9d4SSatish Balay     tmpk[f] = prob->jetDegree[f];
5579371c9d4SSatish Balay   }
5589371c9d4SSatish Balay   for (f = Nf; f < NfNew; ++f) {
5599371c9d4SSatish Balay     tmpd[f] = NULL;
5609371c9d4SSatish Balay     tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE;
5619371c9d4SSatish Balay     tmpk[f] = 1;
5629371c9d4SSatish Balay   }
5639566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree));
5649566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(prob->wf, NfNew));
5652764a2aaSMatthew G. Knepley   prob->Nf        = NfNew;
5662764a2aaSMatthew G. Knepley   prob->disc      = tmpd;
567249df284SMatthew G. Knepley   prob->implicit  = tmpi;
5685fedec97SMatthew G. Knepley   prob->cohesive  = tmpc;
569f9244615SMatthew G. Knepley   prob->jetDegree = tmpk;
5709566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx));
57132d2bbc9SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
5720c2f2876SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
57332d2bbc9SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
5740c2f2876SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
5759566063dSJacob Faibussowitsch   PetscCall(PetscFree2(prob->update, prob->ctx));
57632d2bbc9SMatthew G. Knepley   prob->update = tmpup;
5770c2f2876SMatthew G. Knepley   prob->ctx    = tmpctx;
5789566063dSJacob Faibussowitsch   PetscCall(PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t));
579c371a6d1SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
58095cbbfd3SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
581f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
582f2cacb80SMatthew G. Knepley   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
583c371a6d1SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
58495cbbfd3SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
585f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
586f2cacb80SMatthew G. Knepley   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
5879566063dSJacob Faibussowitsch   PetscCall(PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t));
588c371a6d1SMatthew G. Knepley   prob->exactSol   = tmpexactSol;
58995cbbfd3SMatthew G. Knepley   prob->exactCtx   = tmpexactCtx;
590f2cacb80SMatthew G. Knepley   prob->exactSol_t = tmpexactSol_t;
591f2cacb80SMatthew G. Knepley   prob->exactCtx_t = tmpexactCtx_t;
5923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5932764a2aaSMatthew G. Knepley }
5942764a2aaSMatthew G. Knepley 
5952764a2aaSMatthew G. Knepley /*@
596*20f4b53cSBarry Smith   PetscDSDestroy - Destroys a `PetscDS` object
5972764a2aaSMatthew G. Knepley 
598*20f4b53cSBarry Smith   Collective
5992764a2aaSMatthew G. Knepley 
6002764a2aaSMatthew G. Knepley   Input Parameter:
601*20f4b53cSBarry Smith . prob - the `PetscDS` object to destroy
6022764a2aaSMatthew G. Knepley 
6032764a2aaSMatthew G. Knepley   Level: developer
6042764a2aaSMatthew G. Knepley 
605dce8aebaSBarry Smith .seealso: `PetscDSView()`
6062764a2aaSMatthew G. Knepley @*/
607d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroy(PetscDS *ds)
608d71ae5a4SJacob Faibussowitsch {
6092764a2aaSMatthew G. Knepley   PetscInt f;
6102764a2aaSMatthew G. Knepley 
6112764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6123ba16761SJacob Faibussowitsch   if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
6136528b96dSMatthew G. Knepley   PetscValidHeaderSpecific((*ds), PETSCDS_CLASSID, 1);
6142764a2aaSMatthew G. Knepley 
6159371c9d4SSatish Balay   if (--((PetscObject)(*ds))->refct > 0) {
6169371c9d4SSatish Balay     *ds = NULL;
6173ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
6189371c9d4SSatish Balay   }
6196528b96dSMatthew G. Knepley   ((PetscObject)(*ds))->refct = 0;
6206528b96dSMatthew G. Knepley   if ((*ds)->subprobs) {
621df3a45bdSMatthew G. Knepley     PetscInt dim, d;
622df3a45bdSMatthew G. Knepley 
6239566063dSJacob Faibussowitsch     PetscCall(PetscDSGetSpatialDimension(*ds, &dim));
6249566063dSJacob Faibussowitsch     for (d = 0; d < dim; ++d) PetscCall(PetscDSDestroy(&(*ds)->subprobs[d]));
625df3a45bdSMatthew G. Knepley   }
6269566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->subprobs));
6279566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyStructs_Static(*ds));
62848a46eb9SPierre Jolivet   for (f = 0; f < (*ds)->Nf; ++f) PetscCall(PetscObjectDereference((*ds)->disc[f]));
6299566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree));
6309566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormDestroy(&(*ds)->wf));
6319566063dSJacob Faibussowitsch   PetscCall(PetscFree2((*ds)->update, (*ds)->ctx));
6329566063dSJacob Faibussowitsch   PetscCall(PetscFree4((*ds)->exactSol, (*ds)->exactCtx, (*ds)->exactSol_t, (*ds)->exactCtx_t));
633dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ds), destroy);
6349566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(*ds));
6359566063dSJacob Faibussowitsch   PetscCall(PetscFree((*ds)->constants));
6369566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ds));
6373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6382764a2aaSMatthew G. Knepley }
6392764a2aaSMatthew G. Knepley 
6402764a2aaSMatthew G. Knepley /*@
641dce8aebaSBarry Smith   PetscDSCreate - Creates an empty `PetscDS` object. The type can then be set with `PetscDSSetType()`.
6422764a2aaSMatthew G. Knepley 
643d083f849SBarry Smith   Collective
6442764a2aaSMatthew G. Knepley 
6452764a2aaSMatthew G. Knepley   Input Parameter:
646dce8aebaSBarry Smith . comm - The communicator for the `PetscDS` object
6472764a2aaSMatthew G. Knepley 
6482764a2aaSMatthew G. Knepley   Output Parameter:
649dce8aebaSBarry Smith . ds   - The `PetscDS` object
6502764a2aaSMatthew G. Knepley 
6512764a2aaSMatthew G. Knepley   Level: beginner
6522764a2aaSMatthew G. Knepley 
653dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetType()`, `PETSCDSBASIC`, `PetscDSType`
6542764a2aaSMatthew G. Knepley @*/
655d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
656d71ae5a4SJacob Faibussowitsch {
6572764a2aaSMatthew G. Knepley   PetscDS p;
6582764a2aaSMatthew G. Knepley 
6592764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6606528b96dSMatthew G. Knepley   PetscValidPointer(ds, 2);
6616528b96dSMatthew G. Knepley   *ds = NULL;
6629566063dSJacob Faibussowitsch   PetscCall(PetscDSInitializePackage());
6632764a2aaSMatthew G. Knepley 
6649566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView));
6652764a2aaSMatthew G. Knepley 
6662764a2aaSMatthew G. Knepley   p->Nf           = 0;
6672764a2aaSMatthew G. Knepley   p->setup        = PETSC_FALSE;
66897b6e6e8SMatthew G. Knepley   p->numConstants = 0;
66997b6e6e8SMatthew G. Knepley   p->constants    = NULL;
670a859676bSMatthew G. Knepley   p->dimEmbed     = -1;
67155c1f793SMatthew G. Knepley   p->useJacPre    = PETSC_TRUE;
67212fc5b22SMatthew G. Knepley   p->forceQuad    = PETSC_TRUE;
6739566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(comm, &p->wf));
6742764a2aaSMatthew G. Knepley 
6756528b96dSMatthew G. Knepley   *ds = p;
6763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6772764a2aaSMatthew G. Knepley }
6782764a2aaSMatthew G. Knepley 
679bc4ae4beSMatthew G. Knepley /*@
680dce8aebaSBarry Smith   PetscDSGetNumFields - Returns the number of fields in the `PetscDS`
681bc4ae4beSMatthew G. Knepley 
682*20f4b53cSBarry Smith   Not Collective
683bc4ae4beSMatthew G. Knepley 
684bc4ae4beSMatthew G. Knepley   Input Parameter:
685*20f4b53cSBarry Smith . prob - The `PetscDS` object
686bc4ae4beSMatthew G. Knepley 
687bc4ae4beSMatthew G. Knepley   Output Parameter:
688bc4ae4beSMatthew G. Knepley . Nf - The number of fields
689bc4ae4beSMatthew G. Knepley 
690bc4ae4beSMatthew G. Knepley   Level: beginner
691bc4ae4beSMatthew G. Knepley 
692dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetSpatialDimension()`, `PetscDSCreate()`
693bc4ae4beSMatthew G. Knepley @*/
694d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
695d71ae5a4SJacob Faibussowitsch {
6962764a2aaSMatthew G. Knepley   PetscFunctionBegin;
6972764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
698dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nf, 2);
6992764a2aaSMatthew G. Knepley   *Nf = prob->Nf;
7003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7012764a2aaSMatthew G. Knepley }
7022764a2aaSMatthew G. Knepley 
703bc4ae4beSMatthew G. Knepley /*@
704dce8aebaSBarry Smith   PetscDSGetSpatialDimension - Returns the spatial dimension of the `PetscDS`, meaning the topological dimension of the discretizations
705bc4ae4beSMatthew G. Knepley 
706*20f4b53cSBarry Smith   Not Collective
707bc4ae4beSMatthew G. Knepley 
708bc4ae4beSMatthew G. Knepley   Input Parameter:
709dce8aebaSBarry Smith . prob - The `PetscDS` object
710bc4ae4beSMatthew G. Knepley 
711bc4ae4beSMatthew G. Knepley   Output Parameter:
712bc4ae4beSMatthew G. Knepley . dim - The spatial dimension
713bc4ae4beSMatthew G. Knepley 
714bc4ae4beSMatthew G. Knepley   Level: beginner
715bc4ae4beSMatthew G. Knepley 
716dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
717bc4ae4beSMatthew G. Knepley @*/
718d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
719d71ae5a4SJacob Faibussowitsch {
7202764a2aaSMatthew G. Knepley   PetscFunctionBegin;
7212764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
722dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
7232764a2aaSMatthew G. Knepley   *dim = 0;
7249de99aefSMatthew G. Knepley   if (prob->Nf) {
7259de99aefSMatthew G. Knepley     PetscObject  obj;
7269de99aefSMatthew G. Knepley     PetscClassId id;
7279de99aefSMatthew G. Knepley 
7289566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
729665f567fSMatthew G. Knepley     if (obj) {
7309566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
7319566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetSpatialDimension((PetscFE)obj, dim));
7329566063dSJacob Faibussowitsch       else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetSpatialDimension((PetscFV)obj, dim));
73398921bdaSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
7349de99aefSMatthew G. Knepley     }
735665f567fSMatthew G. Knepley   }
7363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7372764a2aaSMatthew G. Knepley }
7382764a2aaSMatthew G. Knepley 
739bc4ae4beSMatthew G. Knepley /*@
740dce8aebaSBarry Smith   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
741a859676bSMatthew G. Knepley 
742*20f4b53cSBarry Smith   Not Collective
743a859676bSMatthew G. Knepley 
744a859676bSMatthew G. Knepley   Input Parameter:
745dce8aebaSBarry Smith . prob - The `PetscDS` object
746a859676bSMatthew G. Knepley 
747a859676bSMatthew G. Knepley   Output Parameter:
748a859676bSMatthew G. Knepley . dimEmbed - The coordinate dimension
749a859676bSMatthew G. Knepley 
750a859676bSMatthew G. Knepley   Level: beginner
751a859676bSMatthew G. Knepley 
752dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
753a859676bSMatthew G. Knepley @*/
754d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
755d71ae5a4SJacob Faibussowitsch {
756a859676bSMatthew G. Knepley   PetscFunctionBegin;
757a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
758dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dimEmbed, 2);
75908401ef6SPierre Jolivet   PetscCheck(prob->dimEmbed >= 0, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
760a859676bSMatthew G. Knepley   *dimEmbed = prob->dimEmbed;
7613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
762a859676bSMatthew G. Knepley }
763a859676bSMatthew G. Knepley 
764a859676bSMatthew G. Knepley /*@
765dce8aebaSBarry Smith   PetscDSSetCoordinateDimension - Set the coordinate dimension of the `PetscDS`, meaning the dimension of the space into which the discretiaztions are embedded
766a859676bSMatthew G. Knepley 
767*20f4b53cSBarry Smith   Logically Collective
768a859676bSMatthew G. Knepley 
769a859676bSMatthew G. Knepley   Input Parameters:
770dce8aebaSBarry Smith + prob - The `PetscDS` object
771a859676bSMatthew G. Knepley - dimEmbed - The coordinate dimension
772a859676bSMatthew G. Knepley 
773a859676bSMatthew G. Knepley   Level: beginner
774a859676bSMatthew G. Knepley 
775dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCoordinateDimension()`, `PetscDSGetSpatialDimension()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
776a859676bSMatthew G. Knepley @*/
777d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
778d71ae5a4SJacob Faibussowitsch {
779a859676bSMatthew G. Knepley   PetscFunctionBegin;
780a859676bSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
78163a3b9bcSJacob Faibussowitsch   PetscCheck(dimEmbed >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %" PetscInt_FMT, dimEmbed);
782a859676bSMatthew G. Knepley   prob->dimEmbed = dimEmbed;
7833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
784a859676bSMatthew G. Knepley }
785a859676bSMatthew G. Knepley 
786a859676bSMatthew G. Knepley /*@
78712fc5b22SMatthew G. Knepley   PetscDSGetForceQuad - Returns the flag to force matching quadratures among the field discretizations
78812fc5b22SMatthew G. Knepley 
78912fc5b22SMatthew G. Knepley   Not collective
79012fc5b22SMatthew G. Knepley 
79112fc5b22SMatthew G. Knepley   Input Parameter:
79212fc5b22SMatthew G. Knepley . prob - The `PetscDS` object
79312fc5b22SMatthew G. Knepley 
79412fc5b22SMatthew G. Knepley   Output Parameter:
79512fc5b22SMatthew G. Knepley . forceQuad - The flag
79612fc5b22SMatthew G. Knepley 
79712fc5b22SMatthew G. Knepley   Level: intermediate
79812fc5b22SMatthew G. Knepley 
79912fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSSetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
80012fc5b22SMatthew G. Knepley @*/
80112fc5b22SMatthew G. Knepley PetscErrorCode PetscDSGetForceQuad(PetscDS ds, PetscBool *forceQuad)
80212fc5b22SMatthew G. Knepley {
80312fc5b22SMatthew G. Knepley   PetscFunctionBegin;
80412fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
80512fc5b22SMatthew G. Knepley   PetscValidIntPointer(forceQuad, 2);
80612fc5b22SMatthew G. Knepley   *forceQuad = ds->forceQuad;
80712fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
80812fc5b22SMatthew G. Knepley }
80912fc5b22SMatthew G. Knepley 
81012fc5b22SMatthew G. Knepley /*@
81112fc5b22SMatthew G. Knepley   PetscDSSetForceQuad - Set the flag to force matching quadratures among the field discretizations
81212fc5b22SMatthew G. Knepley 
81312fc5b22SMatthew G. Knepley   Logically collective on ds
81412fc5b22SMatthew G. Knepley 
81512fc5b22SMatthew G. Knepley   Input Parameters:
81612fc5b22SMatthew G. Knepley + ds - The `PetscDS` object
81712fc5b22SMatthew G. Knepley - forceQuad - The flag
81812fc5b22SMatthew G. Knepley 
81912fc5b22SMatthew G. Knepley   Level: intermediate
82012fc5b22SMatthew G. Knepley 
82112fc5b22SMatthew G. Knepley .seealso: `PetscDS`, `PetscDSGetForceQuad()`, `PetscDSGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
82212fc5b22SMatthew G. Knepley @*/
82312fc5b22SMatthew G. Knepley PetscErrorCode PetscDSSetForceQuad(PetscDS ds, PetscBool forceQuad)
82412fc5b22SMatthew G. Knepley {
82512fc5b22SMatthew G. Knepley   PetscFunctionBegin;
82612fc5b22SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
82712fc5b22SMatthew G. Knepley   ds->forceQuad = forceQuad;
82812fc5b22SMatthew G. Knepley   PetscFunctionReturn(PETSC_SUCCESS);
82912fc5b22SMatthew G. Knepley }
83012fc5b22SMatthew G. Knepley 
83112fc5b22SMatthew G. Knepley /*@
832dce8aebaSBarry Smith   PetscDSIsCohesive - Returns the flag indicating that this `PetscDS` is for a cohesive cell
8338edf6225SMatthew G. Knepley 
834*20f4b53cSBarry Smith   Not Collective
8358edf6225SMatthew G. Knepley 
8368edf6225SMatthew G. Knepley   Input Parameter:
837dce8aebaSBarry Smith . ds - The `PetscDS` object
8388edf6225SMatthew G. Knepley 
8398edf6225SMatthew G. Knepley   Output Parameter:
8405fedec97SMatthew G. Knepley . isCohesive - The flag
8418edf6225SMatthew G. Knepley 
8428edf6225SMatthew G. Knepley   Level: developer
8438edf6225SMatthew G. Knepley 
844dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumCohesive()`, `PetscDSGetCohesive()`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8458edf6225SMatthew G. Knepley @*/
846d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
847d71ae5a4SJacob Faibussowitsch {
8488edf6225SMatthew G. Knepley   PetscFunctionBegin;
8495fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
850dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 2);
8515fedec97SMatthew G. Knepley   *isCohesive = ds->isCohesive;
8523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8538edf6225SMatthew G. Knepley }
8548edf6225SMatthew G. Knepley 
8558edf6225SMatthew G. Knepley /*@
8565fedec97SMatthew G. Knepley   PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell
8575fedec97SMatthew G. Knepley 
858*20f4b53cSBarry Smith   Not Collective
8595fedec97SMatthew G. Knepley 
8605fedec97SMatthew G. Knepley   Input Parameter:
861dce8aebaSBarry Smith . ds - The `PetscDS` object
8625fedec97SMatthew G. Knepley 
8635fedec97SMatthew G. Knepley   Output Parameter:
8645fedec97SMatthew G. Knepley . numCohesive - The number of cohesive fields
8655fedec97SMatthew G. Knepley 
8665fedec97SMatthew G. Knepley   Level: developer
8675fedec97SMatthew G. Knepley 
868dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSCreate()`
8695fedec97SMatthew G. Knepley @*/
870d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
871d71ae5a4SJacob Faibussowitsch {
8725fedec97SMatthew G. Knepley   PetscInt f;
8735fedec97SMatthew G. Knepley 
8745fedec97SMatthew G. Knepley   PetscFunctionBegin;
8755fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
876dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numCohesive, 2);
8775fedec97SMatthew G. Knepley   *numCohesive = 0;
8785fedec97SMatthew G. Knepley   for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
8793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8805fedec97SMatthew G. Knepley }
8815fedec97SMatthew G. Knepley 
8825fedec97SMatthew G. Knepley /*@
8835fedec97SMatthew G. Knepley   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
8845fedec97SMatthew G. Knepley 
885*20f4b53cSBarry Smith   Not Collective
8865fedec97SMatthew G. Knepley 
887f1a722f8SMatthew G. Knepley   Input Parameters:
888dce8aebaSBarry Smith + ds - The `PetscDS` object
8895fedec97SMatthew G. Knepley - f  - The field index
8905fedec97SMatthew G. Knepley 
8915fedec97SMatthew G. Knepley   Output Parameter:
8925fedec97SMatthew G. Knepley . isCohesive - The flag
8935fedec97SMatthew G. Knepley 
8945fedec97SMatthew G. Knepley   Level: developer
8955fedec97SMatthew G. Knepley 
896dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
8975fedec97SMatthew G. Knepley @*/
898d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
899d71ae5a4SJacob Faibussowitsch {
9005fedec97SMatthew G. Knepley   PetscFunctionBegin;
9015fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
902dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(isCohesive, 3);
90363a3b9bcSJacob 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);
9045fedec97SMatthew G. Knepley   *isCohesive = ds->cohesive[f];
9053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9065fedec97SMatthew G. Knepley }
9075fedec97SMatthew G. Knepley 
9085fedec97SMatthew G. Knepley /*@
9095fedec97SMatthew G. Knepley   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
9108edf6225SMatthew G. Knepley 
911*20f4b53cSBarry Smith   Not Collective
9128edf6225SMatthew G. Knepley 
9138edf6225SMatthew G. Knepley   Input Parameters:
914dce8aebaSBarry Smith + ds - The `PetscDS` object
9155fedec97SMatthew G. Knepley . f  - The field index
9165fedec97SMatthew G. Knepley - isCohesive - The flag for a cohesive field
9178edf6225SMatthew G. Knepley 
9188edf6225SMatthew G. Knepley   Level: developer
9198edf6225SMatthew G. Knepley 
920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetCohesive()`, `PetscDSIsCohesive()`, `PetscDSCreate()`
9218edf6225SMatthew G. Knepley @*/
922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
923d71ae5a4SJacob Faibussowitsch {
9245fedec97SMatthew G. Knepley   PetscInt i;
9255fedec97SMatthew G. Knepley 
9268edf6225SMatthew G. Knepley   PetscFunctionBegin;
9275fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
92863a3b9bcSJacob 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);
9295fedec97SMatthew G. Knepley   ds->cohesive[f] = isCohesive;
9305fedec97SMatthew G. Knepley   ds->isCohesive  = PETSC_FALSE;
9315fedec97SMatthew G. Knepley   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
9323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9338edf6225SMatthew G. Knepley }
9348edf6225SMatthew G. Knepley 
9358edf6225SMatthew G. Knepley /*@
936bc4ae4beSMatthew G. Knepley   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
937bc4ae4beSMatthew G. Knepley 
938*20f4b53cSBarry Smith   Not Collective
939bc4ae4beSMatthew G. Knepley 
940bc4ae4beSMatthew G. Knepley   Input Parameter:
941dce8aebaSBarry Smith . prob - The `PetscDS` object
942bc4ae4beSMatthew G. Knepley 
943bc4ae4beSMatthew G. Knepley   Output Parameter:
944bc4ae4beSMatthew G. Knepley . dim - The total problem dimension
945bc4ae4beSMatthew G. Knepley 
946bc4ae4beSMatthew G. Knepley   Level: beginner
947bc4ae4beSMatthew G. Knepley 
948dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
949bc4ae4beSMatthew G. Knepley @*/
950d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
951d71ae5a4SJacob Faibussowitsch {
9522764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9532764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9549566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
955dadcf809SJacob Faibussowitsch   PetscValidIntPointer(dim, 2);
9562764a2aaSMatthew G. Knepley   *dim = prob->totDim;
9573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9582764a2aaSMatthew G. Knepley }
9592764a2aaSMatthew G. Knepley 
960bc4ae4beSMatthew G. Knepley /*@
961bc4ae4beSMatthew G. Knepley   PetscDSGetTotalComponents - Returns the total number of components in this system
962bc4ae4beSMatthew G. Knepley 
963*20f4b53cSBarry Smith   Not Collective
964bc4ae4beSMatthew G. Knepley 
965bc4ae4beSMatthew G. Knepley   Input Parameter:
966dce8aebaSBarry Smith . prob - The `PetscDS` object
967bc4ae4beSMatthew G. Knepley 
968bc4ae4beSMatthew G. Knepley   Output Parameter:
969bc4ae4beSMatthew G. Knepley . dim - The total number of components
970bc4ae4beSMatthew G. Knepley 
971bc4ae4beSMatthew G. Knepley   Level: beginner
972bc4ae4beSMatthew G. Knepley 
973dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
974bc4ae4beSMatthew G. Knepley @*/
975d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
976d71ae5a4SJacob Faibussowitsch {
9772764a2aaSMatthew G. Knepley   PetscFunctionBegin;
9782764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
9799566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
980dadcf809SJacob Faibussowitsch   PetscValidIntPointer(Nc, 2);
9812764a2aaSMatthew G. Knepley   *Nc = prob->totComp;
9823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9832764a2aaSMatthew G. Knepley }
9842764a2aaSMatthew G. Knepley 
985bc4ae4beSMatthew G. Knepley /*@
986bc4ae4beSMatthew G. Knepley   PetscDSGetDiscretization - Returns the discretization object for the given field
987bc4ae4beSMatthew G. Knepley 
988*20f4b53cSBarry Smith   Not Collective
989bc4ae4beSMatthew G. Knepley 
990bc4ae4beSMatthew G. Knepley   Input Parameters:
991dce8aebaSBarry Smith + prob - The `PetscDS` object
992bc4ae4beSMatthew G. Knepley - f - The field number
993bc4ae4beSMatthew G. Knepley 
994bc4ae4beSMatthew G. Knepley   Output Parameter:
995bc4ae4beSMatthew G. Knepley . disc - The discretization object
996bc4ae4beSMatthew G. Knepley 
997bc4ae4beSMatthew G. Knepley   Level: beginner
998bc4ae4beSMatthew G. Knepley 
999dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1000bc4ae4beSMatthew G. Knepley @*/
1001d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
1002d71ae5a4SJacob Faibussowitsch {
10036528b96dSMatthew G. Knepley   PetscFunctionBeginHot;
10042764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
10052764a2aaSMatthew G. Knepley   PetscValidPointer(disc, 3);
100663a3b9bcSJacob 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);
10072764a2aaSMatthew G. Knepley   *disc = prob->disc[f];
10083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10092764a2aaSMatthew G. Knepley }
10102764a2aaSMatthew G. Knepley 
1011bc4ae4beSMatthew G. Knepley /*@
1012bc4ae4beSMatthew G. Knepley   PetscDSSetDiscretization - Sets the discretization object for the given field
1013bc4ae4beSMatthew G. Knepley 
1014*20f4b53cSBarry Smith   Not Collective
1015bc4ae4beSMatthew G. Knepley 
1016bc4ae4beSMatthew G. Knepley   Input Parameters:
1017dce8aebaSBarry Smith + prob - The `PetscDS` object
1018bc4ae4beSMatthew G. Knepley . f - The field number
1019bc4ae4beSMatthew G. Knepley - disc - The discretization object
1020bc4ae4beSMatthew G. Knepley 
1021bc4ae4beSMatthew G. Knepley   Level: beginner
1022bc4ae4beSMatthew G. Knepley 
1023dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscFE`, `PetscFV`, `PetscDSGetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1024bc4ae4beSMatthew G. Knepley @*/
1025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
1026d71ae5a4SJacob Faibussowitsch {
10272764a2aaSMatthew G. Knepley   PetscFunctionBegin;
10282764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1029665f567fSMatthew G. Knepley   if (disc) PetscValidPointer(disc, 3);
103063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
10319566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
10329566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference(prob->disc[f]));
10332764a2aaSMatthew G. Knepley   prob->disc[f] = disc;
10349566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference(disc));
1035665f567fSMatthew G. Knepley   if (disc) {
1036249df284SMatthew G. Knepley     PetscClassId id;
1037249df284SMatthew G. Knepley 
10389566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(disc, &id));
10391cf84007SMatthew G. Knepley     if (id == PETSCFE_CLASSID) {
10409566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_TRUE));
10411cf84007SMatthew G. Knepley     } else if (id == PETSCFV_CLASSID) {
10429566063dSJacob Faibussowitsch       PetscCall(PetscDSSetImplicit(prob, f, PETSC_FALSE));
1043a6cbbb48SMatthew G. Knepley     }
10449566063dSJacob Faibussowitsch     PetscCall(PetscDSSetJetDegree(prob, f, 1));
1045249df284SMatthew G. Knepley   }
10463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10472764a2aaSMatthew G. Knepley }
10482764a2aaSMatthew G. Knepley 
1049bc4ae4beSMatthew G. Knepley /*@
10506528b96dSMatthew G. Knepley   PetscDSGetWeakForm - Returns the weak form object
10516528b96dSMatthew G. Knepley 
1052*20f4b53cSBarry Smith   Not Collective
10536528b96dSMatthew G. Knepley 
10546528b96dSMatthew G. Knepley   Input Parameter:
1055dce8aebaSBarry Smith . ds - The `PetscDS` object
10566528b96dSMatthew G. Knepley 
10576528b96dSMatthew G. Knepley   Output Parameter:
10586528b96dSMatthew G. Knepley . wf - The weak form object
10596528b96dSMatthew G. Knepley 
10606528b96dSMatthew G. Knepley   Level: beginner
10616528b96dSMatthew G. Knepley 
1062dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSSetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10636528b96dSMatthew G. Knepley @*/
1064d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
1065d71ae5a4SJacob Faibussowitsch {
10666528b96dSMatthew G. Knepley   PetscFunctionBegin;
10676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10686528b96dSMatthew G. Knepley   PetscValidPointer(wf, 2);
10696528b96dSMatthew G. Knepley   *wf = ds->wf;
10703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10716528b96dSMatthew G. Knepley }
10726528b96dSMatthew G. Knepley 
10736528b96dSMatthew G. Knepley /*@
10746528b96dSMatthew G. Knepley   PetscDSSetWeakForm - Sets the weak form object
10756528b96dSMatthew G. Knepley 
1076*20f4b53cSBarry Smith   Not Collective
10776528b96dSMatthew G. Knepley 
10786528b96dSMatthew G. Knepley   Input Parameters:
1079dce8aebaSBarry Smith + ds - The `PetscDS` object
10806528b96dSMatthew G. Knepley - wf - The weak form object
10816528b96dSMatthew G. Knepley 
10826528b96dSMatthew G. Knepley   Level: beginner
10836528b96dSMatthew G. Knepley 
1084dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetWeakForm()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
10856528b96dSMatthew G. Knepley @*/
1086d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
1087d71ae5a4SJacob Faibussowitsch {
10886528b96dSMatthew G. Knepley   PetscFunctionBegin;
10896528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
10906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(wf, PETSCWEAKFORM_CLASSID, 2);
10919566063dSJacob Faibussowitsch   PetscCall(PetscObjectDereference((PetscObject)ds->wf));
10926528b96dSMatthew G. Knepley   ds->wf = wf;
10939566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)wf));
10949566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(wf, ds->Nf));
10953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10966528b96dSMatthew G. Knepley }
10976528b96dSMatthew G. Knepley 
10986528b96dSMatthew G. Knepley /*@
1099bc4ae4beSMatthew G. Knepley   PetscDSAddDiscretization - Adds a discretization object
1100bc4ae4beSMatthew G. Knepley 
1101*20f4b53cSBarry Smith   Not Collective
1102bc4ae4beSMatthew G. Knepley 
1103bc4ae4beSMatthew G. Knepley   Input Parameters:
1104dce8aebaSBarry Smith + prob - The `PetscDS` object
1105bc4ae4beSMatthew G. Knepley - disc - The boundary discretization object
1106bc4ae4beSMatthew G. Knepley 
1107bc4ae4beSMatthew G. Knepley   Level: beginner
1108bc4ae4beSMatthew G. Knepley 
1109dce8aebaSBarry Smith .seealso: `PetscWeakForm`, `PetscDSGetDiscretization()`, `PetscDSSetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1110bc4ae4beSMatthew G. Knepley @*/
1111d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
1112d71ae5a4SJacob Faibussowitsch {
11132764a2aaSMatthew G. Knepley   PetscFunctionBegin;
11149566063dSJacob Faibussowitsch   PetscCall(PetscDSSetDiscretization(prob, prob->Nf, disc));
11153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11162764a2aaSMatthew G. Knepley }
11172764a2aaSMatthew G. Knepley 
1118249df284SMatthew G. Knepley /*@
1119dce8aebaSBarry Smith   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the `PetscDS`
1120083401c6SMatthew G. Knepley 
1121*20f4b53cSBarry Smith   Not Collective
1122083401c6SMatthew G. Knepley 
1123083401c6SMatthew G. Knepley   Input Parameter:
1124dce8aebaSBarry Smith . prob - The `PetscDS` object
1125083401c6SMatthew G. Knepley 
1126083401c6SMatthew G. Knepley   Output Parameter:
1127083401c6SMatthew G. Knepley . q - The quadrature object
1128083401c6SMatthew G. Knepley 
1129083401c6SMatthew G. Knepley   Level: intermediate
1130083401c6SMatthew G. Knepley 
1131dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscQuadrature`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1132083401c6SMatthew G. Knepley @*/
1133d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
1134d71ae5a4SJacob Faibussowitsch {
1135083401c6SMatthew G. Knepley   PetscObject  obj;
1136083401c6SMatthew G. Knepley   PetscClassId id;
1137083401c6SMatthew G. Knepley 
1138083401c6SMatthew G. Knepley   PetscFunctionBegin;
1139083401c6SMatthew G. Knepley   *q = NULL;
11403ba16761SJacob Faibussowitsch   if (!prob->Nf) PetscFunctionReturn(PETSC_SUCCESS);
11419566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, &obj));
11429566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetClassId(obj, &id));
11439566063dSJacob Faibussowitsch   if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetQuadrature((PetscFE)obj, q));
11449566063dSJacob Faibussowitsch   else if (id == PETSCFV_CLASSID) PetscCall(PetscFVGetQuadrature((PetscFV)obj, q));
114598921bdaSJacob Faibussowitsch   else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
11463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1147083401c6SMatthew G. Knepley }
1148083401c6SMatthew G. Knepley 
1149083401c6SMatthew G. Knepley /*@
1150dce8aebaSBarry Smith   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1151249df284SMatthew G. Knepley 
1152*20f4b53cSBarry Smith   Not Collective
1153249df284SMatthew G. Knepley 
1154249df284SMatthew G. Knepley   Input Parameters:
1155dce8aebaSBarry Smith + prob - The `PetscDS` object
1156249df284SMatthew G. Knepley - f - The field number
1157249df284SMatthew G. Knepley 
1158249df284SMatthew G. Knepley   Output Parameter:
1159249df284SMatthew G. Knepley . implicit - The flag indicating what kind of solve to use for this field
1160249df284SMatthew G. Knepley 
1161249df284SMatthew G. Knepley   Level: developer
1162249df284SMatthew G. Knepley 
1163dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDS`, `PetscDSSetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1164249df284SMatthew G. Knepley @*/
1165d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1166d71ae5a4SJacob Faibussowitsch {
1167249df284SMatthew G. Knepley   PetscFunctionBegin;
1168249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1169dadcf809SJacob Faibussowitsch   PetscValidBoolPointer(implicit, 3);
117063a3b9bcSJacob 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);
1171249df284SMatthew G. Knepley   *implicit = prob->implicit[f];
11723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1173249df284SMatthew G. Knepley }
1174249df284SMatthew G. Knepley 
1175249df284SMatthew G. Knepley /*@
1176dce8aebaSBarry Smith   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for `TSIMEX`
1177249df284SMatthew G. Knepley 
1178*20f4b53cSBarry Smith   Not Collective
1179249df284SMatthew G. Knepley 
1180249df284SMatthew G. Knepley   Input Parameters:
1181dce8aebaSBarry Smith + prob - The `PetscDS` object
1182249df284SMatthew G. Knepley . f - The field number
1183249df284SMatthew G. Knepley - implicit - The flag indicating what kind of solve to use for this field
1184249df284SMatthew G. Knepley 
1185249df284SMatthew G. Knepley   Level: developer
1186249df284SMatthew G. Knepley 
1187dce8aebaSBarry Smith .seealso: `TSIMEX`, `PetscDSGetImplicit()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1188249df284SMatthew G. Knepley @*/
1189d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1190d71ae5a4SJacob Faibussowitsch {
1191249df284SMatthew G. Knepley   PetscFunctionBegin;
1192249df284SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
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   prob->implicit[f] = implicit;
11953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1196249df284SMatthew G. Knepley }
1197249df284SMatthew G. Knepley 
1198f9244615SMatthew G. Knepley /*@
1199f9244615SMatthew G. Knepley   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1200f9244615SMatthew G. Knepley 
1201*20f4b53cSBarry Smith   Not Collective
1202f9244615SMatthew G. Knepley 
1203f9244615SMatthew G. Knepley   Input Parameters:
1204dce8aebaSBarry Smith + ds - The `PetscDS` object
1205f9244615SMatthew G. Knepley - f  - The field number
1206f9244615SMatthew G. Knepley 
1207f9244615SMatthew G. Knepley   Output Parameter:
1208f9244615SMatthew G. Knepley . k  - The highest derivative we need to tabulate
1209f9244615SMatthew G. Knepley 
1210f9244615SMatthew G. Knepley   Level: developer
1211f9244615SMatthew G. Knepley 
1212dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1213f9244615SMatthew G. Knepley @*/
1214d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1215d71ae5a4SJacob Faibussowitsch {
1216f9244615SMatthew G. Knepley   PetscFunctionBegin;
1217f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1218dadcf809SJacob Faibussowitsch   PetscValidIntPointer(k, 3);
121963a3b9bcSJacob 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);
1220f9244615SMatthew G. Knepley   *k = ds->jetDegree[f];
12213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1222f9244615SMatthew G. Knepley }
1223f9244615SMatthew G. Knepley 
1224f9244615SMatthew G. Knepley /*@
1225f9244615SMatthew G. Knepley   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1226f9244615SMatthew G. Knepley 
1227*20f4b53cSBarry Smith   Not Collective
1228f9244615SMatthew G. Knepley 
1229f9244615SMatthew G. Knepley   Input Parameters:
1230dce8aebaSBarry Smith + ds - The `PetscDS` object
1231f9244615SMatthew G. Knepley . f  - The field number
1232f9244615SMatthew G. Knepley - k  - The highest derivative we need to tabulate
1233f9244615SMatthew G. Knepley 
1234f9244615SMatthew G. Knepley   Level: developer
1235f9244615SMatthew G. Knepley 
1236dce8aebaSBarry Smith .seealso: ``PetscDS`, PetscDSGetJetDegree()`, `PetscDSSetDiscretization()`, `PetscDSAddDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
1237f9244615SMatthew G. Knepley @*/
1238d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1239d71ae5a4SJacob Faibussowitsch {
1240f9244615SMatthew G. Knepley   PetscFunctionBegin;
1241f9244615SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
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   ds->jetDegree[f] = k;
12443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1245f9244615SMatthew G. Knepley }
1246f9244615SMatthew G. Knepley 
1247d71ae5a4SJacob 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[]))
1248d71ae5a4SJacob Faibussowitsch {
12496528b96dSMatthew G. Knepley   PetscPointFunc *tmp;
12506528b96dSMatthew G. Knepley   PetscInt        n;
12516528b96dSMatthew G. Knepley 
12522764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12546528b96dSMatthew G. Knepley   PetscValidPointer(obj, 3);
125563a3b9bcSJacob 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);
12569566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp));
12576528b96dSMatthew G. Knepley   *obj = tmp ? tmp[0] : NULL;
12583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12592764a2aaSMatthew G. Knepley }
12602764a2aaSMatthew G. Knepley 
1261d71ae5a4SJacob 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[]))
1262d71ae5a4SJacob Faibussowitsch {
12632764a2aaSMatthew G. Knepley   PetscFunctionBegin;
12646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
12656528b96dSMatthew G. Knepley   if (obj) PetscValidFunction(obj, 3);
126663a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
12679566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj));
12683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12692764a2aaSMatthew G. Knepley }
12702764a2aaSMatthew G. Knepley 
1271194d53e6SMatthew G. Knepley /*@C
1272194d53e6SMatthew G. Knepley   PetscDSGetResidual - Get the pointwise residual function for a given test field
1273194d53e6SMatthew G. Knepley 
1274*20f4b53cSBarry Smith   Not Collective
1275194d53e6SMatthew G. Knepley 
1276194d53e6SMatthew G. Knepley   Input Parameters:
1277dce8aebaSBarry Smith + ds - The `PetscDS`
1278194d53e6SMatthew G. Knepley - f  - The test field number
1279194d53e6SMatthew G. Knepley 
1280194d53e6SMatthew G. Knepley   Output Parameters:
1281194d53e6SMatthew G. Knepley + f0 - integrand for the test function term
1282194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1283194d53e6SMatthew G. Knepley 
1284*20f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1285dce8aebaSBarry Smith .vb
1286*20f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1287dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1288dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1289dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1290dce8aebaSBarry Smith .ve
1291194d53e6SMatthew G. Knepley + dim - the spatial dimension
1292194d53e6SMatthew G. Knepley . Nf - the number of fields
1293194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1294194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1295194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1296194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1297194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1298194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1299194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1300194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1301194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1302194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1303194d53e6SMatthew G. Knepley . t - current time
1304194d53e6SMatthew G. Knepley . x - coordinates of the current point
130597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
130697b6e6e8SMatthew G. Knepley . constants - constant parameters
1307194d53e6SMatthew G. Knepley - f0 - output values at the current point
1308194d53e6SMatthew G. Knepley 
1309194d53e6SMatthew G. Knepley   Level: intermediate
1310194d53e6SMatthew G. Knepley 
1311dce8aebaSBarry Smith   Note:
1312dce8aebaSBarry 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)
1313dce8aebaSBarry Smith 
1314dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetResidual()`
1315194d53e6SMatthew G. Knepley @*/
1316d71ae5a4SJacob 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[]))
1317d71ae5a4SJacob Faibussowitsch {
13186528b96dSMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
13196528b96dSMatthew G. Knepley   PetscInt        n0, n1;
13206528b96dSMatthew G. Knepley 
13212764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13226528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
132363a3b9bcSJacob 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);
13249566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
13256528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
13266528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
13273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13282764a2aaSMatthew G. Knepley }
13292764a2aaSMatthew G. Knepley 
1330194d53e6SMatthew G. Knepley /*@C
1331194d53e6SMatthew G. Knepley   PetscDSSetResidual - Set the pointwise residual function for a given test field
1332194d53e6SMatthew G. Knepley 
1333*20f4b53cSBarry Smith   Not Collective
1334194d53e6SMatthew G. Knepley 
1335194d53e6SMatthew G. Knepley   Input Parameters:
1336dce8aebaSBarry Smith + ds - The `PetscDS`
1337194d53e6SMatthew G. Knepley . f  - The test field number
1338194d53e6SMatthew G. Knepley . f0 - integrand for the test function term
1339194d53e6SMatthew G. Knepley - f1 - integrand for the test function gradient term
1340194d53e6SMatthew G. Knepley 
1341*20f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1342dce8aebaSBarry Smith .vb
1343*20f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1344dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1345dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1346dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1347dce8aebaSBarry Smith .ve
1348194d53e6SMatthew G. Knepley + dim - the spatial dimension
1349194d53e6SMatthew G. Knepley . Nf - the number of fields
1350194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1351194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1352194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1353194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1354194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1355194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1356194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1357194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1358194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1359194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1360194d53e6SMatthew G. Knepley . t - current time
1361194d53e6SMatthew G. Knepley . x - coordinates of the current point
136297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
136397b6e6e8SMatthew G. Knepley . constants - constant parameters
1364194d53e6SMatthew G. Knepley - f0 - output values at the current point
1365194d53e6SMatthew G. Knepley 
1366194d53e6SMatthew G. Knepley   Level: intermediate
1367194d53e6SMatthew G. Knepley 
1368dce8aebaSBarry Smith   Note:
1369dce8aebaSBarry 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)
1370dce8aebaSBarry Smith 
1371dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1372194d53e6SMatthew G. Knepley @*/
1373d71ae5a4SJacob 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[]))
1374d71ae5a4SJacob Faibussowitsch {
13752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
13766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1377f866a1d0SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1378f866a1d0SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
137963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
13809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
13813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13822764a2aaSMatthew G. Knepley }
13832764a2aaSMatthew G. Knepley 
13843e75805dSMatthew G. Knepley /*@C
1385cb36c0f9SMatthew G. Knepley   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1386cb36c0f9SMatthew G. Knepley 
1387*20f4b53cSBarry Smith   Not Collective
1388cb36c0f9SMatthew G. Knepley 
1389cb36c0f9SMatthew G. Knepley   Input Parameters:
1390dce8aebaSBarry Smith + ds - The `PetscDS`
1391cb36c0f9SMatthew G. Knepley - f  - The test field number
1392cb36c0f9SMatthew G. Knepley 
1393cb36c0f9SMatthew G. Knepley   Output Parameters:
1394cb36c0f9SMatthew G. Knepley + f0 - integrand for the test function term
1395cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1396cb36c0f9SMatthew G. Knepley 
1397*20f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
1398dce8aebaSBarry Smith .vb
1399*20f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1400dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1401dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1402dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar f0[])
1403dce8aebaSBarry Smith .ve
1404cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1405cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1406cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1407cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1408cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1409cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1410cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1411cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1412cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1413cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1414cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1415cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1416cb36c0f9SMatthew G. Knepley . t - current time
1417cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1418cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1419cb36c0f9SMatthew G. Knepley . constants - constant parameters
1420cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1421cb36c0f9SMatthew G. Knepley 
1422cb36c0f9SMatthew G. Knepley   Level: intermediate
1423cb36c0f9SMatthew G. Knepley 
1424dce8aebaSBarry Smith   Note:
1425dce8aebaSBarry 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)
1426dce8aebaSBarry Smith 
1427dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRHSResidual()`
1428cb36c0f9SMatthew G. Knepley @*/
1429d71ae5a4SJacob 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[]))
1430d71ae5a4SJacob Faibussowitsch {
1431cb36c0f9SMatthew G. Knepley   PetscPointFunc *tmp0, *tmp1;
1432cb36c0f9SMatthew G. Knepley   PetscInt        n0, n1;
1433cb36c0f9SMatthew G. Knepley 
1434cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1435cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
143663a3b9bcSJacob 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);
14379566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1));
1438cb36c0f9SMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
1439cb36c0f9SMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
14403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1441cb36c0f9SMatthew G. Knepley }
1442cb36c0f9SMatthew G. Knepley 
1443cb36c0f9SMatthew G. Knepley /*@C
1444cb36c0f9SMatthew G. Knepley   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1445cb36c0f9SMatthew G. Knepley 
1446*20f4b53cSBarry Smith   Not Collective
1447cb36c0f9SMatthew G. Knepley 
1448cb36c0f9SMatthew G. Knepley   Input Parameters:
1449dce8aebaSBarry Smith + ds - The `PetscDS`
1450cb36c0f9SMatthew G. Knepley . f  - The test field number
1451cb36c0f9SMatthew G. Knepley . f0 - integrand for the test function term
1452cb36c0f9SMatthew G. Knepley - f1 - integrand for the test function gradient term
1453cb36c0f9SMatthew G. Knepley 
1454dce8aebaSBarry Smith   Clling sequence for the callbacks f0 and f1:
1455dce8aebaSBarry Smith .vb
1456dce8aebaSBarry Smith   f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1457dce8aebaSBarry Smith      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1458dce8aebaSBarry Smith      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1459dce8aebaSBarry Smith      PetscReal t, const PetscReal x[], PetscScalar f0[])
1460dce8aebaSBarry Smith .ve
1461cb36c0f9SMatthew G. Knepley + dim - the spatial dimension
1462cb36c0f9SMatthew G. Knepley . Nf - the number of fields
1463cb36c0f9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1464cb36c0f9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1465cb36c0f9SMatthew G. Knepley . u - each field evaluated at the current point
1466cb36c0f9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1467cb36c0f9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1468cb36c0f9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1469cb36c0f9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1470cb36c0f9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1471cb36c0f9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1472cb36c0f9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1473cb36c0f9SMatthew G. Knepley . t - current time
1474cb36c0f9SMatthew G. Knepley . x - coordinates of the current point
1475cb36c0f9SMatthew G. Knepley . numConstants - number of constant parameters
1476cb36c0f9SMatthew G. Knepley . constants - constant parameters
1477cb36c0f9SMatthew G. Knepley - f0 - output values at the current point
1478cb36c0f9SMatthew G. Knepley 
1479cb36c0f9SMatthew G. Knepley   Level: intermediate
1480cb36c0f9SMatthew G. Knepley 
1481dce8aebaSBarry Smith   Note:
1482dce8aebaSBarry 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)
1483dce8aebaSBarry Smith 
1484dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
1485cb36c0f9SMatthew G. Knepley @*/
1486d71ae5a4SJacob 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[]))
1487d71ae5a4SJacob Faibussowitsch {
1488cb36c0f9SMatthew G. Knepley   PetscFunctionBegin;
1489cb36c0f9SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1490cb36c0f9SMatthew G. Knepley   if (f0) PetscValidFunction(f0, 3);
1491cb36c0f9SMatthew G. Knepley   if (f1) PetscValidFunction(f1, 4);
149263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
14939566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1));
14943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1495cb36c0f9SMatthew G. Knepley }
1496cb36c0f9SMatthew G. Knepley 
1497cb36c0f9SMatthew G. Knepley /*@C
1498dce8aebaSBarry Smith   PetscDSHasJacobian - Checks that the Jacobian functions have been set
14993e75805dSMatthew G. Knepley 
1500*20f4b53cSBarry Smith   Not Collective
15013e75805dSMatthew G. Knepley 
15023e75805dSMatthew G. Knepley   Input Parameter:
1503dce8aebaSBarry Smith . prob - The `PetscDS`
15043e75805dSMatthew G. Knepley 
15053e75805dSMatthew G. Knepley   Output Parameter:
15063e75805dSMatthew G. Knepley . hasJac - flag that pointwise function for the Jacobian has been set
15073e75805dSMatthew G. Knepley 
15083e75805dSMatthew G. Knepley   Level: intermediate
15093e75805dSMatthew G. Knepley 
1510dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
15113e75805dSMatthew G. Knepley @*/
1512d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1513d71ae5a4SJacob Faibussowitsch {
15143e75805dSMatthew G. Knepley   PetscFunctionBegin;
15156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
15169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobian(ds->wf, hasJac));
15173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15183e75805dSMatthew G. Knepley }
15193e75805dSMatthew G. Knepley 
1520194d53e6SMatthew G. Knepley /*@C
1521194d53e6SMatthew G. Knepley   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1522194d53e6SMatthew G. Knepley 
1523*20f4b53cSBarry Smith   Not Collective
1524194d53e6SMatthew G. Knepley 
1525194d53e6SMatthew G. Knepley   Input Parameters:
1526dce8aebaSBarry Smith + ds - The `PetscDS`
1527194d53e6SMatthew G. Knepley . f  - The test field number
1528194d53e6SMatthew G. Knepley - g  - The field number
1529194d53e6SMatthew G. Knepley 
1530194d53e6SMatthew G. Knepley   Output Parameters:
1531194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
1532194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1533194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1534194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1535194d53e6SMatthew G. Knepley 
1536*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1537dce8aebaSBarry Smith .vb
1538*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1539dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1540dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1541dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1542dce8aebaSBarry Smith .ve
1543194d53e6SMatthew G. Knepley + dim - the spatial dimension
1544194d53e6SMatthew G. Knepley . Nf - the number of fields
1545194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1546194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1547194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1548194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1549194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1550194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1551194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1552194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1553194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1554194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1555194d53e6SMatthew G. Knepley . t - current time
15562aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1557194d53e6SMatthew G. Knepley . x - coordinates of the current point
155897b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
155997b6e6e8SMatthew G. Knepley . constants - constant parameters
1560194d53e6SMatthew G. Knepley - g0 - output values at the current point
1561194d53e6SMatthew G. Knepley 
1562194d53e6SMatthew G. Knepley   Level: intermediate
1563194d53e6SMatthew G. Knepley 
1564dce8aebaSBarry Smith   Note:
1565dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1566dce8aebaSBarry 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
1567dce8aebaSBarry Smith 
1568dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1569194d53e6SMatthew G. Knepley @*/
1570d71ae5a4SJacob 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[]))
1571d71ae5a4SJacob Faibussowitsch {
15726528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
15736528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
15746528b96dSMatthew G. Knepley 
15752764a2aaSMatthew G. Knepley   PetscFunctionBegin;
15766528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
157763a3b9bcSJacob 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);
157863a3b9bcSJacob 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);
15799566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
15806528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
15816528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
15826528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
15836528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
15843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15852764a2aaSMatthew G. Knepley }
15862764a2aaSMatthew G. Knepley 
1587194d53e6SMatthew G. Knepley /*@C
1588194d53e6SMatthew G. Knepley   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1589194d53e6SMatthew G. Knepley 
1590*20f4b53cSBarry Smith   Not Collective
1591194d53e6SMatthew G. Knepley 
1592194d53e6SMatthew G. Knepley   Input Parameters:
1593dce8aebaSBarry Smith + ds - The `PetscDS`
1594194d53e6SMatthew G. Knepley . f  - The test field number
1595194d53e6SMatthew G. Knepley . g  - The field number
1596194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
1597194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1598194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1599194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1600194d53e6SMatthew G. Knepley 
1601*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1602dce8aebaSBarry Smith .vb
1603*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1604dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1605dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1606dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar g0[])
1607dce8aebaSBarry Smith .ve
1608194d53e6SMatthew G. Knepley + dim - the spatial dimension
1609194d53e6SMatthew G. Knepley . Nf - the number of fields
1610194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1611194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1612194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
1613194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1614194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1615194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1616194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1617194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1618194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1619194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1620194d53e6SMatthew G. Knepley . t - current time
16212aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1622194d53e6SMatthew G. Knepley . x - coordinates of the current point
162397b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
162497b6e6e8SMatthew G. Knepley . constants - constant parameters
1625194d53e6SMatthew G. Knepley - g0 - output values at the current point
1626194d53e6SMatthew G. Knepley 
1627194d53e6SMatthew G. Knepley   Level: intermediate
1628194d53e6SMatthew G. Knepley 
1629dce8aebaSBarry Smith   Note:
1630dce8aebaSBarry Smith    We are using a first order FEM model for the weak form:
1631dce8aebaSBarry 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
1632dce8aebaSBarry Smith 
1633dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1634194d53e6SMatthew G. Knepley @*/
1635d71ae5a4SJacob 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[]))
1636d71ae5a4SJacob Faibussowitsch {
16372764a2aaSMatthew G. Knepley   PetscFunctionBegin;
16386528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
16392764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
16402764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
16412764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
16422764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
164363a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
164463a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
16459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
16463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16472764a2aaSMatthew G. Knepley }
16482764a2aaSMatthew G. Knepley 
1649475e0ac9SMatthew G. Knepley /*@C
1650dce8aebaSBarry Smith   PetscDSUseJacobianPreconditioner - Set whether to construct a Jacobian preconditioner
165155c1f793SMatthew G. Knepley 
1652*20f4b53cSBarry Smith   Not Collective
165355c1f793SMatthew G. Knepley 
165455c1f793SMatthew G. Knepley   Input Parameters:
1655dce8aebaSBarry Smith + prob - The `PetscDS`
165655c1f793SMatthew G. Knepley - useJacPre - flag that enables construction of a Jacobian preconditioner
165755c1f793SMatthew G. Knepley 
165855c1f793SMatthew G. Knepley   Level: intermediate
165955c1f793SMatthew G. Knepley 
1660dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
166155c1f793SMatthew G. Knepley @*/
1662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1663d71ae5a4SJacob Faibussowitsch {
166455c1f793SMatthew G. Knepley   PetscFunctionBegin;
166555c1f793SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
166655c1f793SMatthew G. Knepley   prob->useJacPre = useJacPre;
16673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166855c1f793SMatthew G. Knepley }
166955c1f793SMatthew G. Knepley 
167055c1f793SMatthew G. Knepley /*@C
1671dce8aebaSBarry Smith   PetscDSHasJacobianPreconditioner - Checks if a Jacobian preconditioner matrix has been set
1672475e0ac9SMatthew G. Knepley 
1673*20f4b53cSBarry Smith   Not Collective
1674475e0ac9SMatthew G. Knepley 
1675475e0ac9SMatthew G. Knepley   Input Parameter:
1676dce8aebaSBarry Smith . prob - The `PetscDS`
1677475e0ac9SMatthew G. Knepley 
1678475e0ac9SMatthew G. Knepley   Output Parameter:
1679475e0ac9SMatthew G. Knepley . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1680475e0ac9SMatthew G. Knepley 
1681475e0ac9SMatthew G. Knepley   Level: intermediate
1682475e0ac9SMatthew G. Knepley 
1683dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1684475e0ac9SMatthew G. Knepley @*/
1685d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1686d71ae5a4SJacob Faibussowitsch {
1687475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
16886528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1689475e0ac9SMatthew G. Knepley   *hasJacPre = PETSC_FALSE;
16903ba16761SJacob Faibussowitsch   if (!ds->useJacPre) PetscFunctionReturn(PETSC_SUCCESS);
16919566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre));
16923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1693475e0ac9SMatthew G. Knepley }
1694475e0ac9SMatthew G. Knepley 
1695475e0ac9SMatthew G. Knepley /*@C
1696dce8aebaSBarry Smith   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing,
1697dce8aebaSBarry Smith    the system matrix is used to build the preconditioner.
1698475e0ac9SMatthew G. Knepley 
1699*20f4b53cSBarry Smith   Not Collective
1700475e0ac9SMatthew G. Knepley 
1701475e0ac9SMatthew G. Knepley   Input Parameters:
1702dce8aebaSBarry Smith + ds - The `PetscDS`
1703475e0ac9SMatthew G. Knepley . f  - The test field number
1704475e0ac9SMatthew G. Knepley - g  - The field number
1705475e0ac9SMatthew G. Knepley 
1706475e0ac9SMatthew G. Knepley   Output Parameters:
1707475e0ac9SMatthew G. Knepley + g0 - integrand for the test and basis function term
1708475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1709475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1710475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1711475e0ac9SMatthew G. Knepley 
1712*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1713dce8aebaSBarry Smith .vb
1714*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1715dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1716dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1717dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1718dce8aebaSBarry Smith .ve
1719475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1720475e0ac9SMatthew G. Knepley . Nf - the number of fields
1721475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1722475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1723475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1724475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1725475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1726475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1727475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1728475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1729475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1730475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1731475e0ac9SMatthew G. Knepley . t - current time
1732475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1733475e0ac9SMatthew G. Knepley . x - coordinates of the current point
173497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
173597b6e6e8SMatthew G. Knepley . constants - constant parameters
1736475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1737475e0ac9SMatthew G. Knepley 
1738475e0ac9SMatthew G. Knepley   Level: intermediate
1739475e0ac9SMatthew G. Knepley 
1740dce8aebaSBarry Smith   Note:
1741dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1742dce8aebaSBarry Smith   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi
1743dce8aebaSBarry Smith 
1744dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobianPreconditioner()`, `PetscDSGetJacobian()`
1745475e0ac9SMatthew G. Knepley @*/
1746d71ae5a4SJacob 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[]))
1747d71ae5a4SJacob Faibussowitsch {
17486528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
17496528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
17506528b96dSMatthew G. Knepley 
1751475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
17526528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
175363a3b9bcSJacob 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);
175463a3b9bcSJacob 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);
17559566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
17566528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
17576528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
17586528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
17596528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
17603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1761475e0ac9SMatthew G. Knepley }
1762475e0ac9SMatthew G. Knepley 
1763475e0ac9SMatthew G. Knepley /*@C
1764dce8aebaSBarry Smith   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields.
1765dce8aebaSBarry Smith   If this is missing, the system matrix is used to build the preconditioner.
1766475e0ac9SMatthew G. Knepley 
1767*20f4b53cSBarry Smith   Not Collective
1768475e0ac9SMatthew G. Knepley 
1769475e0ac9SMatthew G. Knepley   Input Parameters:
1770dce8aebaSBarry Smith + ds - The `PetscDS`
1771475e0ac9SMatthew G. Knepley . f  - The test field number
1772475e0ac9SMatthew G. Knepley . g  - The field number
1773475e0ac9SMatthew G. Knepley . g0 - integrand for the test and basis function term
1774475e0ac9SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1775475e0ac9SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1776475e0ac9SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1777475e0ac9SMatthew G. Knepley 
1778*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1779dce8aebaSBarry Smith .vb
1780*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1781dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1782dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1783dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], PetscScalar g0[])
1784dce8aebaSBarry Smith .ve
1785475e0ac9SMatthew G. Knepley + dim - the spatial dimension
1786475e0ac9SMatthew G. Knepley . Nf - the number of fields
1787475e0ac9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1788475e0ac9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1789475e0ac9SMatthew G. Knepley . u - each field evaluated at the current point
1790475e0ac9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1791475e0ac9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1792475e0ac9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1793475e0ac9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1794475e0ac9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1795475e0ac9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1796475e0ac9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1797475e0ac9SMatthew G. Knepley . t - current time
1798475e0ac9SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1799475e0ac9SMatthew G. Knepley . x - coordinates of the current point
180097b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
180197b6e6e8SMatthew G. Knepley . constants - constant parameters
1802475e0ac9SMatthew G. Knepley - g0 - output values at the current point
1803475e0ac9SMatthew G. Knepley 
1804475e0ac9SMatthew G. Knepley   Level: intermediate
1805475e0ac9SMatthew G. Knepley 
1806dce8aebaSBarry Smith   Note:
1807dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1808dce8aebaSBarry 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
1809dce8aebaSBarry Smith 
1810dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobianPreconditioner()`, `PetscDSSetJacobian()`
1811475e0ac9SMatthew G. Knepley @*/
1812d71ae5a4SJacob 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[]))
1813d71ae5a4SJacob Faibussowitsch {
1814475e0ac9SMatthew G. Knepley   PetscFunctionBegin;
18156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1816475e0ac9SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1817475e0ac9SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1818475e0ac9SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1819475e0ac9SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
182063a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
182163a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
18229566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
18233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1824475e0ac9SMatthew G. Knepley }
1825475e0ac9SMatthew G. Knepley 
1826b7e05686SMatthew G. Knepley /*@C
1827b7e05686SMatthew G. Knepley   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1828b7e05686SMatthew G. Knepley 
1829*20f4b53cSBarry Smith   Not Collective
1830b7e05686SMatthew G. Knepley 
1831b7e05686SMatthew G. Knepley   Input Parameter:
1832dce8aebaSBarry Smith . ds - The `PetscDS`
1833b7e05686SMatthew G. Knepley 
1834b7e05686SMatthew G. Knepley   Output Parameter:
1835b7e05686SMatthew G. Knepley . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1836b7e05686SMatthew G. Knepley 
1837b7e05686SMatthew G. Knepley   Level: intermediate
1838b7e05686SMatthew G. Knepley 
1839dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetDynamicJacobian()`, `PetscDSSetDynamicJacobian()`, `PetscDSGetJacobian()`
1840b7e05686SMatthew G. Knepley @*/
1841d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1842d71ae5a4SJacob Faibussowitsch {
1843b7e05686SMatthew G. Knepley   PetscFunctionBegin;
18446528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
18459566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac));
18463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1847b7e05686SMatthew G. Knepley }
1848b7e05686SMatthew G. Knepley 
1849b7e05686SMatthew G. Knepley /*@C
1850b7e05686SMatthew G. Knepley   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1851b7e05686SMatthew G. Knepley 
1852*20f4b53cSBarry Smith   Not Collective
1853b7e05686SMatthew G. Knepley 
1854b7e05686SMatthew G. Knepley   Input Parameters:
1855dce8aebaSBarry Smith + ds - The `PetscDS`
1856b7e05686SMatthew G. Knepley . f  - The test field number
1857b7e05686SMatthew G. Knepley - g  - The field number
1858b7e05686SMatthew G. Knepley 
1859b7e05686SMatthew G. Knepley   Output Parameters:
1860b7e05686SMatthew G. Knepley + g0 - integrand for the test and basis function term
1861b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1862b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1863b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1864b7e05686SMatthew G. Knepley 
1865*20f4b53cSBarry Smith    Calling sequence of `g0`, `g1`, `g2` and `g3`:
1866dce8aebaSBarry Smith .vb
1867*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1868dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1869dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1870dce8aebaSBarry Smith           PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1871dce8aebaSBarry Smith .ve
1872b7e05686SMatthew G. Knepley + dim - the spatial dimension
1873b7e05686SMatthew G. Knepley . Nf - the number of fields
1874b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1875b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1876b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1877b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1878b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1879b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1880b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1881b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1882b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1883b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1884b7e05686SMatthew G. Knepley . t - current time
1885b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1886b7e05686SMatthew G. Knepley . x - coordinates of the current point
188797b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
188897b6e6e8SMatthew G. Knepley . constants - constant parameters
1889b7e05686SMatthew G. Knepley - g0 - output values at the current point
1890b7e05686SMatthew G. Knepley 
1891b7e05686SMatthew G. Knepley   Level: intermediate
1892b7e05686SMatthew G. Knepley 
1893dce8aebaSBarry Smith   Note:
1894dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1895dce8aebaSBarry 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
1896dce8aebaSBarry Smith 
1897dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetJacobian()`
1898b7e05686SMatthew G. Knepley @*/
1899d71ae5a4SJacob 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[]))
1900d71ae5a4SJacob Faibussowitsch {
19016528b96dSMatthew G. Knepley   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
19026528b96dSMatthew G. Knepley   PetscInt       n0, n1, n2, n3;
19036528b96dSMatthew G. Knepley 
1904b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19056528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
190663a3b9bcSJacob 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);
190763a3b9bcSJacob 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);
19089566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
19096528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
19106528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
19116528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
19126528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
19133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1914b7e05686SMatthew G. Knepley }
1915b7e05686SMatthew G. Knepley 
1916b7e05686SMatthew G. Knepley /*@C
1917b7e05686SMatthew G. Knepley   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1918b7e05686SMatthew G. Knepley 
1919*20f4b53cSBarry Smith   Not Collective
1920b7e05686SMatthew G. Knepley 
1921b7e05686SMatthew G. Knepley   Input Parameters:
1922dce8aebaSBarry Smith + ds - The `PetscDS`
1923b7e05686SMatthew G. Knepley . f  - The test field number
1924b7e05686SMatthew G. Knepley . g  - The field number
1925b7e05686SMatthew G. Knepley . g0 - integrand for the test and basis function term
1926b7e05686SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
1927b7e05686SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
1928b7e05686SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
1929b7e05686SMatthew G. Knepley 
1930*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
1931dce8aebaSBarry Smith .vb
1932*20f4b53cSBarry Smith    void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1933dce8aebaSBarry Smith            const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1934dce8aebaSBarry Smith            const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1935dce8aebaSBarry Smith            PetscReal t, const PetscReal x[], PetscScalar g0[])
1936dce8aebaSBarry Smith .ve
1937b7e05686SMatthew G. Knepley + dim - the spatial dimension
1938b7e05686SMatthew G. Knepley . Nf - the number of fields
1939b7e05686SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
1940b7e05686SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
1941b7e05686SMatthew G. Knepley . u - each field evaluated at the current point
1942b7e05686SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
1943b7e05686SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
1944b7e05686SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
1945b7e05686SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
1946b7e05686SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
1947b7e05686SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
1948b7e05686SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
1949b7e05686SMatthew G. Knepley . t - current time
1950b7e05686SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
1951b7e05686SMatthew G. Knepley . x - coordinates of the current point
195297b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
195397b6e6e8SMatthew G. Knepley . constants - constant parameters
1954b7e05686SMatthew G. Knepley - g0 - output values at the current point
1955b7e05686SMatthew G. Knepley 
1956b7e05686SMatthew G. Knepley   Level: intermediate
1957b7e05686SMatthew G. Knepley 
1958dce8aebaSBarry Smith   Note:
1959dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
1960dce8aebaSBarry 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
1961dce8aebaSBarry Smith 
1962dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetJacobian()`
1963b7e05686SMatthew G. Knepley @*/
1964d71ae5a4SJacob 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[]))
1965d71ae5a4SJacob Faibussowitsch {
1966b7e05686SMatthew G. Knepley   PetscFunctionBegin;
19676528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
1968b7e05686SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
1969b7e05686SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
1970b7e05686SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
1971b7e05686SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
197263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
197363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
19749566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
19753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1976b7e05686SMatthew G. Knepley }
1977b7e05686SMatthew G. Knepley 
19780c2f2876SMatthew G. Knepley /*@C
19790c2f2876SMatthew G. Knepley   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
19800c2f2876SMatthew G. Knepley 
1981*20f4b53cSBarry Smith   Not Collective
19820c2f2876SMatthew G. Knepley 
19834165533cSJose E. Roman   Input Parameters:
1984dce8aebaSBarry Smith + ds - The `PetscDS` object
19850c2f2876SMatthew G. Knepley - f  - The field number
19860c2f2876SMatthew G. Knepley 
19874165533cSJose E. Roman   Output Parameter:
19880c2f2876SMatthew G. Knepley . r    - Riemann solver
19890c2f2876SMatthew G. Knepley 
1990*20f4b53cSBarry Smith   Calling sequence of `r`:
1991dce8aebaSBarry Smith .vb
1992*20f4b53cSBarry Smith   void r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1993dce8aebaSBarry Smith .ve
19945db36cf9SMatthew G. Knepley + dim  - The spatial dimension
19955db36cf9SMatthew G. Knepley . Nf   - The number of fields
19965db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
19970c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
19980c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
19990c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20000c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
200197b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
200297b6e6e8SMatthew G. Knepley . constants - constant parameters
20030c2f2876SMatthew G. Knepley - ctx  - optional user context
20040c2f2876SMatthew G. Knepley 
20050c2f2876SMatthew G. Knepley   Level: intermediate
20060c2f2876SMatthew G. Knepley 
2007dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetRiemannSolver()`
20080c2f2876SMatthew G. Knepley @*/
2009d71ae5a4SJacob 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))
2010d71ae5a4SJacob Faibussowitsch {
20116528b96dSMatthew G. Knepley   PetscRiemannFunc *tmp;
20126528b96dSMatthew G. Knepley   PetscInt          n;
20136528b96dSMatthew G. Knepley 
20140c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20156528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
20160c2f2876SMatthew G. Knepley   PetscValidPointer(r, 3);
201763a3b9bcSJacob 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);
20189566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp));
20196528b96dSMatthew G. Knepley   *r = tmp ? tmp[0] : NULL;
20203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20210c2f2876SMatthew G. Knepley }
20220c2f2876SMatthew G. Knepley 
20230c2f2876SMatthew G. Knepley /*@C
20240c2f2876SMatthew G. Knepley   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
20250c2f2876SMatthew G. Knepley 
2026*20f4b53cSBarry Smith   Not Collective
20270c2f2876SMatthew G. Knepley 
20284165533cSJose E. Roman   Input Parameters:
2029dce8aebaSBarry Smith + ds - The `PetscDS` object
20300c2f2876SMatthew G. Knepley . f  - The field number
20310c2f2876SMatthew G. Knepley - r  - Riemann solver
20320c2f2876SMatthew G. Knepley 
2033*20f4b53cSBarry Smith   Calling sequence of `r`:
2034dce8aebaSBarry Smith .vb
2035*20f4b53cSBarry Smith    void r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2036dce8aebaSBarry Smith .ve
20375db36cf9SMatthew G. Knepley + dim  - The spatial dimension
20385db36cf9SMatthew G. Knepley . Nf   - The number of fields
20395db36cf9SMatthew G. Knepley . x    - The coordinates at a point on the interface
20400c2f2876SMatthew G. Knepley . n    - The normal vector to the interface
20410c2f2876SMatthew G. Knepley . uL   - The state vector to the left of the interface
20420c2f2876SMatthew G. Knepley . uR   - The state vector to the right of the interface
20430c2f2876SMatthew G. Knepley . flux - output array of flux through the interface
204497b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
204597b6e6e8SMatthew G. Knepley . constants - constant parameters
20460c2f2876SMatthew G. Knepley - ctx  - optional user context
20470c2f2876SMatthew G. Knepley 
20480c2f2876SMatthew G. Knepley   Level: intermediate
20490c2f2876SMatthew G. Knepley 
2050dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetRiemannSolver()`
20510c2f2876SMatthew G. Knepley @*/
2052d71ae5a4SJacob 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))
2053d71ae5a4SJacob Faibussowitsch {
20540c2f2876SMatthew G. Knepley   PetscFunctionBegin;
20556528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2056de716cbcSToby Isaac   if (r) PetscValidFunction(r, 3);
205763a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
20589566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r));
20593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20600c2f2876SMatthew G. Knepley }
20610c2f2876SMatthew G. Knepley 
206232d2bbc9SMatthew G. Knepley /*@C
206332d2bbc9SMatthew G. Knepley   PetscDSGetUpdate - Get the pointwise update function for a given field
206432d2bbc9SMatthew G. Knepley 
2065*20f4b53cSBarry Smith   Not Collective
206632d2bbc9SMatthew G. Knepley 
206732d2bbc9SMatthew G. Knepley   Input Parameters:
2068dce8aebaSBarry Smith + ds - The `PetscDS`
206932d2bbc9SMatthew G. Knepley - f  - The field number
207032d2bbc9SMatthew G. Knepley 
2071f899ff85SJose E. Roman   Output Parameter:
2072a2b725a8SWilliam Gropp . update - update function
207332d2bbc9SMatthew G. Knepley 
2074*20f4b53cSBarry Smith   Calling sequence of `update`:
2075dce8aebaSBarry Smith .vb
2076*20f4b53cSBarry Smith   void update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2077dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2078dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2079dce8aebaSBarry Smith               PetscReal t, const PetscReal x[], PetscScalar uNew[])
2080dce8aebaSBarry Smith .ve
208132d2bbc9SMatthew G. Knepley + dim - the spatial dimension
208232d2bbc9SMatthew G. Knepley . Nf - the number of fields
208332d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
208432d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
208532d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
208632d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
208732d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
208832d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
208932d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
209032d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
209132d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
209232d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
209332d2bbc9SMatthew G. Knepley . t - current time
209432d2bbc9SMatthew G. Knepley . x - coordinates of the current point
209532d2bbc9SMatthew G. Knepley - uNew - new value for field at the current point
209632d2bbc9SMatthew G. Knepley 
209732d2bbc9SMatthew G. Knepley   Level: intermediate
209832d2bbc9SMatthew G. Knepley 
2099dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetUpdate()`, `PetscDSSetResidual()`
210032d2bbc9SMatthew G. Knepley @*/
2101d71ae5a4SJacob 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[]))
2102d71ae5a4SJacob Faibussowitsch {
210332d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21046528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
210563a3b9bcSJacob 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);
21069371c9d4SSatish Balay   if (update) {
21079371c9d4SSatish Balay     PetscValidPointer(update, 3);
21089371c9d4SSatish Balay     *update = ds->update[f];
21099371c9d4SSatish Balay   }
21103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
211132d2bbc9SMatthew G. Knepley }
211232d2bbc9SMatthew G. Knepley 
211332d2bbc9SMatthew G. Knepley /*@C
21143fa77dffSMatthew G. Knepley   PetscDSSetUpdate - Set the pointwise update function for a given field
211532d2bbc9SMatthew G. Knepley 
2116*20f4b53cSBarry Smith   Not Collective
211732d2bbc9SMatthew G. Knepley 
211832d2bbc9SMatthew G. Knepley   Input Parameters:
2119dce8aebaSBarry Smith + ds     - The `PetscDS`
212032d2bbc9SMatthew G. Knepley . f      - The field number
212132d2bbc9SMatthew G. Knepley - update - update function
212232d2bbc9SMatthew G. Knepley 
2123*20f4b53cSBarry Smith   Calling sequence of `update`:
2124dce8aebaSBarry Smith .vb
2125*20f4b53cSBarry Smith   void update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2126dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2127dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2128dce8aebaSBarry Smith               PetscReal t, const PetscReal x[], PetscScalar uNew[])
2129dce8aebaSBarry Smith .ve
213032d2bbc9SMatthew G. Knepley + dim - the spatial dimension
213132d2bbc9SMatthew G. Knepley . Nf - the number of fields
213232d2bbc9SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
213332d2bbc9SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
213432d2bbc9SMatthew G. Knepley . u - each field evaluated at the current point
213532d2bbc9SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
213632d2bbc9SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
213732d2bbc9SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
213832d2bbc9SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
213932d2bbc9SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
214032d2bbc9SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
214132d2bbc9SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
214232d2bbc9SMatthew G. Knepley . t - current time
214332d2bbc9SMatthew G. Knepley . x - coordinates of the current point
214432d2bbc9SMatthew G. Knepley - uNew - new field values at the current point
214532d2bbc9SMatthew G. Knepley 
214632d2bbc9SMatthew G. Knepley   Level: intermediate
214732d2bbc9SMatthew G. Knepley 
2148dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetResidual()`
214932d2bbc9SMatthew G. Knepley @*/
2150d71ae5a4SJacob 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[]))
2151d71ae5a4SJacob Faibussowitsch {
215232d2bbc9SMatthew G. Knepley   PetscFunctionBegin;
21536528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
215432d2bbc9SMatthew G. Knepley   if (update) PetscValidFunction(update, 3);
215563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21569566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21576528b96dSMatthew G. Knepley   ds->update[f] = update;
21583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
215932d2bbc9SMatthew G. Knepley }
216032d2bbc9SMatthew G. Knepley 
2161d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2162d71ae5a4SJacob Faibussowitsch {
21630c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21646528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
216563a3b9bcSJacob 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);
21660c2f2876SMatthew G. Knepley   PetscValidPointer(ctx, 3);
21673ec1f749SStefano Zampini   *(void **)ctx = ds->ctx[f];
21683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21690c2f2876SMatthew G. Knepley }
21700c2f2876SMatthew G. Knepley 
2171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2172d71ae5a4SJacob Faibussowitsch {
21730c2f2876SMatthew G. Knepley   PetscFunctionBegin;
21746528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
217563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
21769566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(ds, f + 1));
21776528b96dSMatthew G. Knepley   ds->ctx[f] = ctx;
21783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21790c2f2876SMatthew G. Knepley }
21800c2f2876SMatthew G. Knepley 
2181194d53e6SMatthew G. Knepley /*@C
2182194d53e6SMatthew G. Knepley   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2183194d53e6SMatthew G. Knepley 
2184*20f4b53cSBarry Smith   Not Collective
2185194d53e6SMatthew G. Knepley 
2186194d53e6SMatthew G. Knepley   Input Parameters:
21876528b96dSMatthew G. Knepley + ds - The PetscDS
2188194d53e6SMatthew G. Knepley - f  - The test field number
2189194d53e6SMatthew G. Knepley 
2190194d53e6SMatthew G. Knepley   Output Parameters:
2191194d53e6SMatthew G. Knepley + f0 - boundary integrand for the test function term
2192194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2193194d53e6SMatthew G. Knepley 
2194*20f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
2195dce8aebaSBarry Smith .vb
2196*20f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2197dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2198dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2199dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2200dce8aebaSBarry Smith .ve
2201194d53e6SMatthew G. Knepley + dim - the spatial dimension
2202194d53e6SMatthew G. Knepley . Nf - the number of fields
2203194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2204194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2205194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2206194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2207194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2208194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2209194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2210194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2211194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2212194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2213194d53e6SMatthew G. Knepley . t - current time
2214194d53e6SMatthew G. Knepley . x - coordinates of the current point
2215194d53e6SMatthew G. Knepley . n - unit normal at the current point
221697b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
221797b6e6e8SMatthew G. Knepley . constants - constant parameters
2218194d53e6SMatthew G. Knepley - f0 - output values at the current point
2219194d53e6SMatthew G. Knepley 
2220194d53e6SMatthew G. Knepley   Level: intermediate
2221194d53e6SMatthew G. Knepley 
2222dce8aebaSBarry Smith   Note:
2223dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2224dce8aebaSBarry 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
2225dce8aebaSBarry Smith 
2226dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdResidual()`
2227194d53e6SMatthew G. Knepley @*/
2228d71ae5a4SJacob 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[]))
2229d71ae5a4SJacob Faibussowitsch {
22306528b96dSMatthew G. Knepley   PetscBdPointFunc *tmp0, *tmp1;
22316528b96dSMatthew G. Knepley   PetscInt          n0, n1;
22326528b96dSMatthew G. Knepley 
22332764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22346528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
223563a3b9bcSJacob 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);
22369566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1));
22376528b96dSMatthew G. Knepley   *f0 = tmp0 ? tmp0[0] : NULL;
22386528b96dSMatthew G. Knepley   *f1 = tmp1 ? tmp1[0] : NULL;
22393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22402764a2aaSMatthew G. Knepley }
22412764a2aaSMatthew G. Knepley 
2242194d53e6SMatthew G. Knepley /*@C
2243194d53e6SMatthew G. Knepley   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2244194d53e6SMatthew G. Knepley 
2245*20f4b53cSBarry Smith   Not Collective
2246194d53e6SMatthew G. Knepley 
2247194d53e6SMatthew G. Knepley   Input Parameters:
2248dce8aebaSBarry Smith + ds - The `PetscDS`
2249194d53e6SMatthew G. Knepley . f  - The test field number
2250194d53e6SMatthew G. Knepley . f0 - boundary integrand for the test function term
2251194d53e6SMatthew G. Knepley - f1 - boundary integrand for the test function gradient term
2252194d53e6SMatthew G. Knepley 
2253*20f4b53cSBarry Smith   Calling sequence of `f0` and `f1`:
2254dce8aebaSBarry Smith .vb
2255*20f4b53cSBarry Smith   void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2256dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2257dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2258dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2259dce8aebaSBarry Smith .ve
2260194d53e6SMatthew G. Knepley + dim - the spatial dimension
2261194d53e6SMatthew G. Knepley . Nf - the number of fields
2262194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2263194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2264194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2265194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2266194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2267194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2268194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2269194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2270194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2271194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2272194d53e6SMatthew G. Knepley . t - current time
2273194d53e6SMatthew G. Knepley . x - coordinates of the current point
2274194d53e6SMatthew G. Knepley . n - unit normal at the current point
227597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
227697b6e6e8SMatthew G. Knepley . constants - constant parameters
2277194d53e6SMatthew G. Knepley - f0 - output values at the current point
2278194d53e6SMatthew G. Knepley 
2279194d53e6SMatthew G. Knepley   Level: intermediate
2280194d53e6SMatthew G. Knepley 
2281dce8aebaSBarry Smith   Note:
2282dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2283dce8aebaSBarry 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
2284dce8aebaSBarry Smith 
2285dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdResidual()`
2286194d53e6SMatthew G. Knepley @*/
2287d71ae5a4SJacob 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[]))
2288d71ae5a4SJacob Faibussowitsch {
22892764a2aaSMatthew G. Knepley   PetscFunctionBegin;
22906528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
229163a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
22929566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1));
22933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22942764a2aaSMatthew G. Knepley }
22952764a2aaSMatthew G. Knepley 
229627f02ce8SMatthew G. Knepley /*@
2297dce8aebaSBarry Smith   PetscDSHasBdJacobian - Indicates that boundary Jacobian functions have been set
229827f02ce8SMatthew G. Knepley 
2299*20f4b53cSBarry Smith   Not Collective
230027f02ce8SMatthew G. Knepley 
230127f02ce8SMatthew G. Knepley   Input Parameter:
2302dce8aebaSBarry Smith . ds - The `PetscDS`
230327f02ce8SMatthew G. Knepley 
230427f02ce8SMatthew G. Knepley   Output Parameter:
230527f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
230627f02ce8SMatthew G. Knepley 
230727f02ce8SMatthew G. Knepley   Level: intermediate
230827f02ce8SMatthew G. Knepley 
2309dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
231027f02ce8SMatthew G. Knepley @*/
2311d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2312d71ae5a4SJacob Faibussowitsch {
231327f02ce8SMatthew G. Knepley   PetscFunctionBegin;
23146528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
23156528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJac, 2);
23169566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobian(ds->wf, hasBdJac));
23173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
231827f02ce8SMatthew G. Knepley }
231927f02ce8SMatthew G. Knepley 
2320194d53e6SMatthew G. Knepley /*@C
2321194d53e6SMatthew G. Knepley   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2322194d53e6SMatthew G. Knepley 
2323*20f4b53cSBarry Smith   Not Collective
2324194d53e6SMatthew G. Knepley 
2325194d53e6SMatthew G. Knepley   Input Parameters:
2326dce8aebaSBarry Smith + ds - The `PetscDS`
2327194d53e6SMatthew G. Knepley . f  - The test field number
2328194d53e6SMatthew G. Knepley - g  - The field number
2329194d53e6SMatthew G. Knepley 
2330194d53e6SMatthew G. Knepley   Output Parameters:
2331194d53e6SMatthew G. Knepley + g0 - integrand for the test and basis function term
2332194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2333194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2334194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2335194d53e6SMatthew G. Knepley 
2336*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2337dce8aebaSBarry Smith .vb
2338*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2339dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2340dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2341dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2342dce8aebaSBarry Smith .ve
2343194d53e6SMatthew G. Knepley + dim - the spatial dimension
2344194d53e6SMatthew G. Knepley . Nf - the number of fields
2345194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2346194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2347194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2348194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2349194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2350194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2351194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2352194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2353194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2354194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2355194d53e6SMatthew G. Knepley . t - current time
23562aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2357194d53e6SMatthew G. Knepley . x - coordinates of the current point
2358194d53e6SMatthew G. Knepley . n - normal at the current point
235997b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
236097b6e6e8SMatthew G. Knepley . constants - constant parameters
2361194d53e6SMatthew G. Knepley - g0 - output values at the current point
2362194d53e6SMatthew G. Knepley 
2363194d53e6SMatthew G. Knepley   Level: intermediate
2364194d53e6SMatthew G. Knepley 
2365dce8aebaSBarry Smith   Note:
2366dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2367dce8aebaSBarry 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
2368dce8aebaSBarry Smith 
2369dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobian()`
2370194d53e6SMatthew G. Knepley @*/
2371d71ae5a4SJacob 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[]))
2372d71ae5a4SJacob Faibussowitsch {
23736528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
23746528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
23756528b96dSMatthew G. Knepley 
23762764a2aaSMatthew G. Knepley   PetscFunctionBegin;
23776528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
237863a3b9bcSJacob 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);
237963a3b9bcSJacob 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);
23809566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
23816528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
23826528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
23836528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
23846528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
23853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23862764a2aaSMatthew G. Knepley }
23872764a2aaSMatthew G. Knepley 
2388194d53e6SMatthew G. Knepley /*@C
2389194d53e6SMatthew G. Knepley   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2390194d53e6SMatthew G. Knepley 
2391*20f4b53cSBarry Smith   Not Collective
2392194d53e6SMatthew G. Knepley 
2393194d53e6SMatthew G. Knepley   Input Parameters:
23946528b96dSMatthew G. Knepley + ds - The PetscDS
2395194d53e6SMatthew G. Knepley . f  - The test field number
2396194d53e6SMatthew G. Knepley . g  - The field number
2397194d53e6SMatthew G. Knepley . g0 - integrand for the test and basis function term
2398194d53e6SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
2399194d53e6SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
2400194d53e6SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
2401194d53e6SMatthew G. Knepley 
2402*20f4b53cSBarry Smith   Calling sequence of `g0`, `g1`, `g2` and `g3`:
2403dce8aebaSBarry Smith .vb
2404*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2405dce8aebaSBarry Smith        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2406dce8aebaSBarry Smith        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2407dce8aebaSBarry Smith        PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2408dce8aebaSBarry Smith .ve
2409194d53e6SMatthew G. Knepley + dim - the spatial dimension
2410194d53e6SMatthew G. Knepley . Nf - the number of fields
2411194d53e6SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
2412194d53e6SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
2413194d53e6SMatthew G. Knepley . u - each field evaluated at the current point
2414194d53e6SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
2415194d53e6SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
2416194d53e6SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
2417194d53e6SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
2418194d53e6SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
2419194d53e6SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
2420194d53e6SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
2421194d53e6SMatthew G. Knepley . t - current time
24222aa1fc23SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
2423194d53e6SMatthew G. Knepley . x - coordinates of the current point
2424194d53e6SMatthew G. Knepley . n - normal at the current point
242597b6e6e8SMatthew G. Knepley . numConstants - number of constant parameters
242697b6e6e8SMatthew G. Knepley . constants - constant parameters
2427194d53e6SMatthew G. Knepley - g0 - output values at the current point
2428194d53e6SMatthew G. Knepley 
2429194d53e6SMatthew G. Knepley   Level: intermediate
2430194d53e6SMatthew G. Knepley 
2431dce8aebaSBarry Smith   Note:
2432dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2433dce8aebaSBarry 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
2434dce8aebaSBarry Smith 
2435dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobian()`
2436194d53e6SMatthew G. Knepley @*/
2437d71ae5a4SJacob 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[]))
2438d71ae5a4SJacob Faibussowitsch {
24392764a2aaSMatthew G. Knepley   PetscFunctionBegin;
24406528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24412764a2aaSMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
24422764a2aaSMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
24432764a2aaSMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
24442764a2aaSMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
244563a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
244663a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
24479566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
24483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24492764a2aaSMatthew G. Knepley }
24502764a2aaSMatthew G. Knepley 
245127f02ce8SMatthew G. Knepley /*@
245227f02ce8SMatthew G. Knepley   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
245327f02ce8SMatthew G. Knepley 
2454*20f4b53cSBarry Smith   Not Collective
245527f02ce8SMatthew G. Knepley 
245627f02ce8SMatthew G. Knepley   Input Parameter:
2457dce8aebaSBarry Smith . ds - The `PetscDS`
245827f02ce8SMatthew G. Knepley 
245927f02ce8SMatthew G. Knepley   Output Parameter:
246027f02ce8SMatthew G. Knepley . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
246127f02ce8SMatthew G. Knepley 
246227f02ce8SMatthew G. Knepley   Level: intermediate
246327f02ce8SMatthew G. Knepley 
2464dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSHasJacobian()`, `PetscDSSetBdJacobian()`, `PetscDSGetBdJacobian()`
246527f02ce8SMatthew G. Knepley @*/
2466d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2467d71ae5a4SJacob Faibussowitsch {
246827f02ce8SMatthew G. Knepley   PetscFunctionBegin;
24696528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
24706528b96dSMatthew G. Knepley   PetscValidBoolPointer(hasBdJacPre, 2);
24719566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre));
24723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
247327f02ce8SMatthew G. Knepley }
247427f02ce8SMatthew G. Knepley 
247527f02ce8SMatthew G. Knepley /*@C
247627f02ce8SMatthew G. Knepley   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
247727f02ce8SMatthew G. Knepley 
2478*20f4b53cSBarry Smith   Not Collective; No Fortran Support
247927f02ce8SMatthew G. Knepley 
248027f02ce8SMatthew G. Knepley   Input Parameters:
2481dce8aebaSBarry Smith + ds - The `PetscDS`
248227f02ce8SMatthew G. Knepley . f  - The test field number
248327f02ce8SMatthew G. Knepley - g  - The field number
248427f02ce8SMatthew G. Knepley 
248527f02ce8SMatthew G. Knepley   Output Parameters:
248627f02ce8SMatthew G. Knepley + g0 - integrand for the test and basis function term
248727f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
248827f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
248927f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
249027f02ce8SMatthew G. Knepley 
2491*20f4b53cSBarry Smith    Calling sequence of `g0`, `g1`, `g2` and `g3`:
2492dce8aebaSBarry Smith .vb
2493*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2494dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2495dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2496dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2497dce8aebaSBarry Smith .ve
249827f02ce8SMatthew G. Knepley + dim - the spatial dimension
249927f02ce8SMatthew G. Knepley . Nf - the number of fields
250027f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
250127f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
250227f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
250327f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
250427f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
250527f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
250627f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
250727f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
250827f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
250927f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
251027f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
251127f02ce8SMatthew G. Knepley . t - current time
251227f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
251327f02ce8SMatthew G. Knepley . x - coordinates of the current point
251427f02ce8SMatthew G. Knepley . n - normal at the current point
251527f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
251627f02ce8SMatthew G. Knepley . constants - constant parameters
251727f02ce8SMatthew G. Knepley - g0 - output values at the current point
251827f02ce8SMatthew G. Knepley 
251927f02ce8SMatthew G. Knepley   Level: intermediate
252027f02ce8SMatthew G. Knepley 
2521dce8aebaSBarry Smith   Note:
2522dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2523dce8aebaSBarry 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
2524dce8aebaSBarry Smith 
2525dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetBdJacobianPreconditioner()`
252627f02ce8SMatthew G. Knepley @*/
2527d71ae5a4SJacob 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[]))
2528d71ae5a4SJacob Faibussowitsch {
25296528b96dSMatthew G. Knepley   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
25306528b96dSMatthew G. Knepley   PetscInt         n0, n1, n2, n3;
25316528b96dSMatthew G. Knepley 
253227f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25336528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
253463a3b9bcSJacob 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);
253563a3b9bcSJacob 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);
25369566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3));
25376528b96dSMatthew G. Knepley   *g0 = tmp0 ? tmp0[0] : NULL;
25386528b96dSMatthew G. Knepley   *g1 = tmp1 ? tmp1[0] : NULL;
25396528b96dSMatthew G. Knepley   *g2 = tmp2 ? tmp2[0] : NULL;
25406528b96dSMatthew G. Knepley   *g3 = tmp3 ? tmp3[0] : NULL;
25413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
254227f02ce8SMatthew G. Knepley }
254327f02ce8SMatthew G. Knepley 
254427f02ce8SMatthew G. Knepley /*@C
254527f02ce8SMatthew G. Knepley   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
254627f02ce8SMatthew G. Knepley 
2547*20f4b53cSBarry Smith   Not Collective; No Fortran Support
254827f02ce8SMatthew G. Knepley 
254927f02ce8SMatthew G. Knepley   Input Parameters:
2550dce8aebaSBarry Smith + ds - The `PetscDS`
255127f02ce8SMatthew G. Knepley . f  - The test field number
255227f02ce8SMatthew G. Knepley . g  - The field number
255327f02ce8SMatthew G. Knepley . g0 - integrand for the test and basis function term
255427f02ce8SMatthew G. Knepley . g1 - integrand for the test function and basis function gradient term
255527f02ce8SMatthew G. Knepley . g2 - integrand for the test function gradient and basis function term
255627f02ce8SMatthew G. Knepley - g3 - integrand for the test function gradient and basis function gradient term
255727f02ce8SMatthew G. Knepley 
2558*20f4b53cSBarry Smith    Calling sequence of `g0`, `g1`, `g2` and `g3`:
2559dce8aebaSBarry Smith .vb
2560*20f4b53cSBarry Smith   void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2561dce8aebaSBarry Smith           const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2562dce8aebaSBarry Smith           const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2563dce8aebaSBarry Smith           PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2564dce8aebaSBarry Smith .ve
256527f02ce8SMatthew G. Knepley + dim - the spatial dimension
256627f02ce8SMatthew G. Knepley . Nf - the number of fields
256727f02ce8SMatthew G. Knepley . NfAux - the number of auxiliary fields
256827f02ce8SMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
256927f02ce8SMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
257027f02ce8SMatthew G. Knepley . u - each field evaluated at the current point
257127f02ce8SMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
257227f02ce8SMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
257327f02ce8SMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
257427f02ce8SMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
257527f02ce8SMatthew G. Knepley . a - each auxiliary field evaluated at the current point
257627f02ce8SMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
257727f02ce8SMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
257827f02ce8SMatthew G. Knepley . t - current time
257927f02ce8SMatthew G. Knepley . u_tShift - the multiplier a for dF/dU_t
258027f02ce8SMatthew G. Knepley . x - coordinates of the current point
258127f02ce8SMatthew G. Knepley . n - normal at the current point
258227f02ce8SMatthew G. Knepley . numConstants - number of constant parameters
258327f02ce8SMatthew G. Knepley . constants - constant parameters
258427f02ce8SMatthew G. Knepley - g0 - output values at the current point
258527f02ce8SMatthew G. Knepley 
258627f02ce8SMatthew G. Knepley   Level: intermediate
258727f02ce8SMatthew G. Knepley 
2588dce8aebaSBarry Smith   Note:
2589dce8aebaSBarry Smith   We are using a first order FEM model for the weak form:
2590dce8aebaSBarry 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
2591dce8aebaSBarry Smith 
2592dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetBdJacobianPreconditioner()`
259327f02ce8SMatthew G. Knepley @*/
2594d71ae5a4SJacob 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[]))
2595d71ae5a4SJacob Faibussowitsch {
259627f02ce8SMatthew G. Knepley   PetscFunctionBegin;
25976528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
259827f02ce8SMatthew G. Knepley   if (g0) PetscValidFunction(g0, 4);
259927f02ce8SMatthew G. Knepley   if (g1) PetscValidFunction(g1, 5);
260027f02ce8SMatthew G. Knepley   if (g2) PetscValidFunction(g2, 6);
260127f02ce8SMatthew G. Knepley   if (g3) PetscValidFunction(g3, 7);
260263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
260363a3b9bcSJacob Faibussowitsch   PetscCheck(g >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", g);
26049566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3));
26053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
260627f02ce8SMatthew G. Knepley }
260727f02ce8SMatthew G. Knepley 
26080d3e9b51SMatthew G. Knepley /*@C
2609c371a6d1SMatthew G. Knepley   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2610c371a6d1SMatthew G. Knepley 
2611*20f4b53cSBarry Smith   Not Collective
2612c371a6d1SMatthew G. Knepley 
2613c371a6d1SMatthew G. Knepley   Input Parameters:
2614c371a6d1SMatthew G. Knepley + prob - The PetscDS
2615c371a6d1SMatthew G. Knepley - f    - The test field number
2616c371a6d1SMatthew G. Knepley 
2617d8d19677SJose E. Roman   Output Parameters:
261895cbbfd3SMatthew G. Knepley + exactSol - exact solution for the test field
261995cbbfd3SMatthew G. Knepley - exactCtx - exact solution context
2620c371a6d1SMatthew G. Knepley 
2621*20f4b53cSBarry Smith   Calling sequence of `exactSol`:
2622dce8aebaSBarry Smith .vb
2623*20f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2624dce8aebaSBarry Smith .ve
2625c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2626c371a6d1SMatthew G. Knepley . t - current time
2627c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2628c371a6d1SMatthew G. Knepley . Nc - the number of field components
2629c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2630c371a6d1SMatthew G. Knepley - ctx - a user context
2631c371a6d1SMatthew G. Knepley 
2632c371a6d1SMatthew G. Knepley   Level: intermediate
2633c371a6d1SMatthew G. Knepley 
2634dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolution()`, `PetscDSGetExactSolutionTimeDerivative()`
2635c371a6d1SMatthew G. Knepley @*/
2636d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2637d71ae5a4SJacob Faibussowitsch {
2638c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2639c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
264063a3b9bcSJacob 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);
26419371c9d4SSatish Balay   if (sol) {
26429371c9d4SSatish Balay     PetscValidPointer(sol, 3);
26439371c9d4SSatish Balay     *sol = prob->exactSol[f];
26449371c9d4SSatish Balay   }
26459371c9d4SSatish Balay   if (ctx) {
26469371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
26479371c9d4SSatish Balay     *ctx = prob->exactCtx[f];
26489371c9d4SSatish Balay   }
26493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2650c371a6d1SMatthew G. Knepley }
2651c371a6d1SMatthew G. Knepley 
2652c371a6d1SMatthew G. Knepley /*@C
2653578a5ef5SMatthew Knepley   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2654c371a6d1SMatthew G. Knepley 
2655*20f4b53cSBarry Smith   Not Collective
2656c371a6d1SMatthew G. Knepley 
2657c371a6d1SMatthew G. Knepley   Input Parameters:
2658dce8aebaSBarry Smith + prob - The `PetscDS`
2659c371a6d1SMatthew G. Knepley . f    - The test field number
266095cbbfd3SMatthew G. Knepley . sol  - solution function for the test fields
2661*20f4b53cSBarry Smith - ctx  - solution context or `NULL`
2662c371a6d1SMatthew G. Knepley 
2663*20f4b53cSBarry Smith   Calling sequence of `sol`:
2664dce8aebaSBarry Smith .vb
2665*20f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2666dce8aebaSBarry Smith .ve
2667c371a6d1SMatthew G. Knepley + dim - the spatial dimension
2668c371a6d1SMatthew G. Knepley . t - current time
2669c371a6d1SMatthew G. Knepley . x - coordinates of the current point
2670c371a6d1SMatthew G. Knepley . Nc - the number of field components
2671c371a6d1SMatthew G. Knepley . u - the solution field evaluated at the current point
2672c371a6d1SMatthew G. Knepley - ctx - a user context
2673c371a6d1SMatthew G. Knepley 
2674c371a6d1SMatthew G. Knepley   Level: intermediate
2675c371a6d1SMatthew G. Knepley 
2676dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolution()`
2677c371a6d1SMatthew G. Knepley @*/
2678d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2679d71ae5a4SJacob Faibussowitsch {
2680c371a6d1SMatthew G. Knepley   PetscFunctionBegin;
2681c371a6d1SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
268263a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
26839566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
26849371c9d4SSatish Balay   if (sol) {
26859371c9d4SSatish Balay     PetscValidFunction(sol, 3);
26869371c9d4SSatish Balay     prob->exactSol[f] = sol;
26879371c9d4SSatish Balay   }
26889371c9d4SSatish Balay   if (ctx) {
26899371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
26909371c9d4SSatish Balay     prob->exactCtx[f] = ctx;
26919371c9d4SSatish Balay   }
26923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2693c371a6d1SMatthew G. Knepley }
2694c371a6d1SMatthew G. Knepley 
26955638fd0eSMatthew G. Knepley /*@C
2696f2cacb80SMatthew G. Knepley   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2697f2cacb80SMatthew G. Knepley 
2698*20f4b53cSBarry Smith   Not Collective
2699f2cacb80SMatthew G. Knepley 
2700f2cacb80SMatthew G. Knepley   Input Parameters:
2701dce8aebaSBarry Smith + prob - The `PetscDS`
2702f2cacb80SMatthew G. Knepley - f    - The test field number
2703f2cacb80SMatthew G. Knepley 
2704d8d19677SJose E. Roman   Output Parameters:
2705f2cacb80SMatthew G. Knepley + exactSol - time derivative of the exact solution for the test field
2706f2cacb80SMatthew G. Knepley - exactCtx - time derivative of the exact solution context
2707f2cacb80SMatthew G. Knepley 
2708*20f4b53cSBarry Smith   Calling sequence of `exactSol`:
2709dce8aebaSBarry Smith .vb
2710*20f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2711dce8aebaSBarry Smith .ve
2712f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2713f2cacb80SMatthew G. Knepley . t - current time
2714f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2715f2cacb80SMatthew G. Knepley . Nc - the number of field components
2716f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2717f2cacb80SMatthew G. Knepley - ctx - a user context
2718f2cacb80SMatthew G. Knepley 
2719f2cacb80SMatthew G. Knepley   Level: intermediate
2720f2cacb80SMatthew G. Knepley 
2721dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetExactSolutionTimeDerivative()`, `PetscDSGetExactSolution()`
2722f2cacb80SMatthew G. Knepley @*/
2723d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2724d71ae5a4SJacob Faibussowitsch {
2725f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2726f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
272763a3b9bcSJacob 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);
27289371c9d4SSatish Balay   if (sol) {
27299371c9d4SSatish Balay     PetscValidPointer(sol, 3);
27309371c9d4SSatish Balay     *sol = prob->exactSol_t[f];
27319371c9d4SSatish Balay   }
27329371c9d4SSatish Balay   if (ctx) {
27339371c9d4SSatish Balay     PetscValidPointer(ctx, 4);
27349371c9d4SSatish Balay     *ctx = prob->exactCtx_t[f];
27359371c9d4SSatish Balay   }
27363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2737f2cacb80SMatthew G. Knepley }
2738f2cacb80SMatthew G. Knepley 
2739f2cacb80SMatthew G. Knepley /*@C
2740f2cacb80SMatthew G. Knepley   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2741f2cacb80SMatthew G. Knepley 
2742*20f4b53cSBarry Smith   Not Collective
2743f2cacb80SMatthew G. Knepley 
2744f2cacb80SMatthew G. Knepley   Input Parameters:
2745dce8aebaSBarry Smith + prob - The `PetscDS`
2746f2cacb80SMatthew G. Knepley . f    - The test field number
2747f2cacb80SMatthew G. Knepley . sol  - time derivative of the solution function for the test fields
2748*20f4b53cSBarry Smith - ctx  - time derivative of the solution context or `NULL`
2749f2cacb80SMatthew G. Knepley 
2750*20f4b53cSBarry Smith   Calling sequence of `sol`:
2751dce8aebaSBarry Smith .vb
2752*20f4b53cSBarry Smith   PetscErrorCode sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2753dce8aebaSBarry Smith .ve
2754f2cacb80SMatthew G. Knepley + dim - the spatial dimension
2755f2cacb80SMatthew G. Knepley . t - current time
2756f2cacb80SMatthew G. Knepley . x - coordinates of the current point
2757f2cacb80SMatthew G. Knepley . Nc - the number of field components
2758f2cacb80SMatthew G. Knepley . u - the solution field evaluated at the current point
2759f2cacb80SMatthew G. Knepley - ctx - a user context
2760f2cacb80SMatthew G. Knepley 
2761f2cacb80SMatthew G. Knepley   Level: intermediate
2762f2cacb80SMatthew G. Knepley 
2763dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetExactSolutionTimeDerivative()`, `PetscDSSetExactSolution()`
2764f2cacb80SMatthew G. Knepley @*/
2765d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2766d71ae5a4SJacob Faibussowitsch {
2767f2cacb80SMatthew G. Knepley   PetscFunctionBegin;
2768f2cacb80SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
276963a3b9bcSJacob Faibussowitsch   PetscCheck(f >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %" PetscInt_FMT " must be non-negative", f);
27709566063dSJacob Faibussowitsch   PetscCall(PetscDSEnlarge_Static(prob, f + 1));
27719371c9d4SSatish Balay   if (sol) {
27729371c9d4SSatish Balay     PetscValidFunction(sol, 3);
27739371c9d4SSatish Balay     prob->exactSol_t[f] = sol;
27749371c9d4SSatish Balay   }
27759371c9d4SSatish Balay   if (ctx) {
27769371c9d4SSatish Balay     PetscValidFunction(ctx, 4);
27779371c9d4SSatish Balay     prob->exactCtx_t[f] = ctx;
27789371c9d4SSatish Balay   }
27793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2780f2cacb80SMatthew G. Knepley }
2781f2cacb80SMatthew G. Knepley 
2782f2cacb80SMatthew G. Knepley /*@C
278397b6e6e8SMatthew G. Knepley   PetscDSGetConstants - Returns the array of constants passed to point functions
278497b6e6e8SMatthew G. Knepley 
2785*20f4b53cSBarry Smith   Not Collective
278697b6e6e8SMatthew G. Knepley 
278797b6e6e8SMatthew G. Knepley   Input Parameter:
2788dce8aebaSBarry Smith . prob - The `PetscDS` object
278997b6e6e8SMatthew G. Knepley 
279097b6e6e8SMatthew G. Knepley   Output Parameters:
279197b6e6e8SMatthew G. Knepley + numConstants - The number of constants
279297b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
279397b6e6e8SMatthew G. Knepley 
279497b6e6e8SMatthew G. Knepley   Level: intermediate
279597b6e6e8SMatthew G. Knepley 
2796dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSetConstants()`, `PetscDSCreate()`
279797b6e6e8SMatthew G. Knepley @*/
2798d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2799d71ae5a4SJacob Faibussowitsch {
280097b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
280197b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
28029371c9d4SSatish Balay   if (numConstants) {
28039371c9d4SSatish Balay     PetscValidIntPointer(numConstants, 2);
28049371c9d4SSatish Balay     *numConstants = prob->numConstants;
28059371c9d4SSatish Balay   }
28069371c9d4SSatish Balay   if (constants) {
28079371c9d4SSatish Balay     PetscValidPointer(constants, 3);
28089371c9d4SSatish Balay     *constants = prob->constants;
28099371c9d4SSatish Balay   }
28103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
281197b6e6e8SMatthew G. Knepley }
281297b6e6e8SMatthew G. Knepley 
28130d3e9b51SMatthew G. Knepley /*@C
281497b6e6e8SMatthew G. Knepley   PetscDSSetConstants - Set the array of constants passed to point functions
281597b6e6e8SMatthew G. Knepley 
2816*20f4b53cSBarry Smith   Not Collective
281797b6e6e8SMatthew G. Knepley 
281897b6e6e8SMatthew G. Knepley   Input Parameters:
2819dce8aebaSBarry Smith + prob         - The `PetscDS` object
282097b6e6e8SMatthew G. Knepley . numConstants - The number of constants
282197b6e6e8SMatthew G. Knepley - constants    - The array of constants, NULL if there are none
282297b6e6e8SMatthew G. Knepley 
282397b6e6e8SMatthew G. Knepley   Level: intermediate
282497b6e6e8SMatthew G. Knepley 
2825dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetConstants()`, `PetscDSCreate()`
282697b6e6e8SMatthew G. Knepley @*/
2827d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2828d71ae5a4SJacob Faibussowitsch {
282997b6e6e8SMatthew G. Knepley   PetscFunctionBegin;
283097b6e6e8SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
283197b6e6e8SMatthew G. Knepley   if (numConstants != prob->numConstants) {
28329566063dSJacob Faibussowitsch     PetscCall(PetscFree(prob->constants));
283397b6e6e8SMatthew G. Knepley     prob->numConstants = numConstants;
283497b6e6e8SMatthew G. Knepley     if (prob->numConstants) {
28359566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(prob->numConstants, &prob->constants));
283620be0f5bSMatthew G. Knepley     } else {
283720be0f5bSMatthew G. Knepley       prob->constants = NULL;
283820be0f5bSMatthew G. Knepley     }
283920be0f5bSMatthew G. Knepley   }
284020be0f5bSMatthew G. Knepley   if (prob->numConstants) {
2841dadcf809SJacob Faibussowitsch     PetscValidScalarPointer(constants, 3);
28429566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(prob->constants, constants, prob->numConstants));
284397b6e6e8SMatthew G. Knepley   }
28443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
284597b6e6e8SMatthew G. Knepley }
284697b6e6e8SMatthew G. Knepley 
28474cd1e086SMatthew G. Knepley /*@
28484cd1e086SMatthew G. Knepley   PetscDSGetFieldIndex - Returns the index of the given field
28494cd1e086SMatthew G. Knepley 
2850*20f4b53cSBarry Smith   Not Collective
28514cd1e086SMatthew G. Knepley 
28524cd1e086SMatthew G. Knepley   Input Parameters:
2853dce8aebaSBarry Smith + prob - The `PetscDS` object
28544cd1e086SMatthew G. Knepley - disc - The discretization object
28554cd1e086SMatthew G. Knepley 
28564cd1e086SMatthew G. Knepley   Output Parameter:
28574cd1e086SMatthew G. Knepley . f - The field number
28584cd1e086SMatthew G. Knepley 
28594cd1e086SMatthew G. Knepley   Level: beginner
28604cd1e086SMatthew G. Knepley 
2861dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscGetDiscretization()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28624cd1e086SMatthew G. Knepley @*/
2863d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2864d71ae5a4SJacob Faibussowitsch {
28654cd1e086SMatthew G. Knepley   PetscInt g;
28664cd1e086SMatthew G. Knepley 
28674cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28684cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2869dadcf809SJacob Faibussowitsch   PetscValidIntPointer(f, 3);
28704cd1e086SMatthew G. Knepley   *f = -1;
28719371c9d4SSatish Balay   for (g = 0; g < prob->Nf; ++g) {
28729371c9d4SSatish Balay     if (disc == prob->disc[g]) break;
28739371c9d4SSatish Balay   }
287408401ef6SPierre Jolivet   PetscCheck(g != prob->Nf, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
28754cd1e086SMatthew G. Knepley   *f = g;
28763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28774cd1e086SMatthew G. Knepley }
28784cd1e086SMatthew G. Knepley 
28794cd1e086SMatthew G. Knepley /*@
28804cd1e086SMatthew G. Knepley   PetscDSGetFieldSize - Returns the size of the given field in the full space basis
28814cd1e086SMatthew G. Knepley 
2882*20f4b53cSBarry Smith   Not Collective
28834cd1e086SMatthew G. Knepley 
28844cd1e086SMatthew G. Knepley   Input Parameters:
2885dce8aebaSBarry Smith + prob - The `PetscDS` object
28864cd1e086SMatthew G. Knepley - f - The field number
28874cd1e086SMatthew G. Knepley 
28884cd1e086SMatthew G. Knepley   Output Parameter:
28894cd1e086SMatthew G. Knepley . size - The size
28904cd1e086SMatthew G. Knepley 
28914cd1e086SMatthew G. Knepley   Level: beginner
28924cd1e086SMatthew G. Knepley 
2893dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldOffset()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
28944cd1e086SMatthew G. Knepley @*/
2895d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2896d71ae5a4SJacob Faibussowitsch {
28974cd1e086SMatthew G. Knepley   PetscFunctionBegin;
28984cd1e086SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2899dadcf809SJacob Faibussowitsch   PetscValidIntPointer(size, 3);
290063a3b9bcSJacob 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);
29019566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
2902d4742ddaSMatthew G. Knepley   *size = prob->Nb[f];
29033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29044cd1e086SMatthew G. Knepley }
29054cd1e086SMatthew G. Knepley 
2906bc4ae4beSMatthew G. Knepley /*@
2907bc4ae4beSMatthew G. Knepley   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2908bc4ae4beSMatthew G. Knepley 
2909*20f4b53cSBarry Smith   Not Collective
2910bc4ae4beSMatthew G. Knepley 
2911bc4ae4beSMatthew G. Knepley   Input Parameters:
2912dce8aebaSBarry Smith + prob - The `PetscDS` object
2913bc4ae4beSMatthew G. Knepley - f - The field number
2914bc4ae4beSMatthew G. Knepley 
2915bc4ae4beSMatthew G. Knepley   Output Parameter:
2916bc4ae4beSMatthew G. Knepley . off - The offset
2917bc4ae4beSMatthew G. Knepley 
2918bc4ae4beSMatthew G. Knepley   Level: beginner
2919bc4ae4beSMatthew G. Knepley 
2920dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2921bc4ae4beSMatthew G. Knepley @*/
2922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2923d71ae5a4SJacob Faibussowitsch {
29244cd1e086SMatthew G. Knepley   PetscInt size, g;
29252764a2aaSMatthew G. Knepley 
29262764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29272764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2928dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
292963a3b9bcSJacob 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);
29302764a2aaSMatthew G. Knepley   *off = 0;
29312764a2aaSMatthew G. Knepley   for (g = 0; g < f; ++g) {
29329566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(prob, g, &size));
29334cd1e086SMatthew G. Knepley     *off += size;
29342764a2aaSMatthew G. Knepley   }
29353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29362764a2aaSMatthew G. Knepley }
29372764a2aaSMatthew G. Knepley 
2938bc4ae4beSMatthew G. Knepley /*@
29395fedec97SMatthew G. Knepley   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
29405fedec97SMatthew G. Knepley 
2941*20f4b53cSBarry Smith   Not Collective
29425fedec97SMatthew G. Knepley 
29435fedec97SMatthew G. Knepley   Input Parameters:
2944dce8aebaSBarry Smith + prob - The `PetscDS` object
29455fedec97SMatthew G. Knepley - f - The field number
29465fedec97SMatthew G. Knepley 
29475fedec97SMatthew G. Knepley   Output Parameter:
29485fedec97SMatthew G. Knepley . off - The offset
29495fedec97SMatthew G. Knepley 
29505fedec97SMatthew G. Knepley   Level: beginner
29515fedec97SMatthew G. Knepley 
2952dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetFieldSize()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
29535fedec97SMatthew G. Knepley @*/
2954d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2955d71ae5a4SJacob Faibussowitsch {
29565fedec97SMatthew G. Knepley   PetscInt size, g;
29575fedec97SMatthew G. Knepley 
29585fedec97SMatthew G. Knepley   PetscFunctionBegin;
29595fedec97SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
2960dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
296163a3b9bcSJacob 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);
29625fedec97SMatthew G. Knepley   *off = 0;
29635fedec97SMatthew G. Knepley   for (g = 0; g < f; ++g) {
29645fedec97SMatthew G. Knepley     PetscBool cohesive;
29655fedec97SMatthew G. Knepley 
29669566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCohesive(ds, g, &cohesive));
29679566063dSJacob Faibussowitsch     PetscCall(PetscDSGetFieldSize(ds, g, &size));
29685fedec97SMatthew G. Knepley     *off += cohesive ? size : size * 2;
29695fedec97SMatthew G. Knepley   }
29703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29715fedec97SMatthew G. Knepley }
29725fedec97SMatthew G. Knepley 
29735fedec97SMatthew G. Knepley /*@
297447e57110SSander Arens   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2975bc4ae4beSMatthew G. Knepley 
2976*20f4b53cSBarry Smith   Not Collective
2977bc4ae4beSMatthew G. Knepley 
297847e57110SSander Arens   Input Parameter:
2979dce8aebaSBarry Smith . prob - The `PetscDS` object
2980bc4ae4beSMatthew G. Knepley 
2981bc4ae4beSMatthew G. Knepley   Output Parameter:
298247e57110SSander Arens . dimensions - The number of dimensions
2983bc4ae4beSMatthew G. Knepley 
2984bc4ae4beSMatthew G. Knepley   Level: beginner
2985bc4ae4beSMatthew G. Knepley 
2986dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
2987bc4ae4beSMatthew G. Knepley @*/
2988d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2989d71ae5a4SJacob Faibussowitsch {
29902764a2aaSMatthew G. Knepley   PetscFunctionBegin;
29912764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
29929566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
299347e57110SSander Arens   PetscValidPointer(dimensions, 2);
299447e57110SSander Arens   *dimensions = prob->Nb;
29953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29966ce16762SMatthew G. Knepley }
299747e57110SSander Arens 
299847e57110SSander Arens /*@
299947e57110SSander Arens   PetscDSGetComponents - Returns the number of components for each field on an evaluation point
300047e57110SSander Arens 
3001*20f4b53cSBarry Smith   Not Collective
300247e57110SSander Arens 
300347e57110SSander Arens   Input Parameter:
3004dce8aebaSBarry Smith . prob - The `PetscDS` object
300547e57110SSander Arens 
300647e57110SSander Arens   Output Parameter:
300747e57110SSander Arens . components - The number of components
300847e57110SSander Arens 
300947e57110SSander Arens   Level: beginner
301047e57110SSander Arens 
3011dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetComponentOffsets()`, `PetscDSGetNumFields()`, `PetscDSCreate()`
301247e57110SSander Arens @*/
3013d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3014d71ae5a4SJacob Faibussowitsch {
301547e57110SSander Arens   PetscFunctionBegin;
301647e57110SSander Arens   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
30179566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
301847e57110SSander Arens   PetscValidPointer(components, 2);
301947e57110SSander Arens   *components = prob->Nc;
30203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30216ce16762SMatthew G. Knepley }
30226ce16762SMatthew G. Knepley 
30236ce16762SMatthew G. Knepley /*@
30246ce16762SMatthew G. Knepley   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
30256ce16762SMatthew G. Knepley 
3026*20f4b53cSBarry Smith   Not Collective
30276ce16762SMatthew G. Knepley 
30286ce16762SMatthew G. Knepley   Input Parameters:
3029dce8aebaSBarry Smith + prob - The `PetscDS` object
30306ce16762SMatthew G. Knepley - f - The field number
30316ce16762SMatthew G. Knepley 
30326ce16762SMatthew G. Knepley   Output Parameter:
30336ce16762SMatthew G. Knepley . off - The offset
30346ce16762SMatthew G. Knepley 
30356ce16762SMatthew G. Knepley   Level: beginner
30366ce16762SMatthew G. Knepley 
3037dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
30386ce16762SMatthew G. Knepley @*/
3039d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3040d71ae5a4SJacob Faibussowitsch {
30416ce16762SMatthew G. Knepley   PetscFunctionBegin;
30426ce16762SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3043dadcf809SJacob Faibussowitsch   PetscValidIntPointer(off, 3);
304463a3b9bcSJacob 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);
30459566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
304647e57110SSander Arens   *off = prob->off[f];
30473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30482764a2aaSMatthew G. Knepley }
30492764a2aaSMatthew G. Knepley 
3050194d53e6SMatthew G. Knepley /*@
3051194d53e6SMatthew G. Knepley   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3052194d53e6SMatthew G. Knepley 
3053*20f4b53cSBarry Smith   Not Collective
3054194d53e6SMatthew G. Knepley 
3055194d53e6SMatthew G. Knepley   Input Parameter:
3056dce8aebaSBarry Smith . prob - The `PetscDS` object
3057194d53e6SMatthew G. Knepley 
3058194d53e6SMatthew G. Knepley   Output Parameter:
3059194d53e6SMatthew G. Knepley . offsets - The offsets
3060194d53e6SMatthew G. Knepley 
3061194d53e6SMatthew G. Knepley   Level: beginner
3062194d53e6SMatthew G. Knepley 
3063dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3064194d53e6SMatthew G. Knepley @*/
3065d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3066d71ae5a4SJacob Faibussowitsch {
3067194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3068194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3069194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
30709566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3071194d53e6SMatthew G. Knepley   *offsets = prob->off;
30723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3073194d53e6SMatthew G. Knepley }
3074194d53e6SMatthew G. Knepley 
3075194d53e6SMatthew G. Knepley /*@
3076194d53e6SMatthew G. Knepley   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3077194d53e6SMatthew G. Knepley 
3078*20f4b53cSBarry Smith   Not Collective
3079194d53e6SMatthew G. Knepley 
3080194d53e6SMatthew G. Knepley   Input Parameter:
3081dce8aebaSBarry Smith . prob - The `PetscDS` object
3082194d53e6SMatthew G. Knepley 
3083194d53e6SMatthew G. Knepley   Output Parameter:
3084194d53e6SMatthew G. Knepley . offsets - The offsets
3085194d53e6SMatthew G. Knepley 
3086194d53e6SMatthew G. Knepley   Level: beginner
3087194d53e6SMatthew G. Knepley 
3088dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
3089194d53e6SMatthew G. Knepley @*/
3090d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3091d71ae5a4SJacob Faibussowitsch {
3092194d53e6SMatthew G. Knepley   PetscFunctionBegin;
3093194d53e6SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3094194d53e6SMatthew G. Knepley   PetscValidPointer(offsets, 2);
30959566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3096194d53e6SMatthew G. Knepley   *offsets = prob->offDer;
30973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3098194d53e6SMatthew G. Knepley }
3099194d53e6SMatthew G. Knepley 
31009ee2af8cSMatthew G. Knepley /*@
31019ee2af8cSMatthew G. Knepley   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
31029ee2af8cSMatthew G. Knepley 
3103*20f4b53cSBarry Smith   Not Collective
31049ee2af8cSMatthew G. Knepley 
31059ee2af8cSMatthew G. Knepley   Input Parameters:
3106dce8aebaSBarry Smith + ds - The `PetscDS` object
31079ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31089ee2af8cSMatthew G. Knepley 
31099ee2af8cSMatthew G. Knepley   Output Parameter:
31109ee2af8cSMatthew G. Knepley . offsets - The offsets
31119ee2af8cSMatthew G. Knepley 
31129ee2af8cSMatthew G. Knepley   Level: beginner
31139ee2af8cSMatthew G. Knepley 
3114dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31159ee2af8cSMatthew G. Knepley @*/
3116d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3117d71ae5a4SJacob Faibussowitsch {
31189ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31199ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31209ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
312128b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
312263a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31239566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31249ee2af8cSMatthew G. Knepley   *offsets = ds->offCohesive[s];
31253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31269ee2af8cSMatthew G. Knepley }
31279ee2af8cSMatthew G. Knepley 
31289ee2af8cSMatthew G. Knepley /*@
31299ee2af8cSMatthew G. Knepley   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
31309ee2af8cSMatthew G. Knepley 
3131*20f4b53cSBarry Smith   Not Collective
31329ee2af8cSMatthew G. Knepley 
31339ee2af8cSMatthew G. Knepley   Input Parameters:
3134dce8aebaSBarry Smith + ds - The `PetscDS` object
31359ee2af8cSMatthew G. Knepley - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
31369ee2af8cSMatthew G. Knepley 
31379ee2af8cSMatthew G. Knepley   Output Parameter:
31389ee2af8cSMatthew G. Knepley . offsets - The offsets
31399ee2af8cSMatthew G. Knepley 
31409ee2af8cSMatthew G. Knepley   Level: beginner
31419ee2af8cSMatthew G. Knepley 
3142dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSGetNumFields()`, `PetscDSCreate()`
31439ee2af8cSMatthew G. Knepley @*/
3144d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3145d71ae5a4SJacob Faibussowitsch {
31469ee2af8cSMatthew G. Knepley   PetscFunctionBegin;
31479ee2af8cSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
31489ee2af8cSMatthew G. Knepley   PetscValidPointer(offsets, 3);
314928b400f6SJacob Faibussowitsch   PetscCheck(ds->isCohesive, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cohesive offsets are only valid for a cohesive DS");
315063a3b9bcSJacob Faibussowitsch   PetscCheck(!(s < 0) && !(s > 2), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cohesive side %" PetscInt_FMT " is not in [0, 2]", s);
31519566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(ds));
31529ee2af8cSMatthew G. Knepley   *offsets = ds->offDerCohesive[s];
31533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31549ee2af8cSMatthew G. Knepley }
31559ee2af8cSMatthew G. Knepley 
315668c9edb9SMatthew G. Knepley /*@C
315768c9edb9SMatthew G. Knepley   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
315868c9edb9SMatthew G. Knepley 
3159*20f4b53cSBarry Smith   Not Collective
316068c9edb9SMatthew G. Knepley 
316168c9edb9SMatthew G. Knepley   Input Parameter:
3162dce8aebaSBarry Smith . prob - The `PetscDS` object
316368c9edb9SMatthew G. Knepley 
3164ef0bb6c7SMatthew G. Knepley   Output Parameter:
3165ef0bb6c7SMatthew G. Knepley . T - The basis function and derivatives tabulation at quadrature points for each field
316668c9edb9SMatthew G. Knepley 
316768c9edb9SMatthew G. Knepley   Level: intermediate
316868c9edb9SMatthew G. Knepley 
3169dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscTabulation`, `PetscDSCreate()`
317068c9edb9SMatthew G. Knepley @*/
3171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3172d71ae5a4SJacob Faibussowitsch {
31732764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31742764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3175ef0bb6c7SMatthew G. Knepley   PetscValidPointer(T, 2);
31769566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3177ef0bb6c7SMatthew G. Knepley   *T = prob->T;
31783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31792764a2aaSMatthew G. Knepley }
31802764a2aaSMatthew G. Knepley 
318168c9edb9SMatthew G. Knepley /*@C
31824d0b9603SSander Arens   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
318368c9edb9SMatthew G. Knepley 
3184*20f4b53cSBarry Smith   Not Collective
318568c9edb9SMatthew G. Knepley 
318668c9edb9SMatthew G. Knepley   Input Parameter:
3187dce8aebaSBarry Smith . prob - The `PetscDS` object
318868c9edb9SMatthew G. Knepley 
3189ef0bb6c7SMatthew G. Knepley   Output Parameter:
3190a5b23f4aSJose E. Roman . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
319168c9edb9SMatthew G. Knepley 
319268c9edb9SMatthew G. Knepley   Level: intermediate
319368c9edb9SMatthew G. Knepley 
3194dce8aebaSBarry Smith .seealso: `PetscTabulation`, `PetscDS`, `PetscDSGetTabulation()`, `PetscDSCreate()`
319568c9edb9SMatthew G. Knepley @*/
3196d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3197d71ae5a4SJacob Faibussowitsch {
31982764a2aaSMatthew G. Knepley   PetscFunctionBegin;
31992764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3200ef0bb6c7SMatthew G. Knepley   PetscValidPointer(Tf, 2);
32019566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
3202ef0bb6c7SMatthew G. Knepley   *Tf = prob->Tf;
32033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32042764a2aaSMatthew G. Knepley }
32052764a2aaSMatthew G. Knepley 
3206d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3207d71ae5a4SJacob Faibussowitsch {
32082764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32092764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32109566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32119371c9d4SSatish Balay   if (u) {
32129371c9d4SSatish Balay     PetscValidPointer(u, 2);
32139371c9d4SSatish Balay     *u = prob->u;
32149371c9d4SSatish Balay   }
32159371c9d4SSatish Balay   if (u_t) {
32169371c9d4SSatish Balay     PetscValidPointer(u_t, 3);
32179371c9d4SSatish Balay     *u_t = prob->u_t;
32189371c9d4SSatish Balay   }
32199371c9d4SSatish Balay   if (u_x) {
32209371c9d4SSatish Balay     PetscValidPointer(u_x, 4);
32219371c9d4SSatish Balay     *u_x = prob->u_x;
32229371c9d4SSatish Balay   }
32233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32242764a2aaSMatthew G. Knepley }
32252764a2aaSMatthew G. Knepley 
3226d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3227d71ae5a4SJacob Faibussowitsch {
32282764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32292764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32309566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32319371c9d4SSatish Balay   if (f0) {
32329371c9d4SSatish Balay     PetscValidPointer(f0, 2);
32339371c9d4SSatish Balay     *f0 = prob->f0;
32349371c9d4SSatish Balay   }
32359371c9d4SSatish Balay   if (f1) {
32369371c9d4SSatish Balay     PetscValidPointer(f1, 3);
32379371c9d4SSatish Balay     *f1 = prob->f1;
32389371c9d4SSatish Balay   }
32399371c9d4SSatish Balay   if (g0) {
32409371c9d4SSatish Balay     PetscValidPointer(g0, 4);
32419371c9d4SSatish Balay     *g0 = prob->g0;
32429371c9d4SSatish Balay   }
32439371c9d4SSatish Balay   if (g1) {
32449371c9d4SSatish Balay     PetscValidPointer(g1, 5);
32459371c9d4SSatish Balay     *g1 = prob->g1;
32469371c9d4SSatish Balay   }
32479371c9d4SSatish Balay   if (g2) {
32489371c9d4SSatish Balay     PetscValidPointer(g2, 6);
32499371c9d4SSatish Balay     *g2 = prob->g2;
32509371c9d4SSatish Balay   }
32519371c9d4SSatish Balay   if (g3) {
32529371c9d4SSatish Balay     PetscValidPointer(g3, 7);
32539371c9d4SSatish Balay     *g3 = prob->g3;
32549371c9d4SSatish Balay   }
32553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32562764a2aaSMatthew G. Knepley }
32572764a2aaSMatthew G. Knepley 
3258d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3259d71ae5a4SJacob Faibussowitsch {
32602764a2aaSMatthew G. Knepley   PetscFunctionBegin;
32612764a2aaSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
32629566063dSJacob Faibussowitsch   PetscCall(PetscDSSetUp(prob));
32639371c9d4SSatish Balay   if (x) {
32649371c9d4SSatish Balay     PetscValidPointer(x, 2);
32659371c9d4SSatish Balay     *x = prob->x;
32669371c9d4SSatish Balay   }
32679371c9d4SSatish Balay   if (basisReal) {
32689371c9d4SSatish Balay     PetscValidPointer(basisReal, 3);
32699371c9d4SSatish Balay     *basisReal = prob->basisReal;
32709371c9d4SSatish Balay   }
32719371c9d4SSatish Balay   if (basisDerReal) {
32729371c9d4SSatish Balay     PetscValidPointer(basisDerReal, 4);
32739371c9d4SSatish Balay     *basisDerReal = prob->basisDerReal;
32749371c9d4SSatish Balay   }
32759371c9d4SSatish Balay   if (testReal) {
32769371c9d4SSatish Balay     PetscValidPointer(testReal, 5);
32779371c9d4SSatish Balay     *testReal = prob->testReal;
32789371c9d4SSatish Balay   }
32799371c9d4SSatish Balay   if (testDerReal) {
32809371c9d4SSatish Balay     PetscValidPointer(testDerReal, 6);
32819371c9d4SSatish Balay     *testDerReal = prob->testDerReal;
32829371c9d4SSatish Balay   }
32833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32842764a2aaSMatthew G. Knepley }
32852764a2aaSMatthew G. Knepley 
328658ebd649SToby Isaac /*@C
3287dce8aebaSBarry Smith   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3288dce8aebaSBarry 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
3289dce8aebaSBarry Smith   integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
329058ebd649SToby Isaac 
3291*20f4b53cSBarry Smith   Collective
3292783e2ec8SMatthew G. Knepley 
329358ebd649SToby Isaac   Input Parameters:
329458ebd649SToby Isaac + ds       - The PetscDS object
3295dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
329658ebd649SToby Isaac . name     - The BC name
329745480ffeSMatthew G. Knepley . label    - The label defining constrained points
3298dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
329945480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
330058ebd649SToby Isaac . field    - The field to constrain
330145480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
330258ebd649SToby Isaac . comps    - An array of constrained component numbers
330358ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3304a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
330558ebd649SToby Isaac - ctx      - An optional user context for bcFunc
330658ebd649SToby Isaac 
330745480ffeSMatthew G. Knepley   Output Parameters:
330845480ffeSMatthew G. Knepley - bd       - The boundary number
330945480ffeSMatthew G. Knepley 
331058ebd649SToby Isaac   Options Database Keys:
331158ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
331258ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
331358ebd649SToby Isaac 
3314dce8aebaSBarry Smith   Level: developer
3315dce8aebaSBarry Smith 
331656cf3b9cSMatthew G. Knepley   Note:
3317*20f4b53cSBarry 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:
331856cf3b9cSMatthew G. Knepley 
3319*20f4b53cSBarry Smith $ void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
332056cf3b9cSMatthew G. Knepley 
3321dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value, then the calling sequence is:
3322dce8aebaSBarry Smith .vb
3323*20f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3324dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3325dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3326dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3327dce8aebaSBarry Smith .ve
332856cf3b9cSMatthew G. Knepley + dim - the spatial dimension
332956cf3b9cSMatthew G. Knepley . Nf - the number of fields
333056cf3b9cSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
333156cf3b9cSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
333256cf3b9cSMatthew G. Knepley . u - each field evaluated at the current point
333356cf3b9cSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
333456cf3b9cSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
333556cf3b9cSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
333656cf3b9cSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
333756cf3b9cSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
333856cf3b9cSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
333956cf3b9cSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
334056cf3b9cSMatthew G. Knepley . t - current time
334156cf3b9cSMatthew G. Knepley . x - coordinates of the current point
334256cf3b9cSMatthew G. Knepley . numConstants - number of constant parameters
334356cf3b9cSMatthew G. Knepley . constants - constant parameters
334456cf3b9cSMatthew G. Knepley - bcval - output values at the current point
334556cf3b9cSMatthew G. Knepley 
3346dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundaryByName()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
334758ebd649SToby Isaac @*/
3348d71ae5a4SJacob 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)
3349d71ae5a4SJacob Faibussowitsch {
335045480ffeSMatthew G. Knepley   DSBoundary  head = ds->boundary, b;
335145480ffeSMatthew G. Knepley   PetscInt    n    = 0;
335245480ffeSMatthew G. Knepley   const char *lname;
335358ebd649SToby Isaac 
335458ebd649SToby Isaac   PetscFunctionBegin;
335558ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3356783e2ec8SMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
335745480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
335845480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
335945480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
336045480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
336145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
3362dce9da9cSMatthew 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);
3363d57bb9dbSMatthew G. Knepley   if (Nc > 0) {
3364d57bb9dbSMatthew G. Knepley     PetscInt *fcomps;
3365d57bb9dbSMatthew G. Knepley     PetscInt  c;
3366d57bb9dbSMatthew G. Knepley 
33679566063dSJacob Faibussowitsch     PetscCall(PetscDSGetComponents(ds, &fcomps));
336863a3b9bcSJacob 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);
3369d57bb9dbSMatthew G. Knepley     for (c = 0; c < Nc; ++c) {
33701dca8a05SBarry 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);
3371d57bb9dbSMatthew G. Knepley     }
3372d57bb9dbSMatthew G. Knepley   }
33739566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
33749566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
33759566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
33769566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
33779566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
33789566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
33799566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
33809566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
33819566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetName((PetscObject)label, &lname));
33829566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
3383f971fd6bSMatthew G. Knepley   b->type   = type;
338445480ffeSMatthew G. Knepley   b->label  = label;
338545480ffeSMatthew G. Knepley   b->Nv     = Nv;
338658ebd649SToby Isaac   b->field  = field;
338745480ffeSMatthew G. Knepley   b->Nc     = Nc;
338858ebd649SToby Isaac   b->func   = bcFunc;
338956cf3b9cSMatthew G. Knepley   b->func_t = bcFunc_t;
339058ebd649SToby Isaac   b->ctx    = ctx;
339145480ffeSMatthew G. Knepley   b->next   = NULL;
339245480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
339345480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
339445480ffeSMatthew G. Knepley   while (head) {
339545480ffeSMatthew G. Knepley     if (!head->next) {
339645480ffeSMatthew G. Knepley       head->next = b;
339745480ffeSMatthew G. Knepley       head       = b;
339845480ffeSMatthew G. Knepley     }
339945480ffeSMatthew G. Knepley     head = head->next;
340045480ffeSMatthew G. Knepley     ++n;
340145480ffeSMatthew G. Knepley   }
34029371c9d4SSatish Balay   if (bd) {
34039371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
34049371c9d4SSatish Balay     *bd = n;
34059371c9d4SSatish Balay   }
34063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
340745480ffeSMatthew G. Knepley }
340845480ffeSMatthew G. Knepley 
340945480ffeSMatthew G. Knepley /*@C
3410dce8aebaSBarry Smith   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3411dce8aebaSBarry 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
3412dce8aebaSBarry Smith   boundary integrals should be performed, using the kernels from `PetscDSSetBdResidual()`.
341345480ffeSMatthew G. Knepley 
3414*20f4b53cSBarry Smith   Collective
341545480ffeSMatthew G. Knepley 
341645480ffeSMatthew G. Knepley   Input Parameters:
3417dce8aebaSBarry Smith + ds       - The `PetscDS` object
3418dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
341945480ffeSMatthew G. Knepley . name     - The BC name
342045480ffeSMatthew G. Knepley . lname    - The naem of the label defining constrained points
3421dce8aebaSBarry Smith . Nv       - The number of `DMLabel` values for constrained points
342245480ffeSMatthew G. Knepley . values   - An array of label values for constrained points
342345480ffeSMatthew G. Knepley . field    - The field to constrain
342445480ffeSMatthew G. Knepley . Nc       - The number of constrained field components (0 will constrain all fields)
342545480ffeSMatthew G. Knepley . comps    - An array of constrained component numbers
342645480ffeSMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3427a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
342845480ffeSMatthew G. Knepley - ctx      - An optional user context for bcFunc
342945480ffeSMatthew G. Knepley 
343045480ffeSMatthew G. Knepley   Output Parameters:
343145480ffeSMatthew G. Knepley - bd       - The boundary number
343245480ffeSMatthew G. Knepley 
343345480ffeSMatthew G. Knepley   Options Database Keys:
343445480ffeSMatthew G. Knepley + -bc_<boundary name> <num> - Overrides the boundary ids
343545480ffeSMatthew G. Knepley - -bc_<boundary name>_comp <num> - Overrides the boundary components
343645480ffeSMatthew G. Knepley 
3437*20f4b53cSBarry Smith   Calling Sequence of `bcFunc` and `bcFunc_t`:
3438dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL`
3439dce8aebaSBarry Smith .vb
3440*20f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3441dce8aebaSBarry Smith .ve
3442dce8aebaSBarry Smith   If the type is `DM_BC_ESSENTIAL_FIELD` or other _FIELD value,
3443dce8aebaSBarry Smith .vb
3444*20f4b53cSBarry Smith   void bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3445dce8aebaSBarry Smith               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3446dce8aebaSBarry Smith               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3447dce8aebaSBarry Smith               PetscReal time, const PetscReal x[], PetscScalar bcval[])
3448dce8aebaSBarry Smith .ve
344945480ffeSMatthew G. Knepley + dim - the spatial dimension
345045480ffeSMatthew G. Knepley . Nf - the number of fields
345145480ffeSMatthew G. Knepley . uOff - the offset into u[] and u_t[] for each field
345245480ffeSMatthew G. Knepley . uOff_x - the offset into u_x[] for each field
345345480ffeSMatthew G. Knepley . u - each field evaluated at the current point
345445480ffeSMatthew G. Knepley . u_t - the time derivative of each field evaluated at the current point
345545480ffeSMatthew G. Knepley . u_x - the gradient of each field evaluated at the current point
345645480ffeSMatthew G. Knepley . aOff - the offset into a[] and a_t[] for each auxiliary field
345745480ffeSMatthew G. Knepley . aOff_x - the offset into a_x[] for each auxiliary field
345845480ffeSMatthew G. Knepley . a - each auxiliary field evaluated at the current point
345945480ffeSMatthew G. Knepley . a_t - the time derivative of each auxiliary field evaluated at the current point
346045480ffeSMatthew G. Knepley . a_x - the gradient of auxiliary each field evaluated at the current point
346145480ffeSMatthew G. Knepley . t - current time
346245480ffeSMatthew G. Knepley . x - coordinates of the current point
346345480ffeSMatthew G. Knepley . numConstants - number of constant parameters
346445480ffeSMatthew G. Knepley . constants - constant parameters
346545480ffeSMatthew G. Knepley - bcval - output values at the current point
346645480ffeSMatthew G. Knepley 
346745480ffeSMatthew G. Knepley   Level: developer
346845480ffeSMatthew G. Knepley 
3469dce8aebaSBarry Smith   Note:
3470dce8aebaSBarry Smith   This function should only be used with `DMFOREST` currently, since labels cannot be defined before the underlying `DMPLEX` is built.
3471dce8aebaSBarry Smith 
3472dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMLabel`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSSetResidual()`, `PetscDSSetBdResidual()`
347345480ffeSMatthew G. Knepley @*/
3474d71ae5a4SJacob 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)
3475d71ae5a4SJacob Faibussowitsch {
347645480ffeSMatthew G. Knepley   DSBoundary head = ds->boundary, b;
347745480ffeSMatthew G. Knepley   PetscInt   n    = 0;
347845480ffeSMatthew G. Knepley 
347945480ffeSMatthew G. Knepley   PetscFunctionBegin;
348045480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
348145480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveEnum(ds, type, 2);
348245480ffeSMatthew G. Knepley   PetscValidCharPointer(name, 3);
348345480ffeSMatthew G. Knepley   PetscValidCharPointer(lname, 4);
348445480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nv, 5);
348545480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, field, 7);
348645480ffeSMatthew G. Knepley   PetscValidLogicalCollectiveInt(ds, Nc, 8);
34879566063dSJacob Faibussowitsch   PetscCall(PetscNew(&b));
34889566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, (char **)&b->name));
34899566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf));
34909566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetNumFields(b->wf, ds->Nf));
34919566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nv, &b->values));
34929566063dSJacob Faibussowitsch   if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
34939566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nc, &b->comps));
34949566063dSJacob Faibussowitsch   if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
34959566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(lname, (char **)&b->lname));
349645480ffeSMatthew G. Knepley   b->type   = type;
349745480ffeSMatthew G. Knepley   b->label  = NULL;
349845480ffeSMatthew G. Knepley   b->Nv     = Nv;
349945480ffeSMatthew G. Knepley   b->field  = field;
350045480ffeSMatthew G. Knepley   b->Nc     = Nc;
350145480ffeSMatthew G. Knepley   b->func   = bcFunc;
350245480ffeSMatthew G. Knepley   b->func_t = bcFunc_t;
350345480ffeSMatthew G. Knepley   b->ctx    = ctx;
350445480ffeSMatthew G. Knepley   b->next   = NULL;
350545480ffeSMatthew G. Knepley   /* Append to linked list so that we can preserve the order */
350645480ffeSMatthew G. Knepley   if (!head) ds->boundary = b;
350745480ffeSMatthew G. Knepley   while (head) {
350845480ffeSMatthew G. Knepley     if (!head->next) {
350945480ffeSMatthew G. Knepley       head->next = b;
351045480ffeSMatthew G. Knepley       head       = b;
351145480ffeSMatthew G. Knepley     }
351245480ffeSMatthew G. Knepley     head = head->next;
351345480ffeSMatthew G. Knepley     ++n;
351445480ffeSMatthew G. Knepley   }
35159371c9d4SSatish Balay   if (bd) {
35169371c9d4SSatish Balay     PetscValidIntPointer(bd, 13);
35179371c9d4SSatish Balay     *bd = n;
35189371c9d4SSatish Balay   }
35193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
352058ebd649SToby Isaac }
352158ebd649SToby Isaac 
3522b67eacb3SMatthew G. Knepley /*@C
3523dce8aebaSBarry Smith   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions.
3524dce8aebaSBarry 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
3525dce8aebaSBarry Smith   should be performed, using the kernels from `PetscDSSetBdResidual()`.
3526b67eacb3SMatthew G. Knepley 
3527b67eacb3SMatthew G. Knepley   Input Parameters:
3528dce8aebaSBarry Smith + ds       - The `PetscDS` object
3529b67eacb3SMatthew G. Knepley . bd       - The boundary condition number
3530dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
3531b67eacb3SMatthew G. Knepley . name     - The BC name
353245480ffeSMatthew G. Knepley . label    - The label defining constrained points
3533dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
353445480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
3535b67eacb3SMatthew G. Knepley . field    - The field to constrain
353645480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
3537b67eacb3SMatthew G. Knepley . comps    - An array of constrained component numbers
3538b67eacb3SMatthew G. Knepley . bcFunc   - A pointwise function giving boundary values
3539a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3540b67eacb3SMatthew G. Knepley - ctx      - An optional user context for bcFunc
3541b67eacb3SMatthew G. Knepley 
3542b67eacb3SMatthew G. Knepley   Level: developer
3543b67eacb3SMatthew G. Knepley 
3544dce8aebaSBarry Smith   Note:
3545dce8aebaSBarry Smith   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from `PetscDSGetNumBoundary()`.
3546dce8aebaSBarry Smith   See `PetscDSAddBoundary()` for a description of the calling sequences for the callbacks.
3547dce8aebaSBarry Smith 
3548dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`, `PetscDSGetNumBoundary()`, `DMLabel`
3549b67eacb3SMatthew G. Knepley @*/
3550d71ae5a4SJacob 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)
3551d71ae5a4SJacob Faibussowitsch {
3552b67eacb3SMatthew G. Knepley   DSBoundary b = ds->boundary;
3553b67eacb3SMatthew G. Knepley   PetscInt   n = 0;
3554b67eacb3SMatthew G. Knepley 
3555b67eacb3SMatthew G. Knepley   PetscFunctionBegin;
3556b67eacb3SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3557b67eacb3SMatthew G. Knepley   while (b) {
3558b67eacb3SMatthew G. Knepley     if (n == bd) break;
3559b67eacb3SMatthew G. Knepley     b = b->next;
3560b67eacb3SMatthew G. Knepley     ++n;
3561b67eacb3SMatthew G. Knepley   }
356263a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
3563b67eacb3SMatthew G. Knepley   if (name) {
35649566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
35659566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->name));
3566b67eacb3SMatthew G. Knepley   }
3567b67eacb3SMatthew G. Knepley   b->type = type;
356845480ffeSMatthew G. Knepley   if (label) {
356945480ffeSMatthew G. Knepley     const char *name;
357045480ffeSMatthew G. Knepley 
357145480ffeSMatthew G. Knepley     b->label = label;
35729566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
35739566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)label, &name));
35749566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(name, (char **)&b->lname));
357545480ffeSMatthew G. Knepley   }
357645480ffeSMatthew G. Knepley   if (Nv >= 0) {
357745480ffeSMatthew G. Knepley     b->Nv = Nv;
35789566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
35799566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nv, &b->values));
35809566063dSJacob Faibussowitsch     if (Nv) PetscCall(PetscArraycpy(b->values, values, Nv));
358145480ffeSMatthew G. Knepley   }
358245480ffeSMatthew G. Knepley   if (field >= 0) b->field = field;
358345480ffeSMatthew G. Knepley   if (Nc >= 0) {
358445480ffeSMatthew G. Knepley     b->Nc = Nc;
35859566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
35869566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(Nc, &b->comps));
35879566063dSJacob Faibussowitsch     if (Nc) PetscCall(PetscArraycpy(b->comps, comps, Nc));
358845480ffeSMatthew G. Knepley   }
358945480ffeSMatthew G. Knepley   if (bcFunc) b->func = bcFunc;
359045480ffeSMatthew G. Knepley   if (bcFunc_t) b->func_t = bcFunc_t;
359145480ffeSMatthew G. Knepley   if (ctx) b->ctx = ctx;
35923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3593b67eacb3SMatthew G. Knepley }
3594b67eacb3SMatthew G. Knepley 
359558ebd649SToby Isaac /*@
359658ebd649SToby Isaac   PetscDSGetNumBoundary - Get the number of registered BC
359758ebd649SToby Isaac 
359858ebd649SToby Isaac   Input Parameters:
3599dce8aebaSBarry Smith . ds - The `PetscDS` object
360058ebd649SToby Isaac 
360158ebd649SToby Isaac   Output Parameters:
360258ebd649SToby Isaac . numBd - The number of BC
360358ebd649SToby Isaac 
360458ebd649SToby Isaac   Level: intermediate
360558ebd649SToby Isaac 
3606dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSAddBoundary()`, `PetscDSGetBoundary()`
360758ebd649SToby Isaac @*/
3608d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3609d71ae5a4SJacob Faibussowitsch {
361058ebd649SToby Isaac   DSBoundary b = ds->boundary;
361158ebd649SToby Isaac 
361258ebd649SToby Isaac   PetscFunctionBegin;
361358ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3614dadcf809SJacob Faibussowitsch   PetscValidIntPointer(numBd, 2);
361558ebd649SToby Isaac   *numBd = 0;
36169371c9d4SSatish Balay   while (b) {
36179371c9d4SSatish Balay     ++(*numBd);
36189371c9d4SSatish Balay     b = b->next;
36199371c9d4SSatish Balay   }
36203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
362158ebd649SToby Isaac }
362258ebd649SToby Isaac 
362358ebd649SToby Isaac /*@C
36249a6efb6aSMatthew G. Knepley   PetscDSGetBoundary - Gets a boundary condition to the model
362558ebd649SToby Isaac 
362658ebd649SToby Isaac   Input Parameters:
3627dce8aebaSBarry Smith + ds          - The `PetscDS` object
362858ebd649SToby Isaac - bd          - The BC number
362958ebd649SToby Isaac 
363058ebd649SToby Isaac   Output Parameters:
3631dce8aebaSBarry Smith + wf       - The `PetscWeakForm` holding the pointwise functions
3632dce8aebaSBarry Smith . type     - The type of condition, e.g. `DM_BC_ESSENTIAL`/`DM_BC_ESSENTIAL_FIELD` (Dirichlet), or `DM_BC_NATURAL` (Neumann)
363358ebd649SToby Isaac . name     - The BC name
363445480ffeSMatthew G. Knepley . label    - The label defining constrained points
3635dce8aebaSBarry Smith . Nv       - The number of `DMLabel` ids for constrained points
363645480ffeSMatthew G. Knepley . values   - An array of ids for constrained points
363758ebd649SToby Isaac . field    - The field to constrain
363845480ffeSMatthew G. Knepley . Nc       - The number of constrained field components
363958ebd649SToby Isaac . comps    - An array of constrained component numbers
364058ebd649SToby Isaac . bcFunc   - A pointwise function giving boundary values
3641a5b23f4aSJose E. Roman . bcFunc_t - A pointwise function giving the time derivative of the boundary values
364258ebd649SToby Isaac - ctx      - An optional user context for bcFunc
364358ebd649SToby Isaac 
364458ebd649SToby Isaac   Options Database Keys:
364558ebd649SToby Isaac + -bc_<boundary name> <num> - Overrides the boundary ids
364658ebd649SToby Isaac - -bc_<boundary name>_comp <num> - Overrides the boundary components
364758ebd649SToby Isaac 
364858ebd649SToby Isaac   Level: developer
364958ebd649SToby Isaac 
3650dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscWeakForm`, `DMBoundaryConditionType`, `PetscDSAddBoundary()`, `DMLabel`
365158ebd649SToby Isaac @*/
3652d71ae5a4SJacob 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)
3653d71ae5a4SJacob Faibussowitsch {
365458ebd649SToby Isaac   DSBoundary b = ds->boundary;
365558ebd649SToby Isaac   PetscInt   n = 0;
365658ebd649SToby Isaac 
365758ebd649SToby Isaac   PetscFunctionBegin;
365858ebd649SToby Isaac   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
365958ebd649SToby Isaac   while (b) {
366058ebd649SToby Isaac     if (n == bd) break;
366158ebd649SToby Isaac     b = b->next;
366258ebd649SToby Isaac     ++n;
366358ebd649SToby Isaac   }
366463a3b9bcSJacob Faibussowitsch   PetscCheck(b, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %" PetscInt_FMT " is not in [0, %" PetscInt_FMT ")", bd, n);
366545480ffeSMatthew G. Knepley   if (wf) {
366645480ffeSMatthew G. Knepley     PetscValidPointer(wf, 3);
366745480ffeSMatthew G. Knepley     *wf = b->wf;
366845480ffeSMatthew G. Knepley   }
3669f971fd6bSMatthew G. Knepley   if (type) {
367045480ffeSMatthew G. Knepley     PetscValidPointer(type, 4);
3671f971fd6bSMatthew G. Knepley     *type = b->type;
367258ebd649SToby Isaac   }
367358ebd649SToby Isaac   if (name) {
367445480ffeSMatthew G. Knepley     PetscValidPointer(name, 5);
367558ebd649SToby Isaac     *name = b->name;
367658ebd649SToby Isaac   }
367745480ffeSMatthew G. Knepley   if (label) {
367845480ffeSMatthew G. Knepley     PetscValidPointer(label, 6);
367945480ffeSMatthew G. Knepley     *label = b->label;
368045480ffeSMatthew G. Knepley   }
368145480ffeSMatthew G. Knepley   if (Nv) {
368245480ffeSMatthew G. Knepley     PetscValidIntPointer(Nv, 7);
368345480ffeSMatthew G. Knepley     *Nv = b->Nv;
368445480ffeSMatthew G. Knepley   }
368545480ffeSMatthew G. Knepley   if (values) {
368645480ffeSMatthew G. Knepley     PetscValidPointer(values, 8);
368745480ffeSMatthew G. Knepley     *values = b->values;
368858ebd649SToby Isaac   }
368958ebd649SToby Isaac   if (field) {
369045480ffeSMatthew G. Knepley     PetscValidIntPointer(field, 9);
369158ebd649SToby Isaac     *field = b->field;
369258ebd649SToby Isaac   }
369345480ffeSMatthew G. Knepley   if (Nc) {
369445480ffeSMatthew G. Knepley     PetscValidIntPointer(Nc, 10);
369545480ffeSMatthew G. Knepley     *Nc = b->Nc;
369658ebd649SToby Isaac   }
369758ebd649SToby Isaac   if (comps) {
369845480ffeSMatthew G. Knepley     PetscValidPointer(comps, 11);
369958ebd649SToby Isaac     *comps = b->comps;
370058ebd649SToby Isaac   }
370158ebd649SToby Isaac   if (func) {
370245480ffeSMatthew G. Knepley     PetscValidPointer(func, 12);
370358ebd649SToby Isaac     *func = b->func;
370458ebd649SToby Isaac   }
370556cf3b9cSMatthew G. Knepley   if (func_t) {
370645480ffeSMatthew G. Knepley     PetscValidPointer(func_t, 13);
370756cf3b9cSMatthew G. Knepley     *func_t = b->func_t;
370856cf3b9cSMatthew G. Knepley   }
370958ebd649SToby Isaac   if (ctx) {
371045480ffeSMatthew G. Knepley     PetscValidPointer(ctx, 14);
371158ebd649SToby Isaac     *ctx = b->ctx;
371258ebd649SToby Isaac   }
37133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
371458ebd649SToby Isaac }
371558ebd649SToby Isaac 
3716d71ae5a4SJacob Faibussowitsch static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3717d71ae5a4SJacob Faibussowitsch {
371845480ffeSMatthew G. Knepley   PetscFunctionBegin;
37199566063dSJacob Faibussowitsch   PetscCall(PetscNew(bNew));
37209566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf));
37219566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(b->wf, (*bNew)->wf));
37229566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->name, (char **)&((*bNew)->name)));
37239566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(b->lname, (char **)&((*bNew)->lname)));
372445480ffeSMatthew G. Knepley   (*bNew)->type  = b->type;
372545480ffeSMatthew G. Knepley   (*bNew)->label = b->label;
372645480ffeSMatthew G. Knepley   (*bNew)->Nv    = b->Nv;
37279566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nv, &(*bNew)->values));
37289566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->values, b->values, b->Nv));
372945480ffeSMatthew G. Knepley   (*bNew)->field = b->field;
373045480ffeSMatthew G. Knepley   (*bNew)->Nc    = b->Nc;
37319566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(b->Nc, &(*bNew)->comps));
37329566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy((*bNew)->comps, b->comps, b->Nc));
373345480ffeSMatthew G. Knepley   (*bNew)->func   = b->func;
373445480ffeSMatthew G. Knepley   (*bNew)->func_t = b->func_t;
373545480ffeSMatthew G. Knepley   (*bNew)->ctx    = b->ctx;
37363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
373745480ffeSMatthew G. Knepley }
373845480ffeSMatthew G. Knepley 
37399252d075SMatthew G. Knepley /*@
37409252d075SMatthew G. Knepley   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
37419252d075SMatthew G. Knepley 
3742*20f4b53cSBarry Smith   Not Collective
37439252d075SMatthew G. Knepley 
374436951cb5SMatthew G. Knepley   Input Parameters:
3745dce8aebaSBarry Smith + ds        - The source `PetscDS` object
3746dce8aebaSBarry Smith . numFields - The number of selected fields, or `PETSC_DEFAULT` for all fields
374736951cb5SMatthew G. Knepley - fields    - The selected fields, or NULL for all fields
37489252d075SMatthew G. Knepley 
37499252d075SMatthew G. Knepley   Output Parameter:
3750dce8aebaSBarry Smith . newds     - The target `PetscDS`, now with a copy of the boundary conditions
37519252d075SMatthew G. Knepley 
37529252d075SMatthew G. Knepley   Level: intermediate
37539252d075SMatthew G. Knepley 
3754dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
37559252d075SMatthew G. Knepley @*/
3756d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3757d71ae5a4SJacob Faibussowitsch {
375845480ffeSMatthew G. Knepley   DSBoundary b, *lastnext;
3759dff059c6SToby Isaac 
3760dff059c6SToby Isaac   PetscFunctionBegin;
376136951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
376236951cb5SMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 4);
37633ba16761SJacob Faibussowitsch   if (ds == newds) PetscFunctionReturn(PETSC_SUCCESS);
37649566063dSJacob Faibussowitsch   PetscCall(PetscDSDestroyBoundary(newds));
376536951cb5SMatthew G. Knepley   lastnext = &(newds->boundary);
376636951cb5SMatthew G. Knepley   for (b = ds->boundary; b; b = b->next) {
3767dff059c6SToby Isaac     DSBoundary bNew;
376836951cb5SMatthew G. Knepley     PetscInt   fieldNew = -1;
3769dff059c6SToby Isaac 
377036951cb5SMatthew G. Knepley     if (numFields > 0 && fields) {
377136951cb5SMatthew G. Knepley       PetscInt f;
377236951cb5SMatthew G. Knepley 
37739371c9d4SSatish Balay       for (f = 0; f < numFields; ++f)
37749371c9d4SSatish Balay         if (b->field == fields[f]) break;
377536951cb5SMatthew G. Knepley       if (f == numFields) continue;
377636951cb5SMatthew G. Knepley       fieldNew = f;
377736951cb5SMatthew G. Knepley     }
37789566063dSJacob Faibussowitsch     PetscCall(DSBoundaryDuplicate_Internal(b, &bNew));
377936951cb5SMatthew G. Knepley     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3780dff059c6SToby Isaac     *lastnext   = bNew;
3781dff059c6SToby Isaac     lastnext    = &(bNew->next);
3782dff059c6SToby Isaac   }
37833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3784dff059c6SToby Isaac }
3785dff059c6SToby Isaac 
37866c1eb96dSMatthew G. Knepley /*@
3787dce8aebaSBarry Smith   PetscDSDestroyBoundary - Remove all `DMBoundary` objects from the `PetscDS`
378845480ffeSMatthew G. Knepley 
3789*20f4b53cSBarry Smith   Not Collective
379045480ffeSMatthew G. Knepley 
379145480ffeSMatthew G. Knepley   Input Parameter:
3792dce8aebaSBarry Smith . ds - The `PetscDS` object
379345480ffeSMatthew G. Knepley 
379445480ffeSMatthew G. Knepley   Level: intermediate
379545480ffeSMatthew G. Knepley 
3796dce8aebaSBarry Smith .seealso: `PetscDS`, `DMBoundary`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`
379745480ffeSMatthew G. Knepley @*/
3798d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3799d71ae5a4SJacob Faibussowitsch {
380045480ffeSMatthew G. Knepley   DSBoundary next = ds->boundary;
380145480ffeSMatthew G. Knepley 
380245480ffeSMatthew G. Knepley   PetscFunctionBegin;
380345480ffeSMatthew G. Knepley   while (next) {
380445480ffeSMatthew G. Knepley     DSBoundary b = next;
380545480ffeSMatthew G. Knepley 
380645480ffeSMatthew G. Knepley     next = b->next;
38079566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormDestroy(&b->wf));
38089566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->name));
38099566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->lname));
38109566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->values));
38119566063dSJacob Faibussowitsch     PetscCall(PetscFree(b->comps));
38129566063dSJacob Faibussowitsch     PetscCall(PetscFree(b));
381345480ffeSMatthew G. Knepley   }
38143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
381545480ffeSMatthew G. Knepley }
381645480ffeSMatthew G. Knepley 
381745480ffeSMatthew G. Knepley /*@
38186c1eb96dSMatthew G. Knepley   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
38196c1eb96dSMatthew G. Knepley 
3820*20f4b53cSBarry Smith   Not Collective
38216c1eb96dSMatthew G. Knepley 
3822d8d19677SJose E. Roman   Input Parameters:
3823dce8aebaSBarry Smith + prob - The `PetscDS` object
38246c1eb96dSMatthew G. Knepley . numFields - Number of new fields
38256c1eb96dSMatthew G. Knepley - fields - Old field number for each new field
38266c1eb96dSMatthew G. Knepley 
38276c1eb96dSMatthew G. Knepley   Output Parameter:
3828dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38296c1eb96dSMatthew G. Knepley 
38306c1eb96dSMatthew G. Knepley   Level: intermediate
38316c1eb96dSMatthew G. Knepley 
3832dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectEquations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38336c1eb96dSMatthew G. Knepley @*/
3834d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3835d71ae5a4SJacob Faibussowitsch {
38366c1eb96dSMatthew G. Knepley   PetscInt Nf, Nfn, fn;
38376c1eb96dSMatthew G. Knepley 
38386c1eb96dSMatthew G. Knepley   PetscFunctionBegin;
38396c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3840dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38416c1eb96dSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38429566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38439566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
384445480ffeSMatthew G. Knepley   numFields = numFields < 0 ? Nf : numFields;
38456c1eb96dSMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38466c1eb96dSMatthew G. Knepley     const PetscInt f = fields ? fields[fn] : fn;
38476c1eb96dSMatthew G. Knepley     PetscObject    disc;
38486c1eb96dSMatthew G. Knepley 
38496c1eb96dSMatthew G. Knepley     if (f >= Nf) continue;
38509566063dSJacob Faibussowitsch     PetscCall(PetscDSGetDiscretization(prob, f, &disc));
38519566063dSJacob Faibussowitsch     PetscCall(PetscDSSetDiscretization(newprob, fn, disc));
38526c1eb96dSMatthew G. Knepley   }
38533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38546c1eb96dSMatthew G. Knepley }
38556c1eb96dSMatthew G. Knepley 
38566c1eb96dSMatthew G. Knepley /*@
38579252d075SMatthew G. Knepley   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
38589252d075SMatthew G. Knepley 
3859*20f4b53cSBarry Smith   Not Collective
38609252d075SMatthew G. Knepley 
3861d8d19677SJose E. Roman   Input Parameters:
3862dce8aebaSBarry Smith + prob - The `PetscDS` object
38639252d075SMatthew G. Knepley . numFields - Number of new fields
38649252d075SMatthew G. Knepley - fields - Old field number for each new field
38659252d075SMatthew G. Knepley 
38669252d075SMatthew G. Knepley   Output Parameter:
3867dce8aebaSBarry Smith . newprob - The `PetscDS` copy
38689252d075SMatthew G. Knepley 
38699252d075SMatthew G. Knepley   Level: intermediate
38709252d075SMatthew G. Knepley 
3871dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSSelectDiscretizations()`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
38729252d075SMatthew G. Knepley @*/
3873d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3874d71ae5a4SJacob Faibussowitsch {
38759252d075SMatthew G. Knepley   PetscInt Nf, Nfn, fn, gn;
38769252d075SMatthew G. Knepley 
38779252d075SMatthew G. Knepley   PetscFunctionBegin;
38789252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3879dadcf809SJacob Faibussowitsch   if (fields) PetscValidIntPointer(fields, 3);
38809252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
38819566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
38829566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Nfn));
388363a3b9bcSJacob 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);
38849252d075SMatthew G. Knepley   for (fn = 0; fn < numFields; ++fn) {
38859252d075SMatthew G. Knepley     const PetscInt   f = fields ? fields[fn] : fn;
38869252d075SMatthew G. Knepley     PetscPointFunc   obj;
38879252d075SMatthew G. Knepley     PetscPointFunc   f0, f1;
38889252d075SMatthew G. Knepley     PetscBdPointFunc f0Bd, f1Bd;
38899252d075SMatthew G. Knepley     PetscRiemannFunc r;
38909252d075SMatthew G. Knepley 
3891c52f1e13SMatthew G. Knepley     if (f >= Nf) continue;
38929566063dSJacob Faibussowitsch     PetscCall(PetscDSGetObjective(prob, f, &obj));
38939566063dSJacob Faibussowitsch     PetscCall(PetscDSGetResidual(prob, f, &f0, &f1));
38949566063dSJacob Faibussowitsch     PetscCall(PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd));
38959566063dSJacob Faibussowitsch     PetscCall(PetscDSGetRiemannSolver(prob, f, &r));
38969566063dSJacob Faibussowitsch     PetscCall(PetscDSSetObjective(newprob, fn, obj));
38979566063dSJacob Faibussowitsch     PetscCall(PetscDSSetResidual(newprob, fn, f0, f1));
38989566063dSJacob Faibussowitsch     PetscCall(PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd));
38999566063dSJacob Faibussowitsch     PetscCall(PetscDSSetRiemannSolver(newprob, fn, r));
39009252d075SMatthew G. Knepley     for (gn = 0; gn < numFields; ++gn) {
39019252d075SMatthew G. Knepley       const PetscInt  g = fields ? fields[gn] : gn;
39029252d075SMatthew G. Knepley       PetscPointJac   g0, g1, g2, g3;
39039252d075SMatthew G. Knepley       PetscPointJac   g0p, g1p, g2p, g3p;
39049252d075SMatthew G. Knepley       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
39059252d075SMatthew G. Knepley 
3906c52f1e13SMatthew G. Knepley       if (g >= Nf) continue;
39079566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3));
39089566063dSJacob Faibussowitsch       PetscCall(PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p));
39099566063dSJacob Faibussowitsch       PetscCall(PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd));
39109566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3));
39119566063dSJacob Faibussowitsch       PetscCall(PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p));
39129566063dSJacob Faibussowitsch       PetscCall(PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd));
39139252d075SMatthew G. Knepley     }
39149252d075SMatthew G. Knepley   }
39153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39169252d075SMatthew G. Knepley }
39179252d075SMatthew G. Knepley 
3918da51fcedSMatthew G. Knepley /*@
3919dce8aebaSBarry Smith   PetscDSCopyEquations - Copy all pointwise function pointers to another `PetscDS`
3920da51fcedSMatthew G. Knepley 
3921*20f4b53cSBarry Smith   Not Collective
3922da51fcedSMatthew G. Knepley 
3923da51fcedSMatthew G. Knepley   Input Parameter:
3924dce8aebaSBarry Smith . prob - The `PetscDS` object
3925da51fcedSMatthew G. Knepley 
3926da51fcedSMatthew G. Knepley   Output Parameter:
3927dce8aebaSBarry Smith . newprob - The `PetscDS` copy
3928da51fcedSMatthew G. Knepley 
3929da51fcedSMatthew G. Knepley   Level: intermediate
3930da51fcedSMatthew G. Knepley 
3931dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
3932da51fcedSMatthew G. Knepley @*/
3933d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3934d71ae5a4SJacob Faibussowitsch {
3935b8025e53SMatthew G. Knepley   PetscWeakForm wf, newwf;
39369252d075SMatthew G. Knepley   PetscInt      Nf, Ng;
3937da51fcedSMatthew G. Knepley 
3938da51fcedSMatthew G. Knepley   PetscFunctionBegin;
3939da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3940da51fcedSMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39419566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
39429566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(newprob, &Ng));
394363a3b9bcSJacob Faibussowitsch   PetscCheck(Nf == Ng, PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %" PetscInt_FMT " != %" PetscInt_FMT, Nf, Ng);
39449566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(prob, &wf));
39459566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(newprob, &newwf));
39469566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormCopy(wf, newwf));
39473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39489252d075SMatthew G. Knepley }
394945480ffeSMatthew G. Knepley 
39509252d075SMatthew G. Knepley /*@
3951dce8aebaSBarry Smith   PetscDSCopyConstants - Copy all constants to another `PetscDS`
3952da51fcedSMatthew G. Knepley 
3953*20f4b53cSBarry Smith   Not Collective
39549252d075SMatthew G. Knepley 
39559252d075SMatthew G. Knepley   Input Parameter:
3956dce8aebaSBarry Smith . prob - The `PetscDS` object
39579252d075SMatthew G. Knepley 
39589252d075SMatthew G. Knepley   Output Parameter:
3959dce8aebaSBarry Smith . newprob - The `PetscDS` copy
39609252d075SMatthew G. Knepley 
39619252d075SMatthew G. Knepley   Level: intermediate
39629252d075SMatthew G. Knepley 
3963dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
39649252d075SMatthew G. Knepley @*/
3965d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3966d71ae5a4SJacob Faibussowitsch {
39679252d075SMatthew G. Knepley   PetscInt           Nc;
39689252d075SMatthew G. Knepley   const PetscScalar *constants;
39699252d075SMatthew G. Knepley 
39709252d075SMatthew G. Knepley   PetscFunctionBegin;
39719252d075SMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
39729252d075SMatthew G. Knepley   PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
39739566063dSJacob Faibussowitsch   PetscCall(PetscDSGetConstants(prob, &Nc, &constants));
39749566063dSJacob Faibussowitsch   PetscCall(PetscDSSetConstants(newprob, Nc, (PetscScalar *)constants));
39753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3976da51fcedSMatthew G. Knepley }
3977da51fcedSMatthew G. Knepley 
397845480ffeSMatthew G. Knepley /*@
3979dce8aebaSBarry Smith   PetscDSCopyExactSolutions - Copy all exact solutions to another `PetscDS`
398045480ffeSMatthew G. Knepley 
3981*20f4b53cSBarry Smith   Not Collective
398245480ffeSMatthew G. Knepley 
398345480ffeSMatthew G. Knepley   Input Parameter:
3984dce8aebaSBarry Smith . ds - The `PetscDS` object
398545480ffeSMatthew G. Knepley 
398645480ffeSMatthew G. Knepley   Output Parameter:
3987dce8aebaSBarry Smith . newds - The `PetscDS` copy
398845480ffeSMatthew G. Knepley 
398945480ffeSMatthew G. Knepley   Level: intermediate
399045480ffeSMatthew G. Knepley 
3991dce8aebaSBarry Smith .seealso: `PetscDS`, `PetscDSCopyBoundary()`, `PetscDSCopyEquations()`, `PetscDSSetResidual()`, `PetscDSSetJacobian()`, `PetscDSSetRiemannSolver()`, `PetscDSSetBdResidual()`, `PetscDSSetBdJacobian()`, `PetscDSCreate()`
399245480ffeSMatthew G. Knepley @*/
3993d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
3994d71ae5a4SJacob Faibussowitsch {
399545480ffeSMatthew G. Knepley   PetscSimplePointFunc sol;
399645480ffeSMatthew G. Knepley   void                *ctx;
399745480ffeSMatthew G. Knepley   PetscInt             Nf, f;
399845480ffeSMatthew G. Knepley 
399945480ffeSMatthew G. Knepley   PetscFunctionBegin;
400045480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
400145480ffeSMatthew G. Knepley   PetscValidHeaderSpecific(newds, PETSCDS_CLASSID, 2);
40029566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
400345480ffeSMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
40049566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolution(ds, f, &sol, &ctx));
40059566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolution(newds, f, sol, ctx));
40069566063dSJacob Faibussowitsch     PetscCall(PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx));
40079566063dSJacob Faibussowitsch     PetscCall(PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx));
400845480ffeSMatthew G. Knepley   }
40093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
401045480ffeSMatthew G. Knepley }
401145480ffeSMatthew G. Knepley 
4012d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
4013d71ae5a4SJacob Faibussowitsch {
4014df3a45bdSMatthew G. Knepley   PetscInt dim, Nf, f;
4015b1353e8eSMatthew G. Knepley 
4016b1353e8eSMatthew G. Knepley   PetscFunctionBegin;
4017b1353e8eSMatthew G. Knepley   PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
4018b1353e8eSMatthew G. Knepley   PetscValidPointer(subprob, 3);
40199371c9d4SSatish Balay   if (height == 0) {
40209371c9d4SSatish Balay     *subprob = prob;
40213ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
40229371c9d4SSatish Balay   }
40239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(prob, &Nf));
40249566063dSJacob Faibussowitsch   PetscCall(PetscDSGetSpatialDimension(prob, &dim));
402563a3b9bcSJacob 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);
40269566063dSJacob Faibussowitsch   if (!prob->subprobs) PetscCall(PetscCalloc1(dim, &prob->subprobs));
4027df3a45bdSMatthew G. Knepley   if (!prob->subprobs[height - 1]) {
4028b1353e8eSMatthew G. Knepley     PetscInt cdim;
4029b1353e8eSMatthew G. Knepley 
40309566063dSJacob Faibussowitsch     PetscCall(PetscDSCreate(PetscObjectComm((PetscObject)prob), &prob->subprobs[height - 1]));
40319566063dSJacob Faibussowitsch     PetscCall(PetscDSGetCoordinateDimension(prob, &cdim));
40329566063dSJacob Faibussowitsch     PetscCall(PetscDSSetCoordinateDimension(prob->subprobs[height - 1], cdim));
4033b1353e8eSMatthew G. Knepley     for (f = 0; f < Nf; ++f) {
4034b1353e8eSMatthew G. Knepley       PetscFE      subfe;
4035b1353e8eSMatthew G. Knepley       PetscObject  obj;
4036b1353e8eSMatthew G. Knepley       PetscClassId id;
4037b1353e8eSMatthew G. Knepley 
40389566063dSJacob Faibussowitsch       PetscCall(PetscDSGetDiscretization(prob, f, &obj));
40399566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetClassId(obj, &id));
40409566063dSJacob Faibussowitsch       if (id == PETSCFE_CLASSID) PetscCall(PetscFEGetHeightSubspace((PetscFE)obj, height, &subfe));
404163a3b9bcSJacob Faibussowitsch       else SETERRQ(PetscObjectComm((PetscObject)prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %" PetscInt_FMT, f);
40429566063dSJacob Faibussowitsch       PetscCall(PetscDSSetDiscretization(prob->subprobs[height - 1], f, (PetscObject)subfe));
4043b1353e8eSMatthew G. Knepley     }
4044b1353e8eSMatthew G. Knepley   }
4045df3a45bdSMatthew G. Knepley   *subprob = prob->subprobs[height - 1];
40463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4047b1353e8eSMatthew G. Knepley }
4048b1353e8eSMatthew G. Knepley 
4049d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
4050d71ae5a4SJacob Faibussowitsch {
4051c7bd5f0bSMatthew G. Knepley   PetscObject  obj;
4052c7bd5f0bSMatthew G. Knepley   PetscClassId id;
4053c7bd5f0bSMatthew G. Knepley   PetscInt     Nf;
4054c7bd5f0bSMatthew G. Knepley 
4055c7bd5f0bSMatthew G. Knepley   PetscFunctionBegin;
4056c7bd5f0bSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
4057665f567fSMatthew G. Knepley   PetscValidPointer(disctype, 3);
4058665f567fSMatthew G. Knepley   *disctype = PETSC_DISC_NONE;
40599566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(ds, &Nf));
406063a3b9bcSJacob Faibussowitsch   PetscCheck(f < Nf, PetscObjectComm((PetscObject)ds), PETSC_ERR_ARG_SIZ, "Field %" PetscInt_FMT " must be in [0, %" PetscInt_FMT ")", f, Nf);
40619566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(ds, f, &obj));
4062665f567fSMatthew G. Knepley   if (obj) {
40639566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetClassId(obj, &id));
4064665f567fSMatthew G. Knepley     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
4065665f567fSMatthew G. Knepley     else *disctype = PETSC_DISC_FV;
4066665f567fSMatthew G. Knepley   }
40673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4068c7bd5f0bSMatthew G. Knepley }
4069c7bd5f0bSMatthew G. Knepley 
4070d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
4071d71ae5a4SJacob Faibussowitsch {
40722764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40739566063dSJacob Faibussowitsch   PetscCall(PetscFree(ds->data));
40743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40752764a2aaSMatthew G. Knepley }
40762764a2aaSMatthew G. Knepley 
4077d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
4078d71ae5a4SJacob Faibussowitsch {
40792764a2aaSMatthew G. Knepley   PetscFunctionBegin;
40806528b96dSMatthew G. Knepley   ds->ops->setfromoptions = NULL;
40816528b96dSMatthew G. Knepley   ds->ops->setup          = NULL;
40826528b96dSMatthew G. Knepley   ds->ops->view           = NULL;
40836528b96dSMatthew G. Knepley   ds->ops->destroy        = PetscDSDestroy_Basic;
40843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40852764a2aaSMatthew G. Knepley }
40862764a2aaSMatthew G. Knepley 
40872764a2aaSMatthew G. Knepley /*MC
40882764a2aaSMatthew G. Knepley   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
40892764a2aaSMatthew G. Knepley 
40902764a2aaSMatthew G. Knepley   Level: intermediate
40912764a2aaSMatthew G. Knepley 
4092db781477SPatrick Sanan .seealso: `PetscDSType`, `PetscDSCreate()`, `PetscDSSetType()`
40932764a2aaSMatthew G. Knepley M*/
40942764a2aaSMatthew G. Knepley 
4095d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4096d71ae5a4SJacob Faibussowitsch {
40972764a2aaSMatthew G. Knepley   PetscDS_Basic *b;
40982764a2aaSMatthew G. Knepley 
40992764a2aaSMatthew G. Knepley   PetscFunctionBegin;
41006528b96dSMatthew G. Knepley   PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
41014dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
41026528b96dSMatthew G. Knepley   ds->data = b;
41032764a2aaSMatthew G. Knepley 
41049566063dSJacob Faibussowitsch   PetscCall(PetscDSInitialize_Basic(ds));
41053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41062764a2aaSMatthew G. Knepley }
4107