Actual source code: dtds.c
1: #include <petsc/private/petscdsimpl.h>
3: PetscClassId PETSCDS_CLASSID = 0;
5: PetscFunctionList PetscDSList = NULL;
6: PetscBool PetscDSRegisterAllCalled = PETSC_FALSE;
8: /* A PetscDS (Discrete System) encodes a set of equations posed in a discrete space, which represents a set of
9: nonlinear continuum equations. The equations can have multiple fields, each field having a different
10: discretization. In addition, different pieces of the domain can have different field combinations and equations.
12: The DS provides the user a description of the approximation space on any given cell. It also gives pointwise
13: functions representing the equations.
15: Each field is associated with a label, marking the cells on which it is supported. Note that a field can be
16: supported on the closure of a cell not in the label due to overlap of the boundary of neighboring cells. The DM
17: then creates a DS for each set of cells with identical approximation spaces. When assembling, the user asks for
18: the space associated with a given cell. DMPlex uses the labels associated with each DS in the default integration loop.
19: */
21: /*@C
22: PetscDSRegister - Adds a new PetscDS implementation
24: Not Collective
26: Input Parameters:
27: + name - The name of a new user-defined creation routine
28: - create_func - The creation routine itself
30: Notes:
31: PetscDSRegister() may be called multiple times to add several user-defined PetscDSs
33: Sample usage:
34: .vb
35: PetscDSRegister("my_ds", MyPetscDSCreate);
36: .ve
38: Then, your PetscDS type can be chosen with the procedural interface via
39: .vb
40: PetscDSCreate(MPI_Comm, PetscDS *);
41: PetscDSSetType(PetscDS, "my_ds");
42: .ve
43: or at runtime via the option
44: .vb
45: -petscds_type my_ds
46: .ve
48: Level: advanced
50: Not available from Fortran
52: .seealso: PetscDSRegisterAll(), PetscDSRegisterDestroy()
54: @*/
55: PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
56: {
57: PetscFunctionListAdd(&PetscDSList, sname, function);
58: return 0;
59: }
61: /*@C
62: PetscDSSetType - Builds a particular PetscDS
64: Collective on prob
66: Input Parameters:
67: + prob - The PetscDS object
68: - name - The kind of system
70: Options Database Key:
71: . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
73: Level: intermediate
75: Not available from Fortran
77: .seealso: PetscDSGetType(), PetscDSCreate()
78: @*/
79: PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
80: {
81: PetscErrorCode (*r)(PetscDS);
82: PetscBool match;
85: PetscObjectTypeCompare((PetscObject) prob, name, &match);
86: if (match) return 0;
88: PetscDSRegisterAll();
89: PetscFunctionListFind(PetscDSList, name, &r);
92: if (prob->ops->destroy) {
93: (*prob->ops->destroy)(prob);
94: prob->ops->destroy = NULL;
95: }
96: (*r)(prob);
97: PetscObjectChangeTypeName((PetscObject) prob, name);
98: return 0;
99: }
101: /*@C
102: PetscDSGetType - Gets the PetscDS type name (as a string) from the object.
104: Not Collective
106: Input Parameter:
107: . prob - The PetscDS
109: Output Parameter:
110: . name - The PetscDS type name
112: Level: intermediate
114: Not available from Fortran
116: .seealso: PetscDSSetType(), PetscDSCreate()
117: @*/
118: PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
119: {
122: PetscDSRegisterAll();
123: *name = ((PetscObject) prob)->type_name;
124: return 0;
125: }
127: static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
128: {
129: PetscViewerFormat format;
130: const PetscScalar *constants;
131: PetscInt Nf, numConstants, f;
133: PetscDSGetNumFields(ds, &Nf);
134: PetscViewerGetFormat(viewer, &format);
135: PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", Nf);
136: PetscViewerASCIIPushTab(viewer);
137: PetscViewerASCIIPrintf(viewer, " cell total dim %D total comp %D\n", ds->totDim, ds->totComp);
138: if (ds->isCohesive) PetscViewerASCIIPrintf(viewer, " cohesive cell\n");
139: for (f = 0; f < Nf; ++f) {
140: DSBoundary b;
141: PetscObject obj;
142: PetscClassId id;
143: PetscQuadrature q;
144: const char *name;
145: PetscInt Nc, Nq, Nqc;
147: PetscDSGetDiscretization(ds, f, &obj);
148: PetscObjectGetClassId(obj, &id);
149: PetscObjectGetName(obj, &name);
150: PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");
151: PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
152: if (id == PETSCFE_CLASSID) {
153: PetscFEGetNumComponents((PetscFE) obj, &Nc);
154: PetscFEGetQuadrature((PetscFE) obj, &q);
155: PetscViewerASCIIPrintf(viewer, " FEM");
156: } else if (id == PETSCFV_CLASSID) {
157: PetscFVGetNumComponents((PetscFV) obj, &Nc);
158: PetscFVGetQuadrature((PetscFV) obj, &q);
159: PetscViewerASCIIPrintf(viewer, " FVM");
160: }
161: else SETERRQ(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %D", f);
162: if (Nc > 1) PetscViewerASCIIPrintf(viewer, " %D components", Nc);
163: else PetscViewerASCIIPrintf(viewer, " %D component ", Nc);
164: if (ds->implicit[f]) PetscViewerASCIIPrintf(viewer, " (implicit)");
165: else PetscViewerASCIIPrintf(viewer, " (explicit)");
166: if (q) {
167: PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL);
168: PetscViewerASCIIPrintf(viewer, " (Nq %D Nqc %D)", Nq, Nqc);
169: }
170: PetscViewerASCIIPrintf(viewer, " %D-jet", ds->jetDegree[f]);
171: PetscViewerASCIIPrintf(viewer, "\n");
172: PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
173: PetscViewerASCIIPushTab(viewer);
174: if (id == PETSCFE_CLASSID) PetscFEView((PetscFE) obj, viewer);
175: else if (id == PETSCFV_CLASSID) PetscFVView((PetscFV) obj, viewer);
176: PetscViewerASCIIPopTab(viewer);
178: for (b = ds->boundary; b; b = b->next) {
179: char *name;
180: PetscInt c, i;
182: if (b->field != f) continue;
183: PetscViewerASCIIPushTab(viewer);
184: PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]);
185: if (!b->Nc) {
186: PetscViewerASCIIPrintf(viewer, " all components\n");
187: } else {
188: PetscViewerASCIIPrintf(viewer, " components: ");
189: PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
190: for (c = 0; c < b->Nc; ++c) {
191: if (c > 0) PetscViewerASCIIPrintf(viewer, ", ");
192: PetscViewerASCIIPrintf(viewer, "%D", b->comps[c]);
193: }
194: PetscViewerASCIIPrintf(viewer, "\n");
195: PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
196: }
197: PetscViewerASCIIPrintf(viewer, " values: ");
198: PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
199: for (i = 0; i < b->Nv; ++i) {
200: if (i > 0) PetscViewerASCIIPrintf(viewer, ", ");
201: PetscViewerASCIIPrintf(viewer, "%D", b->values[i]);
202: }
203: PetscViewerASCIIPrintf(viewer, "\n");
204: PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
205: if (b->func) {
206: PetscDLAddr(b->func, &name);
207: if (name) PetscViewerASCIIPrintf(viewer, " func: %s\n", name);
208: else PetscViewerASCIIPrintf(viewer, " func: %p\n", b->func);
209: PetscFree(name);
210: }
211: if (b->func_t) {
212: PetscDLAddr(b->func_t, &name);
213: if (name) PetscViewerASCIIPrintf(viewer, " func_t: %s\n", name);
214: else PetscViewerASCIIPrintf(viewer, " func_t: %p\n", b->func_t);
215: PetscFree(name);
216: }
217: PetscWeakFormView(b->wf, viewer);
218: PetscViewerASCIIPopTab(viewer);
219: }
220: }
221: PetscDSGetConstants(ds, &numConstants, &constants);
222: if (numConstants) {
223: PetscViewerASCIIPrintf(viewer, "%D constants\n", numConstants);
224: PetscViewerASCIIPushTab(viewer);
225: for (f = 0; f < numConstants; ++f) PetscViewerASCIIPrintf(viewer, "%g\n", (double) PetscRealPart(constants[f]));
226: PetscViewerASCIIPopTab(viewer);
227: }
228: PetscWeakFormView(ds->wf, viewer);
229: PetscViewerASCIIPopTab(viewer);
230: return 0;
231: }
233: /*@C
234: PetscDSViewFromOptions - View from Options
236: Collective on PetscDS
238: Input Parameters:
239: + A - the PetscDS object
240: . obj - Optional object
241: - name - command line option
243: Level: intermediate
244: .seealso: PetscDS, PetscDSView, PetscObjectViewFromOptions(), PetscDSCreate()
245: @*/
246: PetscErrorCode PetscDSViewFromOptions(PetscDS A,PetscObject obj,const char name[])
247: {
249: PetscObjectViewFromOptions((PetscObject)A,obj,name);
250: return 0;
251: }
253: /*@C
254: PetscDSView - Views a PetscDS
256: Collective on prob
258: Input Parameters:
259: + prob - the PetscDS object to view
260: - v - the viewer
262: Level: developer
264: .seealso PetscDSDestroy()
265: @*/
266: PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
267: {
268: PetscBool iascii;
271: if (!v) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);
273: PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
274: if (iascii) PetscDSView_Ascii(prob, v);
275: if (prob->ops->view) (*prob->ops->view)(prob, v);
276: return 0;
277: }
279: /*@
280: PetscDSSetFromOptions - sets parameters in a PetscDS from the options database
282: Collective on prob
284: Input Parameter:
285: . prob - the PetscDS object to set options for
287: Options Database:
288: + -petscds_type <type> - Set the DS type
289: . -petscds_view <view opt> - View the DS
290: . -petscds_jac_pre - Turn formation of a separate Jacobian preconditioner on or off
291: . -bc_<name> <ids> - Specify a list of label ids for a boundary condition
292: - -bc_<name>_comp <comps> - Specify a list of field components to constrain for a boundary condition
294: Level: developer
296: .seealso PetscDSView()
297: @*/
298: PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
299: {
300: DSBoundary b;
301: const char *defaultType;
302: char name[256];
303: PetscBool flg;
307: if (!((PetscObject) prob)->type_name) {
308: defaultType = PETSCDSBASIC;
309: } else {
310: defaultType = ((PetscObject) prob)->type_name;
311: }
312: PetscDSRegisterAll();
314: PetscObjectOptionsBegin((PetscObject) prob);
315: for (b = prob->boundary; b; b = b->next) {
316: char optname[1024];
317: PetscInt ids[1024], len = 1024;
318: PetscBool flg;
320: PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name);
321: PetscMemzero(ids, sizeof(ids));
322: PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg);
323: if (flg) {
324: b->Nv = len;
325: PetscFree(b->values);
326: PetscMalloc1(len, &b->values);
327: PetscArraycpy(b->values, ids, len);
328: PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values);
329: }
330: len = 1024;
331: PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name);
332: PetscMemzero(ids, sizeof(ids));
333: PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg);
334: if (flg) {
335: b->Nc = len;
336: PetscFree(b->comps);
337: PetscMalloc1(len, &b->comps);
338: PetscArraycpy(b->comps, ids, len);
339: }
340: }
341: PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);
342: if (flg) {
343: PetscDSSetType(prob, name);
344: } else if (!((PetscObject) prob)->type_name) {
345: PetscDSSetType(prob, defaultType);
346: }
347: PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg);
348: if (prob->ops->setfromoptions) (*prob->ops->setfromoptions)(prob);
349: /* process any options handlers added with PetscObjectAddOptionsHandler() */
350: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) prob);
351: PetscOptionsEnd();
352: if (prob->Nf) PetscDSViewFromOptions(prob, NULL, "-petscds_view");
353: return 0;
354: }
356: /*@C
357: PetscDSSetUp - Construct data structures for the PetscDS
359: Collective on prob
361: Input Parameter:
362: . prob - the PetscDS object to setup
364: Level: developer
366: .seealso PetscDSView(), PetscDSDestroy()
367: @*/
368: PetscErrorCode PetscDSSetUp(PetscDS prob)
369: {
370: const PetscInt Nf = prob->Nf;
371: PetscBool hasH = PETSC_FALSE;
372: PetscInt dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
376: if (prob->setup) return 0;
377: /* Calculate sizes */
378: PetscDSGetSpatialDimension(prob, &dim);
379: PetscDSGetCoordinateDimension(prob, &dimEmbed);
380: prob->totDim = prob->totComp = 0;
381: PetscMalloc2(Nf,&prob->Nc,Nf,&prob->Nb);
382: PetscCalloc2(Nf+1,&prob->off,Nf+1,&prob->offDer);
383: 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]);
384: PetscMalloc2(Nf,&prob->T,Nf,&prob->Tf);
385: for (f = 0; f < Nf; ++f) {
386: PetscObject obj;
387: PetscClassId id;
388: PetscQuadrature q = NULL;
389: PetscInt Nq = 0, Nb, Nc;
391: PetscDSGetDiscretization(prob, f, &obj);
392: if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
393: if (!obj) {
394: /* Empty mesh */
395: Nb = Nc = 0;
396: prob->T[f] = prob->Tf[f] = NULL;
397: } else {
398: PetscObjectGetClassId(obj, &id);
399: if (id == PETSCFE_CLASSID) {
400: PetscFE fe = (PetscFE) obj;
402: PetscFEGetQuadrature(fe, &q);
403: PetscFEGetDimension(fe, &Nb);
404: PetscFEGetNumComponents(fe, &Nc);
405: PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]);
406: PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]);
407: } else if (id == PETSCFV_CLASSID) {
408: PetscFV fv = (PetscFV) obj;
410: PetscFVGetQuadrature(fv, &q);
411: PetscFVGetNumComponents(fv, &Nc);
412: Nb = Nc;
413: PetscFVGetCellTabulation(fv, &prob->T[f]);
414: /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
415: } else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
416: }
417: prob->Nc[f] = Nc;
418: prob->Nb[f] = Nb;
419: prob->off[f+1] = Nc + prob->off[f];
420: prob->offDer[f+1] = Nc*dim + prob->offDer[f];
421: prob->offCohesive[0][f+1] = (prob->cohesive[f] ? Nc : Nc*2) + prob->offCohesive[0][f];
422: prob->offDerCohesive[0][f+1] = (prob->cohesive[f] ? Nc : Nc*2)*dimEmbed + prob->offDerCohesive[0][f];
423: prob->offCohesive[1][f] = (prob->cohesive[f] ? 0 : Nc) + prob->offCohesive[0][f];
424: prob->offDerCohesive[1][f] = (prob->cohesive[f] ? 0 : Nc)*dimEmbed + prob->offDerCohesive[0][f];
425: prob->offCohesive[2][f+1] = (prob->cohesive[f] ? Nc : Nc*2) + prob->offCohesive[2][f];
426: prob->offDerCohesive[2][f+1] = (prob->cohesive[f] ? Nc : Nc*2)*dimEmbed + prob->offDerCohesive[2][f];
427: if (q) PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL);
428: NqMax = PetscMax(NqMax, Nq);
429: NbMax = PetscMax(NbMax, Nb);
430: NcMax = PetscMax(NcMax, Nc);
431: prob->totDim += Nb;
432: prob->totComp += Nc;
433: /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
434: if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
435: }
436: prob->offCohesive[1][Nf] = prob->offCohesive[0][Nf];
437: prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
438: /* Allocate works space */
439: NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
440: 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);
441: PetscMalloc5(dimEmbed,&prob->x,NbMax*NcMax,&prob->basisReal,NbMax*NcMax*dimEmbed,&prob->basisDerReal,NbMax*NcMax,&prob->testReal,NbMax*NcMax*dimEmbed,&prob->testDerReal);
442: PetscMalloc6(NsMax*NqMax*NcMax,&prob->f0,NsMax*NqMax*NcMax*dimEmbed,&prob->f1,
443: NsMax*NsMax*NqMax*NcMax*NcMax,&prob->g0,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g1,
444: NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g2,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed*dimEmbed,&prob->g3);
445: if (prob->ops->setup) (*prob->ops->setup)(prob);
446: prob->setup = PETSC_TRUE;
447: return 0;
448: }
450: static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
451: {
452: PetscFree2(prob->Nc,prob->Nb);
453: PetscFree2(prob->off,prob->offDer);
454: PetscFree6(prob->offCohesive[0],prob->offCohesive[1],prob->offCohesive[2],prob->offDerCohesive[0],prob->offDerCohesive[1],prob->offDerCohesive[2]);
455: PetscFree2(prob->T,prob->Tf);
456: PetscFree3(prob->u,prob->u_t,prob->u_x);
457: PetscFree5(prob->x,prob->basisReal, prob->basisDerReal,prob->testReal,prob->testDerReal);
458: PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);
459: return 0;
460: }
462: static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
463: {
464: PetscObject *tmpd;
465: PetscBool *tmpi;
466: PetscInt *tmpk;
467: PetscBool *tmpc;
468: PetscPointFunc *tmpup;
469: PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
470: void **tmpexactCtx, **tmpexactCtx_t;
471: void **tmpctx;
472: PetscInt Nf = prob->Nf, f;
474: if (Nf >= NfNew) return 0;
475: prob->setup = PETSC_FALSE;
476: PetscDSDestroyStructs_Static(prob);
477: PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk);
478: for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpi[f] = prob->implicit[f]; tmpc[f] = prob->cohesive[f]; tmpk[f] = prob->jetDegree[f];}
479: for (f = Nf; f < NfNew; ++f) {tmpd[f] = NULL; tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE; tmpk[f] = 1;}
480: PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree);
481: PetscWeakFormSetNumFields(prob->wf, NfNew);
482: prob->Nf = NfNew;
483: prob->disc = tmpd;
484: prob->implicit = tmpi;
485: prob->cohesive = tmpc;
486: prob->jetDegree = tmpk;
487: PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx);
488: for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
489: for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
490: for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
491: for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
492: PetscFree2(prob->update, prob->ctx);
493: prob->update = tmpup;
494: prob->ctx = tmpctx;
495: PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t);
496: for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
497: for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
498: for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
499: for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
500: for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
501: for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
502: for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
503: for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
504: PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t);
505: prob->exactSol = tmpexactSol;
506: prob->exactCtx = tmpexactCtx;
507: prob->exactSol_t = tmpexactSol_t;
508: prob->exactCtx_t = tmpexactCtx_t;
509: return 0;
510: }
512: /*@
513: PetscDSDestroy - Destroys a PetscDS object
515: Collective on prob
517: Input Parameter:
518: . prob - the PetscDS object to destroy
520: Level: developer
522: .seealso PetscDSView()
523: @*/
524: PetscErrorCode PetscDSDestroy(PetscDS *ds)
525: {
526: PetscInt f;
528: if (!*ds) return 0;
531: if (--((PetscObject)(*ds))->refct > 0) {*ds = NULL; return 0;}
532: ((PetscObject) (*ds))->refct = 0;
533: if ((*ds)->subprobs) {
534: PetscInt dim, d;
536: PetscDSGetSpatialDimension(*ds, &dim);
537: for (d = 0; d < dim; ++d) PetscDSDestroy(&(*ds)->subprobs[d]);
538: }
539: PetscFree((*ds)->subprobs);
540: PetscDSDestroyStructs_Static(*ds);
541: for (f = 0; f < (*ds)->Nf; ++f) {
542: PetscObjectDereference((*ds)->disc[f]);
543: }
544: PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree);
545: PetscWeakFormDestroy(&(*ds)->wf);
546: PetscFree2((*ds)->update,(*ds)->ctx);
547: PetscFree4((*ds)->exactSol,(*ds)->exactCtx,(*ds)->exactSol_t,(*ds)->exactCtx_t);
548: if ((*ds)->ops->destroy) (*(*ds)->ops->destroy)(*ds);
549: PetscDSDestroyBoundary(*ds);
550: PetscFree((*ds)->constants);
551: PetscHeaderDestroy(ds);
552: return 0;
553: }
555: /*@
556: PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType().
558: Collective
560: Input Parameter:
561: . comm - The communicator for the PetscDS object
563: Output Parameter:
564: . ds - The PetscDS object
566: Level: beginner
568: .seealso: PetscDSSetType(), PETSCDSBASIC
569: @*/
570: PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
571: {
572: PetscDS p;
575: *ds = NULL;
576: PetscDSInitializePackage();
578: PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);
580: p->Nf = 0;
581: p->setup = PETSC_FALSE;
582: p->numConstants = 0;
583: p->constants = NULL;
584: p->dimEmbed = -1;
585: p->useJacPre = PETSC_TRUE;
586: PetscWeakFormCreate(comm, &p->wf);
588: *ds = p;
589: return 0;
590: }
592: /*@
593: PetscDSGetNumFields - Returns the number of fields in the DS
595: Not collective
597: Input Parameter:
598: . prob - The PetscDS object
600: Output Parameter:
601: . Nf - The number of fields
603: Level: beginner
605: .seealso: PetscDSGetSpatialDimension(), PetscDSCreate()
606: @*/
607: PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
608: {
611: *Nf = prob->Nf;
612: return 0;
613: }
615: /*@
616: PetscDSGetSpatialDimension - Returns the spatial dimension of the DS, meaning the topological dimension of the discretizations
618: Not collective
620: Input Parameter:
621: . prob - The PetscDS object
623: Output Parameter:
624: . dim - The spatial dimension
626: Level: beginner
628: .seealso: PetscDSGetCoordinateDimension(), PetscDSGetNumFields(), PetscDSCreate()
629: @*/
630: PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
631: {
634: *dim = 0;
635: if (prob->Nf) {
636: PetscObject obj;
637: PetscClassId id;
639: PetscDSGetDiscretization(prob, 0, &obj);
640: if (obj) {
641: PetscObjectGetClassId(obj, &id);
642: if (id == PETSCFE_CLASSID) PetscFEGetSpatialDimension((PetscFE) obj, dim);
643: else if (id == PETSCFV_CLASSID) PetscFVGetSpatialDimension((PetscFV) obj, dim);
644: else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
645: }
646: }
647: return 0;
648: }
650: /*@
651: PetscDSGetCoordinateDimension - Returns the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded
653: Not collective
655: Input Parameter:
656: . prob - The PetscDS object
658: Output Parameter:
659: . dimEmbed - The coordinate dimension
661: Level: beginner
663: .seealso: PetscDSSetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
664: @*/
665: PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
666: {
670: *dimEmbed = prob->dimEmbed;
671: return 0;
672: }
674: /*@
675: PetscDSSetCoordinateDimension - Set the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded
677: Logically collective on prob
679: Input Parameters:
680: + prob - The PetscDS object
681: - dimEmbed - The coordinate dimension
683: Level: beginner
685: .seealso: PetscDSGetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
686: @*/
687: PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
688: {
691: prob->dimEmbed = dimEmbed;
692: return 0;
693: }
695: /*@
696: PetscDSIsCohesive - Returns the flag indicating that this DS is for a cohesive cell
698: Not collective
700: Input Parameter:
701: . ds - The PetscDS object
703: Output Parameter:
704: . isCohesive - The flag
706: Level: developer
708: .seealso: PetscDSGetNumCohesive(), PetscDSGetCohesive(), PetscDSSetCohesive(), PetscDSCreate()
709: @*/
710: PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
711: {
714: *isCohesive = ds->isCohesive;
715: return 0;
716: }
718: /*@
719: PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell
721: Not collective
723: Input Parameter:
724: . ds - The PetscDS object
726: Output Parameter:
727: . numCohesive - The number of cohesive fields
729: Level: developer
731: .seealso: PetscDSSetCohesive(), PetscDSCreate()
732: @*/
733: PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
734: {
735: PetscInt f;
739: *numCohesive = 0;
740: for (f = 0; f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
741: return 0;
742: }
744: /*@
745: PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
747: Not collective
749: Input Parameters:
750: + ds - The PetscDS object
751: - f - The field index
753: Output Parameter:
754: . isCohesive - The flag
756: Level: developer
758: .seealso: PetscDSSetCohesive(), PetscDSIsCohesive(), PetscDSCreate()
759: @*/
760: PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
761: {
765: *isCohesive = ds->cohesive[f];
766: return 0;
767: }
769: /*@
770: PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell
772: Not collective
774: Input Parameters:
775: + ds - The PetscDS object
776: . f - The field index
777: - isCohesive - The flag for a cohesive field
779: Level: developer
781: .seealso: PetscDSGetCohesive(), PetscDSIsCohesive(), PetscDSCreate()
782: @*/
783: PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
784: {
785: PetscInt i;
789: ds->cohesive[f] = isCohesive;
790: ds->isCohesive = PETSC_FALSE;
791: for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
792: return 0;
793: }
795: /*@
796: PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
798: Not collective
800: Input Parameter:
801: . prob - The PetscDS object
803: Output Parameter:
804: . dim - The total problem dimension
806: Level: beginner
808: .seealso: PetscDSGetNumFields(), PetscDSCreate()
809: @*/
810: PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
811: {
813: PetscDSSetUp(prob);
815: *dim = prob->totDim;
816: return 0;
817: }
819: /*@
820: PetscDSGetTotalComponents - Returns the total number of components in this system
822: Not collective
824: Input Parameter:
825: . prob - The PetscDS object
827: Output Parameter:
828: . dim - The total number of components
830: Level: beginner
832: .seealso: PetscDSGetNumFields(), PetscDSCreate()
833: @*/
834: PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
835: {
837: PetscDSSetUp(prob);
839: *Nc = prob->totComp;
840: return 0;
841: }
843: /*@
844: PetscDSGetDiscretization - Returns the discretization object for the given field
846: Not collective
848: Input Parameters:
849: + prob - The PetscDS object
850: - f - The field number
852: Output Parameter:
853: . disc - The discretization object
855: Level: beginner
857: .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
858: @*/
859: PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
860: {
865: *disc = prob->disc[f];
866: return 0;
867: }
869: /*@
870: PetscDSSetDiscretization - Sets the discretization object for the given field
872: Not collective
874: Input Parameters:
875: + prob - The PetscDS object
876: . f - The field number
877: - disc - The discretization object
879: Level: beginner
881: .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
882: @*/
883: PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
884: {
888: PetscDSEnlarge_Static(prob, f+1);
889: PetscObjectDereference(prob->disc[f]);
890: prob->disc[f] = disc;
891: PetscObjectReference(disc);
892: if (disc) {
893: PetscClassId id;
895: PetscObjectGetClassId(disc, &id);
896: if (id == PETSCFE_CLASSID) {
897: PetscDSSetImplicit(prob, f, PETSC_TRUE);
898: } else if (id == PETSCFV_CLASSID) {
899: PetscDSSetImplicit(prob, f, PETSC_FALSE);
900: }
901: PetscDSSetJetDegree(prob, f, 1);
902: }
903: return 0;
904: }
906: /*@
907: PetscDSGetWeakForm - Returns the weak form object
909: Not collective
911: Input Parameter:
912: . ds - The PetscDS object
914: Output Parameter:
915: . wf - The weak form object
917: Level: beginner
919: .seealso: PetscDSSetWeakForm(), PetscDSGetNumFields(), PetscDSCreate()
920: @*/
921: PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
922: {
925: *wf = ds->wf;
926: return 0;
927: }
929: /*@
930: PetscDSSetWeakForm - Sets the weak form object
932: Not collective
934: Input Parameters:
935: + ds - The PetscDS object
936: - wf - The weak form object
938: Level: beginner
940: .seealso: PetscDSGetWeakForm(), PetscDSGetNumFields(), PetscDSCreate()
941: @*/
942: PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
943: {
946: PetscObjectDereference((PetscObject) ds->wf);
947: ds->wf = wf;
948: PetscObjectReference((PetscObject) wf);
949: PetscWeakFormSetNumFields(wf, ds->Nf);
950: return 0;
951: }
953: /*@
954: PetscDSAddDiscretization - Adds a discretization object
956: Not collective
958: Input Parameters:
959: + prob - The PetscDS object
960: - disc - The boundary discretization object
962: Level: beginner
964: .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
965: @*/
966: PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
967: {
968: PetscDSSetDiscretization(prob, prob->Nf, disc);
969: return 0;
970: }
972: /*@
973: PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the DS
975: Not collective
977: Input Parameter:
978: . prob - The PetscDS object
980: Output Parameter:
981: . q - The quadrature object
983: Level: intermediate
985: .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
986: @*/
987: PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
988: {
989: PetscObject obj;
990: PetscClassId id;
992: *q = NULL;
993: if (!prob->Nf) return 0;
994: PetscDSGetDiscretization(prob, 0, &obj);
995: PetscObjectGetClassId(obj, &id);
996: if (id == PETSCFE_CLASSID) PetscFEGetQuadrature((PetscFE) obj, q);
997: else if (id == PETSCFV_CLASSID) PetscFVGetQuadrature((PetscFV) obj, q);
998: else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
999: return 0;
1000: }
1002: /*@
1003: PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for IMEX
1005: Not collective
1007: Input Parameters:
1008: + prob - The PetscDS object
1009: - f - The field number
1011: Output Parameter:
1012: . implicit - The flag indicating what kind of solve to use for this field
1014: Level: developer
1016: .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1017: @*/
1018: PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1019: {
1023: *implicit = prob->implicit[f];
1024: return 0;
1025: }
1027: /*@
1028: PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for IMEX
1030: Not collective
1032: Input Parameters:
1033: + prob - The PetscDS object
1034: . f - The field number
1035: - implicit - The flag indicating what kind of solve to use for this field
1037: Level: developer
1039: .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1040: @*/
1041: PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1042: {
1045: prob->implicit[f] = implicit;
1046: return 0;
1047: }
1049: /*@
1050: PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1052: Not collective
1054: Input Parameters:
1055: + ds - The PetscDS object
1056: - f - The field number
1058: Output Parameter:
1059: . k - The highest derivative we need to tabulate
1061: Level: developer
1063: .seealso: PetscDSSetJetDegree(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1064: @*/
1065: PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1066: {
1070: *k = ds->jetDegree[f];
1071: return 0;
1072: }
1074: /*@
1075: PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.
1077: Not collective
1079: Input Parameters:
1080: + ds - The PetscDS object
1081: . f - The field number
1082: - k - The highest derivative we need to tabulate
1084: Level: developer
1086: .seealso: PetscDSGetJetDegree(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1087: @*/
1088: PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1089: {
1092: ds->jetDegree[f] = k;
1093: return 0;
1094: }
1096: PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f,
1097: void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1098: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1099: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1100: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1101: {
1102: PetscPointFunc *tmp;
1103: PetscInt n;
1108: PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp);
1109: *obj = tmp ? tmp[0] : NULL;
1110: return 0;
1111: }
1113: PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f,
1114: void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1115: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1116: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1117: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1118: {
1122: PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj);
1123: return 0;
1124: }
1126: /*@C
1127: PetscDSGetResidual - Get the pointwise residual function for a given test field
1129: Not collective
1131: Input Parameters:
1132: + ds - The PetscDS
1133: - f - The test field number
1135: Output Parameters:
1136: + f0 - integrand for the test function term
1137: - f1 - integrand for the test function gradient term
1139: Note: We are using a first order FEM model for the weak form:
1141: \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)
1143: The calling sequence for the callbacks f0 and f1 is given by:
1145: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1146: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1147: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1148: $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1150: + dim - the spatial dimension
1151: . Nf - the number of fields
1152: . uOff - the offset into u[] and u_t[] for each field
1153: . uOff_x - the offset into u_x[] for each field
1154: . u - each field evaluated at the current point
1155: . u_t - the time derivative of each field evaluated at the current point
1156: . u_x - the gradient of each field evaluated at the current point
1157: . aOff - the offset into a[] and a_t[] for each auxiliary field
1158: . aOff_x - the offset into a_x[] for each auxiliary field
1159: . a - each auxiliary field evaluated at the current point
1160: . a_t - the time derivative of each auxiliary field evaluated at the current point
1161: . a_x - the gradient of auxiliary each field evaluated at the current point
1162: . t - current time
1163: . x - coordinates of the current point
1164: . numConstants - number of constant parameters
1165: . constants - constant parameters
1166: - f0 - output values at the current point
1168: Level: intermediate
1170: .seealso: PetscDSSetResidual()
1171: @*/
1172: PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f,
1173: void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1174: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1175: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1176: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1177: void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1178: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1179: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1180: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1181: {
1182: PetscPointFunc *tmp0, *tmp1;
1183: PetscInt n0, n1;
1187: PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1);
1188: *f0 = tmp0 ? tmp0[0] : NULL;
1189: *f1 = tmp1 ? tmp1[0] : NULL;
1190: return 0;
1191: }
1193: /*@C
1194: PetscDSSetResidual - Set the pointwise residual function for a given test field
1196: Not collective
1198: Input Parameters:
1199: + ds - The PetscDS
1200: . f - The test field number
1201: . f0 - integrand for the test function term
1202: - f1 - integrand for the test function gradient term
1204: Note: We are using a first order FEM model for the weak form:
1206: \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)
1208: The calling sequence for the callbacks f0 and f1 is given by:
1210: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1211: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1212: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1213: $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1215: + dim - the spatial dimension
1216: . Nf - the number of fields
1217: . uOff - the offset into u[] and u_t[] for each field
1218: . uOff_x - the offset into u_x[] for each field
1219: . u - each field evaluated at the current point
1220: . u_t - the time derivative of each field evaluated at the current point
1221: . u_x - the gradient of each field evaluated at the current point
1222: . aOff - the offset into a[] and a_t[] for each auxiliary field
1223: . aOff_x - the offset into a_x[] for each auxiliary field
1224: . a - each auxiliary field evaluated at the current point
1225: . a_t - the time derivative of each auxiliary field evaluated at the current point
1226: . a_x - the gradient of auxiliary each field evaluated at the current point
1227: . t - current time
1228: . x - coordinates of the current point
1229: . numConstants - number of constant parameters
1230: . constants - constant parameters
1231: - f0 - output values at the current point
1233: Level: intermediate
1235: .seealso: PetscDSGetResidual()
1236: @*/
1237: PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f,
1238: void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1239: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1240: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1241: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1242: void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1243: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1244: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1245: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1246: {
1251: PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1);
1252: return 0;
1253: }
1255: /*@C
1256: PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field
1258: Not collective
1260: Input Parameters:
1261: + ds - The PetscDS
1262: - f - The test field number
1264: Output Parameters:
1265: + f0 - integrand for the test function term
1266: - f1 - integrand for the test function gradient term
1268: Note: We are using a first order FEM model for the weak form:
1270: \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)
1272: The calling sequence for the callbacks f0 and f1 is given by:
1274: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1275: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1276: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1277: $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1279: + dim - the spatial dimension
1280: . Nf - the number of fields
1281: . uOff - the offset into u[] and u_t[] for each field
1282: . uOff_x - the offset into u_x[] for each field
1283: . u - each field evaluated at the current point
1284: . u_t - the time derivative of each field evaluated at the current point
1285: . u_x - the gradient of each field evaluated at the current point
1286: . aOff - the offset into a[] and a_t[] for each auxiliary field
1287: . aOff_x - the offset into a_x[] for each auxiliary field
1288: . a - each auxiliary field evaluated at the current point
1289: . a_t - the time derivative of each auxiliary field evaluated at the current point
1290: . a_x - the gradient of auxiliary each field evaluated at the current point
1291: . t - current time
1292: . x - coordinates of the current point
1293: . numConstants - number of constant parameters
1294: . constants - constant parameters
1295: - f0 - output values at the current point
1297: Level: intermediate
1299: .seealso: PetscDSSetRHSResidual()
1300: @*/
1301: PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f,
1302: void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1303: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1304: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1305: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1306: void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1307: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1308: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1309: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1310: {
1311: PetscPointFunc *tmp0, *tmp1;
1312: PetscInt n0, n1;
1316: PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1);
1317: *f0 = tmp0 ? tmp0[0] : NULL;
1318: *f1 = tmp1 ? tmp1[0] : NULL;
1319: return 0;
1320: }
1322: /*@C
1323: PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field
1325: Not collective
1327: Input Parameters:
1328: + ds - The PetscDS
1329: . f - The test field number
1330: . f0 - integrand for the test function term
1331: - f1 - integrand for the test function gradient term
1333: Note: We are using a first order FEM model for the weak form:
1335: \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)
1337: The calling sequence for the callbacks f0 and f1 is given by:
1339: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1340: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1341: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1342: $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1344: + dim - the spatial dimension
1345: . Nf - the number of fields
1346: . uOff - the offset into u[] and u_t[] for each field
1347: . uOff_x - the offset into u_x[] for each field
1348: . u - each field evaluated at the current point
1349: . u_t - the time derivative of each field evaluated at the current point
1350: . u_x - the gradient of each field evaluated at the current point
1351: . aOff - the offset into a[] and a_t[] for each auxiliary field
1352: . aOff_x - the offset into a_x[] for each auxiliary field
1353: . a - each auxiliary field evaluated at the current point
1354: . a_t - the time derivative of each auxiliary field evaluated at the current point
1355: . a_x - the gradient of auxiliary each field evaluated at the current point
1356: . t - current time
1357: . x - coordinates of the current point
1358: . numConstants - number of constant parameters
1359: . constants - constant parameters
1360: - f0 - output values at the current point
1362: Level: intermediate
1364: .seealso: PetscDSGetResidual()
1365: @*/
1366: PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f,
1367: void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1368: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1369: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1370: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1371: void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1372: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1373: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1374: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1375: {
1380: PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1);
1381: return 0;
1382: }
1384: /*@C
1385: PetscDSHasJacobian - Signals that Jacobian functions have been set
1387: Not collective
1389: Input Parameter:
1390: . prob - The PetscDS
1392: Output Parameter:
1393: . hasJac - flag that pointwise function for the Jacobian has been set
1395: Level: intermediate
1397: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1398: @*/
1399: PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1400: {
1402: PetscWeakFormHasJacobian(ds->wf, hasJac);
1403: return 0;
1404: }
1406: /*@C
1407: PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1409: Not collective
1411: Input Parameters:
1412: + ds - The PetscDS
1413: . f - The test field number
1414: - g - The field number
1416: Output Parameters:
1417: + g0 - integrand for the test and basis function term
1418: . g1 - integrand for the test function and basis function gradient term
1419: . g2 - integrand for the test function gradient and basis function term
1420: - g3 - integrand for the test function gradient and basis function gradient term
1422: Note: We are using a first order FEM model for the weak form:
1424: \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
1426: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1428: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1429: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1430: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1431: $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1433: + dim - the spatial dimension
1434: . Nf - the number of fields
1435: . uOff - the offset into u[] and u_t[] for each field
1436: . uOff_x - the offset into u_x[] for each field
1437: . u - each field evaluated at the current point
1438: . u_t - the time derivative of each field evaluated at the current point
1439: . u_x - the gradient of each field evaluated at the current point
1440: . aOff - the offset into a[] and a_t[] for each auxiliary field
1441: . aOff_x - the offset into a_x[] for each auxiliary field
1442: . a - each auxiliary field evaluated at the current point
1443: . a_t - the time derivative of each auxiliary field evaluated at the current point
1444: . a_x - the gradient of auxiliary each field evaluated at the current point
1445: . t - current time
1446: . u_tShift - the multiplier a for dF/dU_t
1447: . x - coordinates of the current point
1448: . numConstants - number of constant parameters
1449: . constants - constant parameters
1450: - g0 - output values at the current point
1452: Level: intermediate
1454: .seealso: PetscDSSetJacobian()
1455: @*/
1456: PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g,
1457: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1458: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1459: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1460: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1461: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1462: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1463: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1464: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1465: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1466: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1467: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1468: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1469: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1470: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1471: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1472: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1473: {
1474: PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
1475: PetscInt n0, n1, n2, n3;
1480: PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
1481: *g0 = tmp0 ? tmp0[0] : NULL;
1482: *g1 = tmp1 ? tmp1[0] : NULL;
1483: *g2 = tmp2 ? tmp2[0] : NULL;
1484: *g3 = tmp3 ? tmp3[0] : NULL;
1485: return 0;
1486: }
1488: /*@C
1489: PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1491: Not collective
1493: Input Parameters:
1494: + ds - The PetscDS
1495: . f - The test field number
1496: . g - The field number
1497: . g0 - integrand for the test and basis function term
1498: . g1 - integrand for the test function and basis function gradient term
1499: . g2 - integrand for the test function gradient and basis function term
1500: - g3 - integrand for the test function gradient and basis function gradient term
1502: Note: We are using a first order FEM model for the weak form:
1504: \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
1506: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1508: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1509: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1510: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1511: $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1513: + dim - the spatial dimension
1514: . Nf - the number of fields
1515: . uOff - the offset into u[] and u_t[] for each field
1516: . uOff_x - the offset into u_x[] for each field
1517: . u - each field evaluated at the current point
1518: . u_t - the time derivative of each field evaluated at the current point
1519: . u_x - the gradient of each field evaluated at the current point
1520: . aOff - the offset into a[] and a_t[] for each auxiliary field
1521: . aOff_x - the offset into a_x[] for each auxiliary field
1522: . a - each auxiliary field evaluated at the current point
1523: . a_t - the time derivative of each auxiliary field evaluated at the current point
1524: . a_x - the gradient of auxiliary each field evaluated at the current point
1525: . t - current time
1526: . u_tShift - the multiplier a for dF/dU_t
1527: . x - coordinates of the current point
1528: . numConstants - number of constant parameters
1529: . constants - constant parameters
1530: - g0 - output values at the current point
1532: Level: intermediate
1534: .seealso: PetscDSGetJacobian()
1535: @*/
1536: PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g,
1537: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1538: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1539: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1540: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1541: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1542: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1543: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1544: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1545: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1546: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1547: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1548: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1549: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1550: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1551: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1552: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1553: {
1561: PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
1562: return 0;
1563: }
1565: /*@C
1566: PetscDSUseJacobianPreconditioner - Whether to construct a Jacobian preconditioner
1568: Not collective
1570: Input Parameters:
1571: + prob - The PetscDS
1572: - useJacPre - flag that enables construction of a Jacobian preconditioner
1574: Level: intermediate
1576: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1577: @*/
1578: PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1579: {
1581: prob->useJacPre = useJacPre;
1582: return 0;
1583: }
1585: /*@C
1586: PetscDSHasJacobianPreconditioner - Signals that a Jacobian preconditioner matrix has been set
1588: Not collective
1590: Input Parameter:
1591: . prob - The PetscDS
1593: Output Parameter:
1594: . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1596: Level: intermediate
1598: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1599: @*/
1600: PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1601: {
1603: *hasJacPre = PETSC_FALSE;
1604: if (!ds->useJacPre) return 0;
1605: PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre);
1606: return 0;
1607: }
1609: /*@C
1610: PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing, the system matrix is used to build the preconditioner.
1612: Not collective
1614: Input Parameters:
1615: + ds - The PetscDS
1616: . f - The test field number
1617: - g - The field number
1619: Output Parameters:
1620: + g0 - integrand for the test and basis function term
1621: . g1 - integrand for the test function and basis function gradient term
1622: . g2 - integrand for the test function gradient and basis function term
1623: - g3 - integrand for the test function gradient and basis function gradient term
1625: Note: We are using a first order FEM model for the weak form:
1627: \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
1629: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1631: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1632: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1633: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1634: $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1636: + dim - the spatial dimension
1637: . Nf - the number of fields
1638: . uOff - the offset into u[] and u_t[] for each field
1639: . uOff_x - the offset into u_x[] for each field
1640: . u - each field evaluated at the current point
1641: . u_t - the time derivative of each field evaluated at the current point
1642: . u_x - the gradient of each field evaluated at the current point
1643: . aOff - the offset into a[] and a_t[] for each auxiliary field
1644: . aOff_x - the offset into a_x[] for each auxiliary field
1645: . a - each auxiliary field evaluated at the current point
1646: . a_t - the time derivative of each auxiliary field evaluated at the current point
1647: . a_x - the gradient of auxiliary each field evaluated at the current point
1648: . t - current time
1649: . u_tShift - the multiplier a for dF/dU_t
1650: . x - coordinates of the current point
1651: . numConstants - number of constant parameters
1652: . constants - constant parameters
1653: - g0 - output values at the current point
1655: Level: intermediate
1657: .seealso: PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1658: @*/
1659: PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
1660: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1661: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1662: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1663: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1664: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1665: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1666: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1667: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1668: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1669: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1670: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1671: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1672: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1673: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1674: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1675: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1676: {
1677: PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
1678: PetscInt n0, n1, n2, n3;
1683: PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
1684: *g0 = tmp0 ? tmp0[0] : NULL;
1685: *g1 = tmp1 ? tmp1[0] : NULL;
1686: *g2 = tmp2 ? tmp2[0] : NULL;
1687: *g3 = tmp3 ? tmp3[0] : NULL;
1688: return 0;
1689: }
1691: /*@C
1692: PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields. If this is missing, the system matrix is used to build the preconditioner.
1694: Not collective
1696: Input Parameters:
1697: + ds - The PetscDS
1698: . f - The test field number
1699: . g - The field number
1700: . g0 - integrand for the test and basis function term
1701: . g1 - integrand for the test function and basis function gradient term
1702: . g2 - integrand for the test function gradient and basis function term
1703: - g3 - integrand for the test function gradient and basis function gradient term
1705: Note: We are using a first order FEM model for the weak form:
1707: \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
1709: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1711: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1712: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1713: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1714: $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1716: + dim - the spatial dimension
1717: . Nf - the number of fields
1718: . uOff - the offset into u[] and u_t[] for each field
1719: . uOff_x - the offset into u_x[] for each field
1720: . u - each field evaluated at the current point
1721: . u_t - the time derivative of each field evaluated at the current point
1722: . u_x - the gradient of each field evaluated at the current point
1723: . aOff - the offset into a[] and a_t[] for each auxiliary field
1724: . aOff_x - the offset into a_x[] for each auxiliary field
1725: . a - each auxiliary field evaluated at the current point
1726: . a_t - the time derivative of each auxiliary field evaluated at the current point
1727: . a_x - the gradient of auxiliary each field evaluated at the current point
1728: . t - current time
1729: . u_tShift - the multiplier a for dF/dU_t
1730: . x - coordinates of the current point
1731: . numConstants - number of constant parameters
1732: . constants - constant parameters
1733: - g0 - output values at the current point
1735: Level: intermediate
1737: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobian()
1738: @*/
1739: PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
1740: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1741: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1742: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1743: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1744: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1745: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1746: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1747: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1748: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1749: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1750: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1751: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1752: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1753: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1754: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1755: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1756: {
1764: PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
1765: return 0;
1766: }
1768: /*@C
1769: PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1771: Not collective
1773: Input Parameter:
1774: . ds - The PetscDS
1776: Output Parameter:
1777: . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1779: Level: intermediate
1781: .seealso: PetscDSGetDynamicJacobian(), PetscDSSetDynamicJacobian(), PetscDSGetJacobian()
1782: @*/
1783: PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1784: {
1786: PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac);
1787: return 0;
1788: }
1790: /*@C
1791: PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1793: Not collective
1795: Input Parameters:
1796: + ds - The PetscDS
1797: . f - The test field number
1798: - g - The field number
1800: Output Parameters:
1801: + g0 - integrand for the test and basis function term
1802: . g1 - integrand for the test function and basis function gradient term
1803: . g2 - integrand for the test function gradient and basis function term
1804: - g3 - integrand for the test function gradient and basis function gradient term
1806: Note: We are using a first order FEM model for the weak form:
1808: \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
1810: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1812: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1813: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1814: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1815: $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1817: + dim - the spatial dimension
1818: . Nf - the number of fields
1819: . uOff - the offset into u[] and u_t[] for each field
1820: . uOff_x - the offset into u_x[] for each field
1821: . u - each field evaluated at the current point
1822: . u_t - the time derivative of each field evaluated at the current point
1823: . u_x - the gradient of each field evaluated at the current point
1824: . aOff - the offset into a[] and a_t[] for each auxiliary field
1825: . aOff_x - the offset into a_x[] for each auxiliary field
1826: . a - each auxiliary field evaluated at the current point
1827: . a_t - the time derivative of each auxiliary field evaluated at the current point
1828: . a_x - the gradient of auxiliary each field evaluated at the current point
1829: . t - current time
1830: . u_tShift - the multiplier a for dF/dU_t
1831: . x - coordinates of the current point
1832: . numConstants - number of constant parameters
1833: . constants - constant parameters
1834: - g0 - output values at the current point
1836: Level: intermediate
1838: .seealso: PetscDSSetJacobian()
1839: @*/
1840: PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g,
1841: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1842: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1843: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1844: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1845: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1846: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1847: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1848: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1849: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1850: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1851: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1852: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1853: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1854: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1855: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1856: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1857: {
1858: PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
1859: PetscInt n0, n1, n2, n3;
1864: PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
1865: *g0 = tmp0 ? tmp0[0] : NULL;
1866: *g1 = tmp1 ? tmp1[0] : NULL;
1867: *g2 = tmp2 ? tmp2[0] : NULL;
1868: *g3 = tmp3 ? tmp3[0] : NULL;
1869: return 0;
1870: }
1872: /*@C
1873: PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1875: Not collective
1877: Input Parameters:
1878: + ds - The PetscDS
1879: . f - The test field number
1880: . g - The field number
1881: . g0 - integrand for the test and basis function term
1882: . g1 - integrand for the test function and basis function gradient term
1883: . g2 - integrand for the test function gradient and basis function term
1884: - g3 - integrand for the test function gradient and basis function gradient term
1886: Note: We are using a first order FEM model for the weak form:
1888: \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
1890: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1892: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1893: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1894: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1895: $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1897: + dim - the spatial dimension
1898: . Nf - the number of fields
1899: . uOff - the offset into u[] and u_t[] for each field
1900: . uOff_x - the offset into u_x[] for each field
1901: . u - each field evaluated at the current point
1902: . u_t - the time derivative of each field evaluated at the current point
1903: . u_x - the gradient of each field evaluated at the current point
1904: . aOff - the offset into a[] and a_t[] for each auxiliary field
1905: . aOff_x - the offset into a_x[] for each auxiliary field
1906: . a - each auxiliary field evaluated at the current point
1907: . a_t - the time derivative of each auxiliary field evaluated at the current point
1908: . a_x - the gradient of auxiliary each field evaluated at the current point
1909: . t - current time
1910: . u_tShift - the multiplier a for dF/dU_t
1911: . x - coordinates of the current point
1912: . numConstants - number of constant parameters
1913: . constants - constant parameters
1914: - g0 - output values at the current point
1916: Level: intermediate
1918: .seealso: PetscDSGetJacobian()
1919: @*/
1920: PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g,
1921: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1922: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1923: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1924: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1925: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1926: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1927: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1928: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1929: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1930: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1931: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1932: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1933: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1934: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1935: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1936: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1937: {
1945: PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
1946: return 0;
1947: }
1949: /*@C
1950: PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
1952: Not collective
1954: Input Parameters:
1955: + ds - The PetscDS object
1956: - f - The field number
1958: Output Parameter:
1959: . r - Riemann solver
1961: Calling sequence for r:
1963: $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1965: + dim - The spatial dimension
1966: . Nf - The number of fields
1967: . x - The coordinates at a point on the interface
1968: . n - The normal vector to the interface
1969: . uL - The state vector to the left of the interface
1970: . uR - The state vector to the right of the interface
1971: . flux - output array of flux through the interface
1972: . numConstants - number of constant parameters
1973: . constants - constant parameters
1974: - ctx - optional user context
1976: Level: intermediate
1978: .seealso: PetscDSSetRiemannSolver()
1979: @*/
1980: PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f,
1981: 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))
1982: {
1983: PetscRiemannFunc *tmp;
1984: PetscInt n;
1989: PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp);
1990: *r = tmp ? tmp[0] : NULL;
1991: return 0;
1992: }
1994: /*@C
1995: PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
1997: Not collective
1999: Input Parameters:
2000: + ds - The PetscDS object
2001: . f - The field number
2002: - r - Riemann solver
2004: Calling sequence for r:
2006: $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
2008: + dim - The spatial dimension
2009: . Nf - The number of fields
2010: . x - The coordinates at a point on the interface
2011: . n - The normal vector to the interface
2012: . uL - The state vector to the left of the interface
2013: . uR - The state vector to the right of the interface
2014: . flux - output array of flux through the interface
2015: . numConstants - number of constant parameters
2016: . constants - constant parameters
2017: - ctx - optional user context
2019: Level: intermediate
2021: .seealso: PetscDSGetRiemannSolver()
2022: @*/
2023: PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f,
2024: 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))
2025: {
2029: PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r);
2030: return 0;
2031: }
2033: /*@C
2034: PetscDSGetUpdate - Get the pointwise update function for a given field
2036: Not collective
2038: Input Parameters:
2039: + ds - The PetscDS
2040: - f - The field number
2042: Output Parameter:
2043: . update - update function
2045: Note: The calling sequence for the callback update is given by:
2047: $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2048: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2049: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2050: $ PetscReal t, const PetscReal x[], PetscScalar uNew[])
2052: + dim - the spatial dimension
2053: . Nf - the number of fields
2054: . uOff - the offset into u[] and u_t[] for each field
2055: . uOff_x - the offset into u_x[] for each field
2056: . u - each field evaluated at the current point
2057: . u_t - the time derivative of each field evaluated at the current point
2058: . u_x - the gradient of each field evaluated at the current point
2059: . aOff - the offset into a[] and a_t[] for each auxiliary field
2060: . aOff_x - the offset into a_x[] for each auxiliary field
2061: . a - each auxiliary field evaluated at the current point
2062: . a_t - the time derivative of each auxiliary field evaluated at the current point
2063: . a_x - the gradient of auxiliary each field evaluated at the current point
2064: . t - current time
2065: . x - coordinates of the current point
2066: - uNew - new value for field at the current point
2068: Level: intermediate
2070: .seealso: PetscDSSetUpdate(), PetscDSSetResidual()
2071: @*/
2072: PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f,
2073: void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2074: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2075: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2076: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2077: {
2081: return 0;
2082: }
2084: /*@C
2085: PetscDSSetUpdate - Set the pointwise update function for a given field
2087: Not collective
2089: Input Parameters:
2090: + ds - The PetscDS
2091: . f - The field number
2092: - update - update function
2094: Note: The calling sequence for the callback update is given by:
2096: $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2097: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2098: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2099: $ PetscReal t, const PetscReal x[], PetscScalar uNew[])
2101: + dim - the spatial dimension
2102: . Nf - the number of fields
2103: . uOff - the offset into u[] and u_t[] for each field
2104: . uOff_x - the offset into u_x[] for each field
2105: . u - each field evaluated at the current point
2106: . u_t - the time derivative of each field evaluated at the current point
2107: . u_x - the gradient of each field evaluated at the current point
2108: . aOff - the offset into a[] and a_t[] for each auxiliary field
2109: . aOff_x - the offset into a_x[] for each auxiliary field
2110: . a - each auxiliary field evaluated at the current point
2111: . a_t - the time derivative of each auxiliary field evaluated at the current point
2112: . a_x - the gradient of auxiliary each field evaluated at the current point
2113: . t - current time
2114: . x - coordinates of the current point
2115: - uNew - new field values at the current point
2117: Level: intermediate
2119: .seealso: PetscDSGetResidual()
2120: @*/
2121: PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f,
2122: void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2123: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2124: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2125: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2126: {
2130: PetscDSEnlarge_Static(ds, f+1);
2131: ds->update[f] = update;
2132: return 0;
2133: }
2135: PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2136: {
2140: *(void**)ctx = ds->ctx[f];
2141: return 0;
2142: }
2144: PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2145: {
2148: PetscDSEnlarge_Static(ds, f+1);
2149: ds->ctx[f] = ctx;
2150: return 0;
2151: }
2153: /*@C
2154: PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
2156: Not collective
2158: Input Parameters:
2159: + ds - The PetscDS
2160: - f - The test field number
2162: Output Parameters:
2163: + f0 - boundary integrand for the test function term
2164: - f1 - boundary integrand for the test function gradient term
2166: Note: We are using a first order FEM model for the weak form:
2168: \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
2170: The calling sequence for the callbacks f0 and f1 is given by:
2172: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2173: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2174: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2175: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2177: + dim - the spatial dimension
2178: . Nf - the number of fields
2179: . uOff - the offset into u[] and u_t[] for each field
2180: . uOff_x - the offset into u_x[] for each field
2181: . u - each field evaluated at the current point
2182: . u_t - the time derivative of each field evaluated at the current point
2183: . u_x - the gradient of each field evaluated at the current point
2184: . aOff - the offset into a[] and a_t[] for each auxiliary field
2185: . aOff_x - the offset into a_x[] for each auxiliary field
2186: . a - each auxiliary field evaluated at the current point
2187: . a_t - the time derivative of each auxiliary field evaluated at the current point
2188: . a_x - the gradient of auxiliary each field evaluated at the current point
2189: . t - current time
2190: . x - coordinates of the current point
2191: . n - unit normal at the current point
2192: . numConstants - number of constant parameters
2193: . constants - constant parameters
2194: - f0 - output values at the current point
2196: Level: intermediate
2198: .seealso: PetscDSSetBdResidual()
2199: @*/
2200: PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f,
2201: void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2202: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2203: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2204: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
2205: void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2206: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2207: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2208: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2209: {
2210: PetscBdPointFunc *tmp0, *tmp1;
2211: PetscInt n0, n1;
2215: PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1);
2216: *f0 = tmp0 ? tmp0[0] : NULL;
2217: *f1 = tmp1 ? tmp1[0] : NULL;
2218: return 0;
2219: }
2221: /*@C
2222: PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2224: Not collective
2226: Input Parameters:
2227: + ds - The PetscDS
2228: . f - The test field number
2229: . f0 - boundary integrand for the test function term
2230: - f1 - boundary integrand for the test function gradient term
2232: Note: We are using a first order FEM model for the weak form:
2234: \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
2236: The calling sequence for the callbacks f0 and f1 is given by:
2238: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2239: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2240: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2241: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2243: + dim - the spatial dimension
2244: . Nf - the number of fields
2245: . uOff - the offset into u[] and u_t[] for each field
2246: . uOff_x - the offset into u_x[] for each field
2247: . u - each field evaluated at the current point
2248: . u_t - the time derivative of each field evaluated at the current point
2249: . u_x - the gradient of each field evaluated at the current point
2250: . aOff - the offset into a[] and a_t[] for each auxiliary field
2251: . aOff_x - the offset into a_x[] for each auxiliary field
2252: . a - each auxiliary field evaluated at the current point
2253: . a_t - the time derivative of each auxiliary field evaluated at the current point
2254: . a_x - the gradient of auxiliary each field evaluated at the current point
2255: . t - current time
2256: . x - coordinates of the current point
2257: . n - unit normal at the current point
2258: . numConstants - number of constant parameters
2259: . constants - constant parameters
2260: - f0 - output values at the current point
2262: Level: intermediate
2264: .seealso: PetscDSGetBdResidual()
2265: @*/
2266: PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f,
2267: void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2268: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2269: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2270: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
2271: void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2272: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2273: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2274: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2275: {
2278: PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1);
2279: return 0;
2280: }
2282: /*@
2283: PetscDSHasBdJacobian - Signals that boundary Jacobian functions have been set
2285: Not collective
2287: Input Parameter:
2288: . ds - The PetscDS
2290: Output Parameter:
2291: . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
2293: Level: intermediate
2295: .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian()
2296: @*/
2297: PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2298: {
2301: PetscWeakFormHasBdJacobian(ds->wf, hasBdJac);
2302: return 0;
2303: }
2305: /*@C
2306: PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2308: Not collective
2310: Input Parameters:
2311: + ds - The PetscDS
2312: . f - The test field number
2313: - g - The field number
2315: Output Parameters:
2316: + g0 - integrand for the test and basis function term
2317: . g1 - integrand for the test function and basis function gradient term
2318: . g2 - integrand for the test function gradient and basis function term
2319: - g3 - integrand for the test function gradient and basis function gradient term
2321: Note: We are using a first order FEM model for the weak form:
2323: \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
2325: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2327: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2328: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2329: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2330: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2332: + dim - the spatial dimension
2333: . Nf - the number of fields
2334: . uOff - the offset into u[] and u_t[] for each field
2335: . uOff_x - the offset into u_x[] for each field
2336: . u - each field evaluated at the current point
2337: . u_t - the time derivative of each field evaluated at the current point
2338: . u_x - the gradient of each field evaluated at the current point
2339: . aOff - the offset into a[] and a_t[] for each auxiliary field
2340: . aOff_x - the offset into a_x[] for each auxiliary field
2341: . a - each auxiliary field evaluated at the current point
2342: . a_t - the time derivative of each auxiliary field evaluated at the current point
2343: . a_x - the gradient of auxiliary each field evaluated at the current point
2344: . t - current time
2345: . u_tShift - the multiplier a for dF/dU_t
2346: . x - coordinates of the current point
2347: . n - normal at the current point
2348: . numConstants - number of constant parameters
2349: . constants - constant parameters
2350: - g0 - output values at the current point
2352: Level: intermediate
2354: .seealso: PetscDSSetBdJacobian()
2355: @*/
2356: PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g,
2357: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2358: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2359: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2360: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2361: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2362: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2363: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2364: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2365: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2366: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2367: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2368: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2369: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2370: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2371: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2372: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2373: {
2374: PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
2375: PetscInt n0, n1, n2, n3;
2380: PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
2381: *g0 = tmp0 ? tmp0[0] : NULL;
2382: *g1 = tmp1 ? tmp1[0] : NULL;
2383: *g2 = tmp2 ? tmp2[0] : NULL;
2384: *g3 = tmp3 ? tmp3[0] : NULL;
2385: return 0;
2386: }
2388: /*@C
2389: PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2391: Not collective
2393: Input Parameters:
2394: + ds - The PetscDS
2395: . f - The test field number
2396: . g - The field number
2397: . g0 - integrand for the test and basis function term
2398: . g1 - integrand for the test function and basis function gradient term
2399: . g2 - integrand for the test function gradient and basis function term
2400: - g3 - integrand for the test function gradient and basis function gradient term
2402: Note: We are using a first order FEM model for the weak form:
2404: \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
2406: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2408: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2409: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2410: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2411: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2413: + dim - the spatial dimension
2414: . Nf - the number of fields
2415: . uOff - the offset into u[] and u_t[] for each field
2416: . uOff_x - the offset into u_x[] for each field
2417: . u - each field evaluated at the current point
2418: . u_t - the time derivative of each field evaluated at the current point
2419: . u_x - the gradient of each field evaluated at the current point
2420: . aOff - the offset into a[] and a_t[] for each auxiliary field
2421: . aOff_x - the offset into a_x[] for each auxiliary field
2422: . a - each auxiliary field evaluated at the current point
2423: . a_t - the time derivative of each auxiliary field evaluated at the current point
2424: . a_x - the gradient of auxiliary each field evaluated at the current point
2425: . t - current time
2426: . u_tShift - the multiplier a for dF/dU_t
2427: . x - coordinates of the current point
2428: . n - normal at the current point
2429: . numConstants - number of constant parameters
2430: . constants - constant parameters
2431: - g0 - output values at the current point
2433: Level: intermediate
2435: .seealso: PetscDSGetBdJacobian()
2436: @*/
2437: PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g,
2438: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2439: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2440: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2441: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2442: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2443: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2444: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2445: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2446: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2447: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2448: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2449: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2450: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2451: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2452: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2453: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2454: {
2462: PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
2463: return 0;
2464: }
2466: /*@
2467: PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
2469: Not collective
2471: Input Parameter:
2472: . ds - The PetscDS
2474: Output Parameter:
2475: . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
2477: Level: intermediate
2479: .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian()
2480: @*/
2481: PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2482: {
2485: PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre);
2486: return 0;
2487: }
2489: /*@C
2490: PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
2492: Not collective
2494: Input Parameters:
2495: + ds - The PetscDS
2496: . f - The test field number
2497: - g - The field number
2499: Output Parameters:
2500: + g0 - integrand for the test and basis function term
2501: . g1 - integrand for the test function and basis function gradient term
2502: . g2 - integrand for the test function gradient and basis function term
2503: - g3 - integrand for the test function gradient and basis function gradient term
2505: Note: We are using a first order FEM model for the weak form:
2507: \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
2509: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2511: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2512: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2513: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2514: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2516: + dim - the spatial dimension
2517: . Nf - the number of fields
2518: . NfAux - the number of auxiliary fields
2519: . uOff - the offset into u[] and u_t[] for each field
2520: . uOff_x - the offset into u_x[] for each field
2521: . u - each field evaluated at the current point
2522: . u_t - the time derivative of each field evaluated at the current point
2523: . u_x - the gradient of each field evaluated at the current point
2524: . aOff - the offset into a[] and a_t[] for each auxiliary field
2525: . aOff_x - the offset into a_x[] for each auxiliary field
2526: . a - each auxiliary field evaluated at the current point
2527: . a_t - the time derivative of each auxiliary field evaluated at the current point
2528: . a_x - the gradient of auxiliary each field evaluated at the current point
2529: . t - current time
2530: . u_tShift - the multiplier a for dF/dU_t
2531: . x - coordinates of the current point
2532: . n - normal at the current point
2533: . numConstants - number of constant parameters
2534: . constants - constant parameters
2535: - g0 - output values at the current point
2537: This is not yet available in Fortran.
2539: Level: intermediate
2541: .seealso: PetscDSSetBdJacobianPreconditioner()
2542: @*/
2543: PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
2544: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2545: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2546: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2547: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2548: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2549: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2550: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2551: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2552: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2553: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2554: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2555: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2556: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2557: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2558: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2559: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2560: {
2561: PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
2562: PetscInt n0, n1, n2, n3;
2567: PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
2568: *g0 = tmp0 ? tmp0[0] : NULL;
2569: *g1 = tmp1 ? tmp1[0] : NULL;
2570: *g2 = tmp2 ? tmp2[0] : NULL;
2571: *g3 = tmp3 ? tmp3[0] : NULL;
2572: return 0;
2573: }
2575: /*@C
2576: PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
2578: Not collective
2580: Input Parameters:
2581: + ds - The PetscDS
2582: . f - The test field number
2583: . g - The field number
2584: . g0 - integrand for the test and basis function term
2585: . g1 - integrand for the test function and basis function gradient term
2586: . g2 - integrand for the test function gradient and basis function term
2587: - g3 - integrand for the test function gradient and basis function gradient term
2589: Note: We are using a first order FEM model for the weak form:
2591: \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
2593: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2595: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2596: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2597: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2598: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2600: + dim - the spatial dimension
2601: . Nf - the number of fields
2602: . NfAux - the number of auxiliary fields
2603: . uOff - the offset into u[] and u_t[] for each field
2604: . uOff_x - the offset into u_x[] for each field
2605: . u - each field evaluated at the current point
2606: . u_t - the time derivative of each field evaluated at the current point
2607: . u_x - the gradient of each field evaluated at the current point
2608: . aOff - the offset into a[] and a_t[] for each auxiliary field
2609: . aOff_x - the offset into a_x[] for each auxiliary field
2610: . a - each auxiliary field evaluated at the current point
2611: . a_t - the time derivative of each auxiliary field evaluated at the current point
2612: . a_x - the gradient of auxiliary each field evaluated at the current point
2613: . t - current time
2614: . u_tShift - the multiplier a for dF/dU_t
2615: . x - coordinates of the current point
2616: . n - normal at the current point
2617: . numConstants - number of constant parameters
2618: . constants - constant parameters
2619: - g0 - output values at the current point
2621: This is not yet available in Fortran.
2623: Level: intermediate
2625: .seealso: PetscDSGetBdJacobianPreconditioner()
2626: @*/
2627: PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
2628: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2629: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2630: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2631: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2632: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2633: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2634: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2635: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2636: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2637: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2638: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2639: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2640: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2641: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2642: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2643: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2644: {
2652: PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
2653: return 0;
2654: }
2656: /*@C
2657: PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2659: Not collective
2661: Input Parameters:
2662: + prob - The PetscDS
2663: - f - The test field number
2665: Output Parameters:
2666: + exactSol - exact solution for the test field
2667: - exactCtx - exact solution context
2669: Note: The calling sequence for the solution functions is given by:
2671: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2673: + dim - the spatial dimension
2674: . t - current time
2675: . x - coordinates of the current point
2676: . Nc - the number of field components
2677: . u - the solution field evaluated at the current point
2678: - ctx - a user context
2680: Level: intermediate
2682: .seealso: PetscDSSetExactSolution(), PetscDSGetExactSolutionTimeDerivative()
2683: @*/
2684: PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2685: {
2690: return 0;
2691: }
2693: /*@C
2694: PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2696: Not collective
2698: Input Parameters:
2699: + prob - The PetscDS
2700: . f - The test field number
2701: . sol - solution function for the test fields
2702: - ctx - solution context or NULL
2704: Note: The calling sequence for solution functions is given by:
2706: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2708: + dim - the spatial dimension
2709: . t - current time
2710: . x - coordinates of the current point
2711: . Nc - the number of field components
2712: . u - the solution field evaluated at the current point
2713: - ctx - a user context
2715: Level: intermediate
2717: .seealso: PetscDSGetExactSolution()
2718: @*/
2719: PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2720: {
2723: PetscDSEnlarge_Static(prob, f+1);
2726: return 0;
2727: }
2729: /*@C
2730: PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2732: Not collective
2734: Input Parameters:
2735: + prob - The PetscDS
2736: - f - The test field number
2738: Output Parameters:
2739: + exactSol - time derivative of the exact solution for the test field
2740: - exactCtx - time derivative of the exact solution context
2742: Note: The calling sequence for the solution functions is given by:
2744: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2746: + dim - the spatial dimension
2747: . t - current time
2748: . x - coordinates of the current point
2749: . Nc - the number of field components
2750: . u - the solution field evaluated at the current point
2751: - ctx - a user context
2753: Level: intermediate
2755: .seealso: PetscDSSetExactSolutionTimeDerivative(), PetscDSGetExactSolution()
2756: @*/
2757: PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2758: {
2763: return 0;
2764: }
2766: /*@C
2767: PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2769: Not collective
2771: Input Parameters:
2772: + prob - The PetscDS
2773: . f - The test field number
2774: . sol - time derivative of the solution function for the test fields
2775: - ctx - time derivative of the solution context or NULL
2777: Note: The calling sequence for solution functions is given by:
2779: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2781: + dim - the spatial dimension
2782: . t - current time
2783: . x - coordinates of the current point
2784: . Nc - the number of field components
2785: . u - the solution field evaluated at the current point
2786: - ctx - a user context
2788: Level: intermediate
2790: .seealso: PetscDSGetExactSolutionTimeDerivative(), PetscDSSetExactSolution()
2791: @*/
2792: PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2793: {
2796: PetscDSEnlarge_Static(prob, f+1);
2799: return 0;
2800: }
2802: /*@C
2803: PetscDSGetConstants - Returns the array of constants passed to point functions
2805: Not collective
2807: Input Parameter:
2808: . prob - The PetscDS object
2810: Output Parameters:
2811: + numConstants - The number of constants
2812: - constants - The array of constants, NULL if there are none
2814: Level: intermediate
2816: .seealso: PetscDSSetConstants(), PetscDSCreate()
2817: @*/
2818: PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2819: {
2823: return 0;
2824: }
2826: /*@C
2827: PetscDSSetConstants - Set the array of constants passed to point functions
2829: Not collective
2831: Input Parameters:
2832: + prob - The PetscDS object
2833: . numConstants - The number of constants
2834: - constants - The array of constants, NULL if there are none
2836: Level: intermediate
2838: .seealso: PetscDSGetConstants(), PetscDSCreate()
2839: @*/
2840: PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2841: {
2843: if (numConstants != prob->numConstants) {
2844: PetscFree(prob->constants);
2845: prob->numConstants = numConstants;
2846: if (prob->numConstants) {
2847: PetscMalloc1(prob->numConstants, &prob->constants);
2848: } else {
2849: prob->constants = NULL;
2850: }
2851: }
2852: if (prob->numConstants) {
2854: PetscArraycpy(prob->constants, constants, prob->numConstants);
2855: }
2856: return 0;
2857: }
2859: /*@
2860: PetscDSGetFieldIndex - Returns the index of the given field
2862: Not collective
2864: Input Parameters:
2865: + prob - The PetscDS object
2866: - disc - The discretization object
2868: Output Parameter:
2869: . f - The field number
2871: Level: beginner
2873: .seealso: PetscGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
2874: @*/
2875: PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2876: {
2877: PetscInt g;
2881: *f = -1;
2882: for (g = 0; g < prob->Nf; ++g) {if (disc == prob->disc[g]) break;}
2884: *f = g;
2885: return 0;
2886: }
2888: /*@
2889: PetscDSGetFieldSize - Returns the size of the given field in the full space basis
2891: Not collective
2893: Input Parameters:
2894: + prob - The PetscDS object
2895: - f - The field number
2897: Output Parameter:
2898: . size - The size
2900: Level: beginner
2902: .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
2903: @*/
2904: PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2905: {
2909: PetscDSSetUp(prob);
2910: *size = prob->Nb[f];
2911: return 0;
2912: }
2914: /*@
2915: PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2917: Not collective
2919: Input Parameters:
2920: + prob - The PetscDS object
2921: - f - The field number
2923: Output Parameter:
2924: . off - The offset
2926: Level: beginner
2928: .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate()
2929: @*/
2930: PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2931: {
2932: PetscInt size, g;
2937: *off = 0;
2938: for (g = 0; g < f; ++g) {
2939: PetscDSGetFieldSize(prob, g, &size);
2940: *off += size;
2941: }
2942: return 0;
2943: }
2945: /*@
2946: PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell
2948: Not collective
2950: Input Parameters:
2951: + prob - The PetscDS object
2952: - f - The field number
2954: Output Parameter:
2955: . off - The offset
2957: Level: beginner
2959: .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate()
2960: @*/
2961: PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2962: {
2963: PetscInt size, g;
2968: *off = 0;
2969: for (g = 0; g < f; ++g) {
2970: PetscBool cohesive;
2972: PetscDSGetCohesive(ds, g, &cohesive);
2973: PetscDSGetFieldSize(ds, g, &size);
2974: *off += cohesive ? size : size*2;
2975: }
2976: return 0;
2977: }
2979: /*@
2980: PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2982: Not collective
2984: Input Parameter:
2985: . prob - The PetscDS object
2987: Output Parameter:
2988: . dimensions - The number of dimensions
2990: Level: beginner
2992: .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
2993: @*/
2994: PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2995: {
2997: PetscDSSetUp(prob);
2999: *dimensions = prob->Nb;
3000: return 0;
3001: }
3003: /*@
3004: PetscDSGetComponents - Returns the number of components for each field on an evaluation point
3006: Not collective
3008: Input Parameter:
3009: . prob - The PetscDS object
3011: Output Parameter:
3012: . components - The number of components
3014: Level: beginner
3016: .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
3017: @*/
3018: PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3019: {
3021: PetscDSSetUp(prob);
3023: *components = prob->Nc;
3024: return 0;
3025: }
3027: /*@
3028: PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
3030: Not collective
3032: Input Parameters:
3033: + prob - The PetscDS object
3034: - f - The field number
3036: Output Parameter:
3037: . off - The offset
3039: Level: beginner
3041: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3042: @*/
3043: PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3044: {
3048: PetscDSSetUp(prob);
3049: *off = prob->off[f];
3050: return 0;
3051: }
3053: /*@
3054: PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
3056: Not collective
3058: Input Parameter:
3059: . prob - The PetscDS object
3061: Output Parameter:
3062: . offsets - The offsets
3064: Level: beginner
3066: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3067: @*/
3068: PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3069: {
3072: PetscDSSetUp(prob);
3073: *offsets = prob->off;
3074: return 0;
3075: }
3077: /*@
3078: PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
3080: Not collective
3082: Input Parameter:
3083: . prob - The PetscDS object
3085: Output Parameter:
3086: . offsets - The offsets
3088: Level: beginner
3090: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3091: @*/
3092: PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3093: {
3096: PetscDSSetUp(prob);
3097: *offsets = prob->offDer;
3098: return 0;
3099: }
3101: /*@
3102: PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point
3104: Not collective
3106: Input Parameters:
3107: + ds - The PetscDS object
3108: - s - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
3110: Output Parameter:
3111: . offsets - The offsets
3113: Level: beginner
3115: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3116: @*/
3117: PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3118: {
3123: PetscDSSetUp(ds);
3124: *offsets = ds->offCohesive[s];
3125: return 0;
3126: }
3128: /*@
3129: PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point
3131: Not collective
3133: Input Parameters:
3134: + ds - The PetscDS object
3135: - s - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive
3137: Output Parameter:
3138: . offsets - The offsets
3140: Level: beginner
3142: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3143: @*/
3144: PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3145: {
3150: PetscDSSetUp(ds);
3151: *offsets = ds->offDerCohesive[s];
3152: return 0;
3153: }
3155: /*@C
3156: PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
3158: Not collective
3160: Input Parameter:
3161: . prob - The PetscDS object
3163: Output Parameter:
3164: . T - The basis function and derivatives tabulation at quadrature points for each field
3166: Level: intermediate
3168: .seealso: PetscDSCreate()
3169: @*/
3170: PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3171: {
3174: PetscDSSetUp(prob);
3175: *T = prob->T;
3176: return 0;
3177: }
3179: /*@C
3180: PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
3182: Not collective
3184: Input Parameter:
3185: . prob - The PetscDS object
3187: Output Parameter:
3188: . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field
3190: Level: intermediate
3192: .seealso: PetscDSGetTabulation(), PetscDSCreate()
3193: @*/
3194: PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3195: {
3198: PetscDSSetUp(prob);
3199: *Tf = prob->Tf;
3200: return 0;
3201: }
3203: PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3204: {
3206: PetscDSSetUp(prob);
3210: return 0;
3211: }
3213: PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3214: {
3216: PetscDSSetUp(prob);
3223: return 0;
3224: }
3226: PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3227: {
3229: PetscDSSetUp(prob);
3235: return 0;
3236: }
3238: /*@C
3239: PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions. 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 should be performed, using the kernels from PetscDSSetBdResidual().
3241: Collective on ds
3243: Input Parameters:
3244: + ds - The PetscDS object
3245: . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3246: . name - The BC name
3247: . label - The label defining constrained points
3248: . Nv - The number of DMLabel values for constrained points
3249: . values - An array of label values for constrained points
3250: . field - The field to constrain
3251: . Nc - The number of constrained field components (0 will constrain all fields)
3252: . comps - An array of constrained component numbers
3253: . bcFunc - A pointwise function giving boundary values
3254: . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3255: - ctx - An optional user context for bcFunc
3257: Output Parameters:
3258: - bd - The boundary number
3260: Options Database Keys:
3261: + -bc_<boundary name> <num> - Overrides the boundary ids
3262: - -bc_<boundary name>_comp <num> - Overrides the boundary components
3264: Note:
3265: Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is:
3267: $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3269: If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is:
3271: $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3272: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3273: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3274: $ PetscReal time, const PetscReal x[], PetscScalar bcval[])
3276: + dim - the spatial dimension
3277: . Nf - the number of fields
3278: . uOff - the offset into u[] and u_t[] for each field
3279: . uOff_x - the offset into u_x[] for each field
3280: . u - each field evaluated at the current point
3281: . u_t - the time derivative of each field evaluated at the current point
3282: . u_x - the gradient of each field evaluated at the current point
3283: . aOff - the offset into a[] and a_t[] for each auxiliary field
3284: . aOff_x - the offset into a_x[] for each auxiliary field
3285: . a - each auxiliary field evaluated at the current point
3286: . a_t - the time derivative of each auxiliary field evaluated at the current point
3287: . a_x - the gradient of auxiliary each field evaluated at the current point
3288: . t - current time
3289: . x - coordinates of the current point
3290: . numConstants - number of constant parameters
3291: . constants - constant parameters
3292: - bcval - output values at the current point
3294: Level: developer
3296: .seealso: PetscDSAddBoundaryByName(), PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual()
3297: @*/
3298: 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)
3299: {
3300: DSBoundary head = ds->boundary, b;
3301: PetscInt n = 0;
3302: const char *lname;
3311: if (Nc > 0) {
3312: PetscInt *fcomps;
3313: PetscInt c;
3315: PetscDSGetComponents(ds, &fcomps);
3317: for (c = 0; c < Nc; ++c) {
3319: }
3320: }
3321: PetscNew(&b);
3322: PetscStrallocpy(name, (char **) &b->name);
3323: PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf);
3324: PetscWeakFormSetNumFields(b->wf, ds->Nf);
3325: PetscMalloc1(Nv, &b->values);
3326: if (Nv) PetscArraycpy(b->values, values, Nv);
3327: PetscMalloc1(Nc, &b->comps);
3328: if (Nc) PetscArraycpy(b->comps, comps, Nc);
3329: PetscObjectGetName((PetscObject) label, &lname);
3330: PetscStrallocpy(lname, (char **) &b->lname);
3331: b->type = type;
3332: b->label = label;
3333: b->Nv = Nv;
3334: b->field = field;
3335: b->Nc = Nc;
3336: b->func = bcFunc;
3337: b->func_t = bcFunc_t;
3338: b->ctx = ctx;
3339: b->next = NULL;
3340: /* Append to linked list so that we can preserve the order */
3341: if (!head) ds->boundary = b;
3342: while (head) {
3343: if (!head->next) {
3344: head->next = b;
3345: head = b;
3346: }
3347: head = head->next;
3348: ++n;
3349: }
3351: return 0;
3352: }
3354: /*@C
3355: PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions. 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 should be performed, using the kernels from PetscDSSetBdResidual().
3357: Collective on ds
3359: Input Parameters:
3360: + ds - The PetscDS object
3361: . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3362: . name - The BC name
3363: . lname - The naem of the label defining constrained points
3364: . Nv - The number of DMLabel values for constrained points
3365: . values - An array of label values for constrained points
3366: . field - The field to constrain
3367: . Nc - The number of constrained field components (0 will constrain all fields)
3368: . comps - An array of constrained component numbers
3369: . bcFunc - A pointwise function giving boundary values
3370: . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3371: - ctx - An optional user context for bcFunc
3373: Output Parameters:
3374: - bd - The boundary number
3376: Options Database Keys:
3377: + -bc_<boundary name> <num> - Overrides the boundary ids
3378: - -bc_<boundary name>_comp <num> - Overrides the boundary components
3380: Note:
3381: This function should only be used with DMForest currently, since labels cannot be defined before the underlygin Plex is built.
3383: Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is:
3385: $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3387: If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is:
3389: $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3390: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3391: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3392: $ PetscReal time, const PetscReal x[], PetscScalar bcval[])
3394: + dim - the spatial dimension
3395: . Nf - the number of fields
3396: . uOff - the offset into u[] and u_t[] for each field
3397: . uOff_x - the offset into u_x[] for each field
3398: . u - each field evaluated at the current point
3399: . u_t - the time derivative of each field evaluated at the current point
3400: . u_x - the gradient of each field evaluated at the current point
3401: . aOff - the offset into a[] and a_t[] for each auxiliary field
3402: . aOff_x - the offset into a_x[] for each auxiliary field
3403: . a - each auxiliary field evaluated at the current point
3404: . a_t - the time derivative of each auxiliary field evaluated at the current point
3405: . a_x - the gradient of auxiliary each field evaluated at the current point
3406: . t - current time
3407: . x - coordinates of the current point
3408: . numConstants - number of constant parameters
3409: . constants - constant parameters
3410: - bcval - output values at the current point
3412: Level: developer
3414: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual()
3415: @*/
3416: 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)
3417: {
3418: DSBoundary head = ds->boundary, b;
3419: PetscInt n = 0;
3428: PetscNew(&b);
3429: PetscStrallocpy(name, (char **) &b->name);
3430: PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf);
3431: PetscWeakFormSetNumFields(b->wf, ds->Nf);
3432: PetscMalloc1(Nv, &b->values);
3433: if (Nv) PetscArraycpy(b->values, values, Nv);
3434: PetscMalloc1(Nc, &b->comps);
3435: if (Nc) PetscArraycpy(b->comps, comps, Nc);
3436: PetscStrallocpy(lname, (char **) &b->lname);
3437: b->type = type;
3438: b->label = NULL;
3439: b->Nv = Nv;
3440: b->field = field;
3441: b->Nc = Nc;
3442: b->func = bcFunc;
3443: b->func_t = bcFunc_t;
3444: b->ctx = ctx;
3445: b->next = NULL;
3446: /* Append to linked list so that we can preserve the order */
3447: if (!head) ds->boundary = b;
3448: while (head) {
3449: if (!head->next) {
3450: head->next = b;
3451: head = b;
3452: }
3453: head = head->next;
3454: ++n;
3455: }
3457: return 0;
3458: }
3460: /*@C
3461: PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions. 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 should be performed, using the kernels from PetscDSSetBdResidual().
3463: Input Parameters:
3464: + ds - The PetscDS object
3465: . bd - The boundary condition number
3466: . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3467: . name - The BC name
3468: . label - The label defining constrained points
3469: . Nv - The number of DMLabel ids for constrained points
3470: . values - An array of ids for constrained points
3471: . field - The field to constrain
3472: . Nc - The number of constrained field components
3473: . comps - An array of constrained component numbers
3474: . bcFunc - A pointwise function giving boundary values
3475: . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3476: - ctx - An optional user context for bcFunc
3478: Note:
3479: The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from PetscDSGetNumBoundary(). See PetscDSAddBoundary() for a description of the calling sequences for the callbacks.
3481: Level: developer
3483: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSGetNumBoundary()
3484: @*/
3485: 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)
3486: {
3487: DSBoundary b = ds->boundary;
3488: PetscInt n = 0;
3491: while (b) {
3492: if (n == bd) break;
3493: b = b->next;
3494: ++n;
3495: }
3497: if (name) {
3498: PetscFree(b->name);
3499: PetscStrallocpy(name, (char **) &b->name);
3500: }
3501: b->type = type;
3502: if (label) {
3503: const char *name;
3505: b->label = label;
3506: PetscFree(b->lname);
3507: PetscObjectGetName((PetscObject) label, &name);
3508: PetscStrallocpy(name, (char **) &b->lname);
3509: }
3510: if (Nv >= 0) {
3511: b->Nv = Nv;
3512: PetscFree(b->values);
3513: PetscMalloc1(Nv, &b->values);
3514: if (Nv) PetscArraycpy(b->values, values, Nv);
3515: }
3516: if (field >= 0) b->field = field;
3517: if (Nc >= 0) {
3518: b->Nc = Nc;
3519: PetscFree(b->comps);
3520: PetscMalloc1(Nc, &b->comps);
3521: if (Nc) PetscArraycpy(b->comps, comps, Nc);
3522: }
3523: if (bcFunc) b->func = bcFunc;
3524: if (bcFunc_t) b->func_t = bcFunc_t;
3525: if (ctx) b->ctx = ctx;
3526: return 0;
3527: }
3529: /*@
3530: PetscDSGetNumBoundary - Get the number of registered BC
3532: Input Parameters:
3533: . ds - The PetscDS object
3535: Output Parameters:
3536: . numBd - The number of BC
3538: Level: intermediate
3540: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary()
3541: @*/
3542: PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3543: {
3544: DSBoundary b = ds->boundary;
3548: *numBd = 0;
3549: while (b) {++(*numBd); b = b->next;}
3550: return 0;
3551: }
3553: /*@C
3554: PetscDSGetBoundary - Gets a boundary condition to the model
3556: Input Parameters:
3557: + ds - The PetscDS object
3558: - bd - The BC number
3560: Output Parameters:
3561: + wf - The PetscWeakForm holding the pointwise functions
3562: . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3563: . name - The BC name
3564: . label - The label defining constrained points
3565: . Nv - The number of DMLabel ids for constrained points
3566: . values - An array of ids for constrained points
3567: . field - The field to constrain
3568: . Nc - The number of constrained field components
3569: . comps - An array of constrained component numbers
3570: . bcFunc - A pointwise function giving boundary values
3571: . bcFunc_t - A pointwise function giving the time derivative of the boundary values
3572: - ctx - An optional user context for bcFunc
3574: Options Database Keys:
3575: + -bc_<boundary name> <num> - Overrides the boundary ids
3576: - -bc_<boundary name>_comp <num> - Overrides the boundary components
3578: Level: developer
3580: .seealso: PetscDSAddBoundary()
3581: @*/
3582: 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)
3583: {
3584: DSBoundary b = ds->boundary;
3585: PetscInt n = 0;
3588: while (b) {
3589: if (n == bd) break;
3590: b = b->next;
3591: ++n;
3592: }
3594: if (wf) {
3596: *wf = b->wf;
3597: }
3598: if (type) {
3600: *type = b->type;
3601: }
3602: if (name) {
3604: *name = b->name;
3605: }
3606: if (label) {
3608: *label = b->label;
3609: }
3610: if (Nv) {
3612: *Nv = b->Nv;
3613: }
3614: if (values) {
3616: *values = b->values;
3617: }
3618: if (field) {
3620: *field = b->field;
3621: }
3622: if (Nc) {
3624: *Nc = b->Nc;
3625: }
3626: if (comps) {
3628: *comps = b->comps;
3629: }
3630: if (func) {
3632: *func = b->func;
3633: }
3634: if (func_t) {
3636: *func_t = b->func_t;
3637: }
3638: if (ctx) {
3640: *ctx = b->ctx;
3641: }
3642: return 0;
3643: }
3645: static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3646: {
3647: PetscNew(bNew);
3648: PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf);
3649: PetscWeakFormCopy(b->wf, (*bNew)->wf);
3650: PetscStrallocpy(b->name,(char **) &((*bNew)->name));
3651: PetscStrallocpy(b->lname,(char **) &((*bNew)->lname));
3652: (*bNew)->type = b->type;
3653: (*bNew)->label = b->label;
3654: (*bNew)->Nv = b->Nv;
3655: PetscMalloc1(b->Nv, &(*bNew)->values);
3656: PetscArraycpy((*bNew)->values, b->values, b->Nv);
3657: (*bNew)->field = b->field;
3658: (*bNew)->Nc = b->Nc;
3659: PetscMalloc1(b->Nc, &(*bNew)->comps);
3660: PetscArraycpy((*bNew)->comps, b->comps, b->Nc);
3661: (*bNew)->func = b->func;
3662: (*bNew)->func_t = b->func_t;
3663: (*bNew)->ctx = b->ctx;
3664: return 0;
3665: }
3667: /*@
3668: PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
3670: Not collective
3672: Input Parameters:
3673: + ds - The source PetscDS object
3674: . numFields - The number of selected fields, or PETSC_DEFAULT for all fields
3675: - fields - The selected fields, or NULL for all fields
3677: Output Parameter:
3678: . newds - The target PetscDS, now with a copy of the boundary conditions
3680: Level: intermediate
3682: .seealso: PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3683: @*/
3684: PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3685: {
3686: DSBoundary b, *lastnext;
3690: if (ds == newds) return 0;
3691: PetscDSDestroyBoundary(newds);
3692: lastnext = &(newds->boundary);
3693: for (b = ds->boundary; b; b = b->next) {
3694: DSBoundary bNew;
3695: PetscInt fieldNew = -1;
3697: if (numFields > 0 && fields) {
3698: PetscInt f;
3700: for (f = 0; f < numFields; ++f) if (b->field == fields[f]) break;
3701: if (f == numFields) continue;
3702: fieldNew = f;
3703: }
3704: DSBoundaryDuplicate_Internal(b, &bNew);
3705: bNew->field = fieldNew < 0 ? b->field : fieldNew;
3706: *lastnext = bNew;
3707: lastnext = &(bNew->next);
3708: }
3709: return 0;
3710: }
3712: /*@
3713: PetscDSDestroyBoundary - Remove all DMBoundary objects from the PetscDS
3715: Not collective
3717: Input Parameter:
3718: . ds - The PetscDS object
3720: Level: intermediate
3722: .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations()
3723: @*/
3724: PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3725: {
3726: DSBoundary next = ds->boundary;
3728: while (next) {
3729: DSBoundary b = next;
3731: next = b->next;
3732: PetscWeakFormDestroy(&b->wf);
3733: PetscFree(b->name);
3734: PetscFree(b->lname);
3735: PetscFree(b->values);
3736: PetscFree(b->comps);
3737: PetscFree(b);
3738: }
3739: return 0;
3740: }
3742: /*@
3743: PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
3745: Not collective
3747: Input Parameters:
3748: + prob - The PetscDS object
3749: . numFields - Number of new fields
3750: - fields - Old field number for each new field
3752: Output Parameter:
3753: . newprob - The PetscDS copy
3755: Level: intermediate
3757: .seealso: PetscDSSelectEquations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3758: @*/
3759: PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3760: {
3761: PetscInt Nf, Nfn, fn;
3766: PetscDSGetNumFields(prob, &Nf);
3767: PetscDSGetNumFields(newprob, &Nfn);
3768: numFields = numFields < 0 ? Nf : numFields;
3769: for (fn = 0; fn < numFields; ++fn) {
3770: const PetscInt f = fields ? fields[fn] : fn;
3771: PetscObject disc;
3773: if (f >= Nf) continue;
3774: PetscDSGetDiscretization(prob, f, &disc);
3775: PetscDSSetDiscretization(newprob, fn, disc);
3776: }
3777: return 0;
3778: }
3780: /*@
3781: PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
3783: Not collective
3785: Input Parameters:
3786: + prob - The PetscDS object
3787: . numFields - Number of new fields
3788: - fields - Old field number for each new field
3790: Output Parameter:
3791: . newprob - The PetscDS copy
3793: Level: intermediate
3795: .seealso: PetscDSSelectDiscretizations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3796: @*/
3797: PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3798: {
3799: PetscInt Nf, Nfn, fn, gn;
3804: PetscDSGetNumFields(prob, &Nf);
3805: PetscDSGetNumFields(newprob, &Nfn);
3807: for (fn = 0; fn < numFields; ++fn) {
3808: const PetscInt f = fields ? fields[fn] : fn;
3809: PetscPointFunc obj;
3810: PetscPointFunc f0, f1;
3811: PetscBdPointFunc f0Bd, f1Bd;
3812: PetscRiemannFunc r;
3814: if (f >= Nf) continue;
3815: PetscDSGetObjective(prob, f, &obj);
3816: PetscDSGetResidual(prob, f, &f0, &f1);
3817: PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd);
3818: PetscDSGetRiemannSolver(prob, f, &r);
3819: PetscDSSetObjective(newprob, fn, obj);
3820: PetscDSSetResidual(newprob, fn, f0, f1);
3821: PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd);
3822: PetscDSSetRiemannSolver(newprob, fn, r);
3823: for (gn = 0; gn < numFields; ++gn) {
3824: const PetscInt g = fields ? fields[gn] : gn;
3825: PetscPointJac g0, g1, g2, g3;
3826: PetscPointJac g0p, g1p, g2p, g3p;
3827: PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
3829: if (g >= Nf) continue;
3830: PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3);
3831: PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p);
3832: PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd);
3833: PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3);
3834: PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p);
3835: PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd);
3836: }
3837: }
3838: return 0;
3839: }
3841: /*@
3842: PetscDSCopyEquations - Copy all pointwise function pointers to the new problem
3844: Not collective
3846: Input Parameter:
3847: . prob - The PetscDS object
3849: Output Parameter:
3850: . newprob - The PetscDS copy
3852: Level: intermediate
3854: .seealso: PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3855: @*/
3856: PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3857: {
3858: PetscWeakForm wf, newwf;
3859: PetscInt Nf, Ng;
3863: PetscDSGetNumFields(prob, &Nf);
3864: PetscDSGetNumFields(newprob, &Ng);
3866: PetscDSGetWeakForm(prob, &wf);
3867: PetscDSGetWeakForm(newprob, &newwf);
3868: PetscWeakFormCopy(wf, newwf);
3869: return 0;
3870: }
3872: /*@
3873: PetscDSCopyConstants - Copy all constants to the new problem
3875: Not collective
3877: Input Parameter:
3878: . prob - The PetscDS object
3880: Output Parameter:
3881: . newprob - The PetscDS copy
3883: Level: intermediate
3885: .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3886: @*/
3887: PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3888: {
3889: PetscInt Nc;
3890: const PetscScalar *constants;
3894: PetscDSGetConstants(prob, &Nc, &constants);
3895: PetscDSSetConstants(newprob, Nc, (PetscScalar *) constants);
3896: return 0;
3897: }
3899: /*@
3900: PetscDSCopyExactSolutions - Copy all exact solutions to the new problem
3902: Not collective
3904: Input Parameter:
3905: . ds - The PetscDS object
3907: Output Parameter:
3908: . newds - The PetscDS copy
3910: Level: intermediate
3912: .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3913: @*/
3914: PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
3915: {
3916: PetscSimplePointFunc sol;
3917: void *ctx;
3918: PetscInt Nf, f;
3922: PetscDSGetNumFields(ds, &Nf);
3923: for (f = 0; f < Nf; ++f) {
3924: PetscDSGetExactSolution(ds, f, &sol, &ctx);
3925: PetscDSSetExactSolution(newds, f, sol, ctx);
3926: PetscDSGetExactSolutionTimeDerivative(ds, f, &sol, &ctx);
3927: PetscDSSetExactSolutionTimeDerivative(newds, f, sol, ctx);
3928: }
3929: return 0;
3930: }
3932: PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
3933: {
3934: PetscInt dim, Nf, f;
3938: if (height == 0) {*subprob = prob; return 0;}
3939: PetscDSGetNumFields(prob, &Nf);
3940: PetscDSGetSpatialDimension(prob, &dim);
3942: if (!prob->subprobs) PetscCalloc1(dim, &prob->subprobs);
3943: if (!prob->subprobs[height-1]) {
3944: PetscInt cdim;
3946: PetscDSCreate(PetscObjectComm((PetscObject) prob), &prob->subprobs[height-1]);
3947: PetscDSGetCoordinateDimension(prob, &cdim);
3948: PetscDSSetCoordinateDimension(prob->subprobs[height-1], cdim);
3949: for (f = 0; f < Nf; ++f) {
3950: PetscFE subfe;
3951: PetscObject obj;
3952: PetscClassId id;
3954: PetscDSGetDiscretization(prob, f, &obj);
3955: PetscObjectGetClassId(obj, &id);
3956: if (id == PETSCFE_CLASSID) PetscFEGetHeightSubspace((PetscFE) obj, height, &subfe);
3957: else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %d", f);
3958: PetscDSSetDiscretization(prob->subprobs[height-1], f, (PetscObject) subfe);
3959: }
3960: }
3961: *subprob = prob->subprobs[height-1];
3962: return 0;
3963: }
3965: PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
3966: {
3967: PetscObject obj;
3968: PetscClassId id;
3969: PetscInt Nf;
3973: *disctype = PETSC_DISC_NONE;
3974: PetscDSGetNumFields(ds, &Nf);
3976: PetscDSGetDiscretization(ds, f, &obj);
3977: if (obj) {
3978: PetscObjectGetClassId(obj, &id);
3979: if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
3980: else *disctype = PETSC_DISC_FV;
3981: }
3982: return 0;
3983: }
3985: static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
3986: {
3987: PetscFree(ds->data);
3988: return 0;
3989: }
3991: static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
3992: {
3993: ds->ops->setfromoptions = NULL;
3994: ds->ops->setup = NULL;
3995: ds->ops->view = NULL;
3996: ds->ops->destroy = PetscDSDestroy_Basic;
3997: return 0;
3998: }
4000: /*MC
4001: PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
4003: Level: intermediate
4005: .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType()
4006: M*/
4008: PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4009: {
4010: PetscDS_Basic *b;
4013: PetscNewLog(ds, &b);
4014: ds->data = b;
4016: PetscDSInitialize_Basic(ds);
4017: return 0;
4018: }