Actual source code: dtds.c
petsc-3.9.4 2018-09-11
1: #include <petsc/private/petscdsimpl.h>
3: PetscClassId PETSCDS_CLASSID = 0;
5: PetscFunctionList PetscDSList = NULL;
6: PetscBool PetscDSRegisterAllCalled = PETSC_FALSE;
8: /*@C
9: PetscDSRegister - Adds a new PetscDS implementation
11: Not Collective
13: Input Parameters:
14: + name - The name of a new user-defined creation routine
15: - create_func - The creation routine itself
17: Notes:
18: PetscDSRegister() may be called multiple times to add several user-defined PetscDSs
20: Sample usage:
21: .vb
22: PetscDSRegister("my_ds", MyPetscDSCreate);
23: .ve
25: Then, your PetscDS type can be chosen with the procedural interface via
26: .vb
27: PetscDSCreate(MPI_Comm, PetscDS *);
28: PetscDSSetType(PetscDS, "my_ds");
29: .ve
30: or at runtime via the option
31: .vb
32: -petscds_type my_ds
33: .ve
35: Level: advanced
37: Not available from Fortran
39: .keywords: PetscDS, register
40: .seealso: PetscDSRegisterAll(), PetscDSRegisterDestroy()
42: @*/
43: PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
44: {
48: PetscFunctionListAdd(&PetscDSList, sname, function);
49: return(0);
50: }
52: /*@C
53: PetscDSSetType - Builds a particular PetscDS
55: Collective on PetscDS
57: Input Parameters:
58: + prob - The PetscDS object
59: - name - The kind of system
61: Options Database Key:
62: . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
64: Level: intermediate
66: Not available from Fortran
68: .keywords: PetscDS, set, type
69: .seealso: PetscDSGetType(), PetscDSCreate()
70: @*/
71: PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
72: {
73: PetscErrorCode (*r)(PetscDS);
74: PetscBool match;
79: PetscObjectTypeCompare((PetscObject) prob, name, &match);
80: if (match) return(0);
82: PetscDSRegisterAll();
83: PetscFunctionListFind(PetscDSList, name, &r);
84: if (!r) SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
86: if (prob->ops->destroy) {
87: (*prob->ops->destroy)(prob);
88: prob->ops->destroy = NULL;
89: }
90: (*r)(prob);
91: PetscObjectChangeTypeName((PetscObject) prob, name);
92: return(0);
93: }
95: /*@C
96: PetscDSGetType - Gets the PetscDS type name (as a string) from the object.
98: Not Collective
100: Input Parameter:
101: . prob - The PetscDS
103: Output Parameter:
104: . name - The PetscDS type name
106: Level: intermediate
108: Not available from Fortran
110: .keywords: PetscDS, get, type, name
111: .seealso: PetscDSSetType(), PetscDSCreate()
112: @*/
113: PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
114: {
120: PetscDSRegisterAll();
121: *name = ((PetscObject) prob)->type_name;
122: return(0);
123: }
125: static PetscErrorCode PetscDSView_Ascii(PetscDS prob, PetscViewer viewer)
126: {
127: PetscViewerFormat format;
128: const PetscScalar *constants;
129: PetscInt numConstants, f;
130: PetscErrorCode ierr;
133: PetscViewerGetFormat(viewer, &format);
134: PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", prob->Nf);
135: PetscViewerASCIIPushTab(viewer);
136: for (f = 0; f < prob->Nf; ++f) {
137: PetscObject obj;
138: PetscClassId id;
139: const char *name;
140: PetscInt Nc;
142: PetscDSGetDiscretization(prob, f, &obj);
143: PetscObjectGetClassId(obj, &id);
144: PetscObjectGetName(obj, &name);
145: PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");
146: if (id == PETSCFE_CLASSID) {
147: PetscFEGetNumComponents((PetscFE) obj, &Nc);
148: PetscViewerASCIIPrintf(viewer, " FEM");
149: } else if (id == PETSCFV_CLASSID) {
150: PetscFVGetNumComponents((PetscFV) obj, &Nc);
151: PetscViewerASCIIPrintf(viewer, " FVM");
152: }
153: else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %D", f);
154: if (Nc > 1) {PetscViewerASCIIPrintf(viewer, "%D components", Nc);}
155: else {PetscViewerASCIIPrintf(viewer, "%D component ", Nc);}
156: if (prob->implicit[f]) {PetscViewerASCIIPrintf(viewer, " (implicit)");}
157: else {PetscViewerASCIIPrintf(viewer, " (explicit)");}
158: if (prob->adjacency[f*2+0]) {
159: if (prob->adjacency[f*2+1]) {PetscViewerASCIIPrintf(viewer, " (adj FVM++)");}
160: else {PetscViewerASCIIPrintf(viewer, " (adj FVM)");}
161: } else {
162: if (prob->adjacency[f*2+1]) {PetscViewerASCIIPrintf(viewer, " (adj FEM)");}
163: else {PetscViewerASCIIPrintf(viewer, " (adj FUNKY)");}
164: }
165: PetscViewerASCIIPrintf(viewer, "\n");
166: PetscViewerASCIIPushTab(viewer);
167: if (id == PETSCFE_CLASSID) {PetscFEView((PetscFE) obj, viewer);}
168: else if (id == PETSCFV_CLASSID) {PetscFVView((PetscFV) obj, viewer);}
169: PetscViewerASCIIPopTab(viewer);
170: }
171: PetscDSGetConstants(prob, &numConstants, &constants);
172: if (numConstants) {
173: PetscViewerASCIIPrintf(viewer, "%D constants\n", numConstants);
174: PetscViewerASCIIPushTab(viewer);
175: for (f = 0; f < numConstants; ++f) {PetscViewerASCIIPrintf(viewer, "%g\n", (double) PetscRealPart(constants[f]));}
176: PetscViewerASCIIPopTab(viewer);
177: }
178: PetscViewerASCIIPopTab(viewer);
179: return(0);
180: }
182: /*@C
183: PetscDSView - Views a PetscDS
185: Collective on PetscDS
187: Input Parameter:
188: + prob - the PetscDS object to view
189: - v - the viewer
191: Level: developer
193: .seealso PetscDSDestroy()
194: @*/
195: PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
196: {
197: PetscBool iascii;
202: if (!v) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);}
204: PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
205: if (iascii) {PetscDSView_Ascii(prob, v);}
206: if (prob->ops->view) {(*prob->ops->view)(prob, v);}
207: return(0);
208: }
210: /*@
211: PetscDSSetFromOptions - sets parameters in a PetscDS from the options database
213: Collective on PetscDS
215: Input Parameter:
216: . prob - the PetscDS object to set options for
218: Options Database:
220: Level: developer
222: .seealso PetscDSView()
223: @*/
224: PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
225: {
226: DSBoundary b;
227: const char *defaultType;
228: char name[256];
229: PetscBool flg;
234: if (!((PetscObject) prob)->type_name) {
235: defaultType = PETSCDSBASIC;
236: } else {
237: defaultType = ((PetscObject) prob)->type_name;
238: }
239: PetscDSRegisterAll();
241: PetscObjectOptionsBegin((PetscObject) prob);
242: for (b = prob->boundary; b; b = b->next) {
243: char optname[1024];
244: PetscInt ids[1024], len = 1024;
245: PetscBool flg;
247: PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name);
248: PetscMemzero(ids, sizeof(ids));
249: PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg);
250: if (flg) {
251: b->numids = len;
252: PetscFree(b->ids);
253: PetscMalloc1(len, &b->ids);
254: PetscMemcpy(b->ids, ids, len*sizeof(PetscInt));
255: }
256: len = 1024;
257: PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name);
258: PetscMemzero(ids, sizeof(ids));
259: PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg);
260: if (flg) {
261: b->numcomps = len;
262: PetscFree(b->comps);
263: PetscMalloc1(len, &b->comps);
264: PetscMemcpy(b->comps, ids, len*sizeof(PetscInt));
265: }
266: }
267: PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);
268: if (flg) {
269: PetscDSSetType(prob, name);
270: } else if (!((PetscObject) prob)->type_name) {
271: PetscDSSetType(prob, defaultType);
272: }
273: if (prob->ops->setfromoptions) {(*prob->ops->setfromoptions)(prob);}
274: /* process any options handlers added with PetscObjectAddOptionsHandler() */
275: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) prob);
276: PetscOptionsEnd();
277: if (prob->Nf) {PetscDSViewFromOptions(prob, NULL, "-petscds_view");}
278: return(0);
279: }
281: /*@C
282: PetscDSSetUp - Construct data structures for the PetscDS
284: Collective on PetscDS
286: Input Parameter:
287: . prob - the PetscDS object to setup
289: Level: developer
291: .seealso PetscDSView(), PetscDSDestroy()
292: @*/
293: PetscErrorCode PetscDSSetUp(PetscDS prob)
294: {
295: const PetscInt Nf = prob->Nf;
296: PetscInt dim, dimEmbed, work, NcMax = 0, NqMax = 0, f;
301: if (prob->setup) return(0);
302: /* Calculate sizes */
303: PetscDSGetSpatialDimension(prob, &dim);
304: PetscDSGetCoordinateDimension(prob, &dimEmbed);
305: prob->totDim = prob->totComp = 0;
306: PetscMalloc2(Nf,&prob->Nc,Nf,&prob->Nb);
307: PetscCalloc2(Nf+1,&prob->off,Nf+1,&prob->offDer);
308: PetscMalloc4(Nf,&prob->basis,Nf,&prob->basisDer,Nf,&prob->basisFace,Nf,&prob->basisDerFace);
309: for (f = 0; f < Nf; ++f) {
310: PetscObject obj;
311: PetscClassId id;
312: PetscQuadrature q;
313: PetscInt Nq = 0, Nb, Nc;
315: PetscDSGetDiscretization(prob, f, &obj);
316: PetscObjectGetClassId(obj, &id);
317: if (id == PETSCFE_CLASSID) {
318: PetscFE fe = (PetscFE) obj;
320: PetscFEGetQuadrature(fe, &q);
321: PetscFEGetDimension(fe, &Nb);
322: PetscFEGetNumComponents(fe, &Nc);
323: PetscFEGetDefaultTabulation(fe, &prob->basis[f], &prob->basisDer[f], NULL);
324: PetscFEGetFaceTabulation(fe, &prob->basisFace[f], &prob->basisDerFace[f], NULL);
325: } else if (id == PETSCFV_CLASSID) {
326: PetscFV fv = (PetscFV) obj;
328: PetscFVGetQuadrature(fv, &q);
329: PetscFVGetNumComponents(fv, &Nc);
330: Nb = Nc;
331: PetscFVGetDefaultTabulation(fv, &prob->basis[f], &prob->basisDer[f], NULL);
332: /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
333: } else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
334: prob->Nc[f] = Nc;
335: prob->Nb[f] = Nb;
336: prob->off[f+1] = Nc + prob->off[f];
337: prob->offDer[f+1] = Nc*dim + prob->offDer[f];
338: if (q) {PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL);}
339: NqMax = PetscMax(NqMax, Nq);
340: NcMax = PetscMax(NcMax, Nc);
341: prob->totDim += Nb;
342: prob->totComp += Nc;
343: }
344: work = PetscMax(prob->totComp*dim, PetscSqr(NcMax*dim));
345: /* Allocate works space */
346: PetscMalloc5(prob->totComp,&prob->u,prob->totComp,&prob->u_t,prob->totComp*dim,&prob->u_x,dimEmbed,&prob->x,work,&prob->refSpaceDer);
347: PetscMalloc6(NqMax*NcMax,&prob->f0,NqMax*NcMax*dim,&prob->f1,NqMax*NcMax*NcMax,&prob->g0,NqMax*NcMax*NcMax*dim,&prob->g1,NqMax*NcMax*NcMax*dim,&prob->g2,NqMax*NcMax*NcMax*dim*dim,&prob->g3);
348: if (prob->ops->setup) {(*prob->ops->setup)(prob);}
349: prob->setup = PETSC_TRUE;
350: return(0);
351: }
353: static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
354: {
358: PetscFree2(prob->Nc,prob->Nb);
359: PetscFree2(prob->off,prob->offDer);
360: PetscFree4(prob->basis,prob->basisDer,prob->basisFace,prob->basisDerFace);
361: PetscFree5(prob->u,prob->u_t,prob->u_x,prob->x,prob->refSpaceDer);
362: PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);
363: return(0);
364: }
366: static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
367: {
368: PetscObject *tmpd;
369: PetscBool *tmpi, *tmpa;
370: PetscPointFunc *tmpobj, *tmpf, *tmpup;
371: PetscPointJac *tmpg, *tmpgp, *tmpgt;
372: PetscBdPointFunc *tmpfbd;
373: PetscBdPointJac *tmpgbd;
374: PetscRiemannFunc *tmpr;
375: PetscSimplePointFunc *tmpexactSol;
376: void **tmpctx;
377: PetscInt Nf = prob->Nf, f, i;
378: PetscErrorCode ierr;
381: if (Nf >= NfNew) return(0);
382: prob->setup = PETSC_FALSE;
383: PetscDSDestroyStructs_Static(prob);
384: PetscMalloc3(NfNew, &tmpd, NfNew, &tmpi, NfNew*2, &tmpa);
385: for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpi[f] = prob->implicit[f]; for (i = 0; i < 2; ++i) tmpa[f*2+i] = prob->adjacency[f*2+i];}
386: for (f = Nf; f < NfNew; ++f) {tmpd[f] = NULL; tmpi[f] = PETSC_TRUE; tmpa[f*2+0] = PETSC_FALSE; tmpa[f*2+1] = PETSC_TRUE;}
387: PetscFree3(prob->disc, prob->implicit, prob->adjacency);
388: prob->Nf = NfNew;
389: prob->disc = tmpd;
390: prob->implicit = tmpi;
391: prob->adjacency = tmpa;
392: PetscCalloc7(NfNew, &tmpobj, NfNew*2, &tmpf, NfNew*NfNew*4, &tmpg, NfNew*NfNew*4, &tmpgp, NfNew*NfNew*4, &tmpgt, NfNew, &tmpr, NfNew, &tmpctx);
393: PetscCalloc1(NfNew, &tmpup);
394: for (f = 0; f < Nf; ++f) tmpobj[f] = prob->obj[f];
395: for (f = 0; f < Nf*2; ++f) tmpf[f] = prob->f[f];
396: for (f = 0; f < Nf*Nf*4; ++f) tmpg[f] = prob->g[f];
397: for (f = 0; f < Nf*Nf*4; ++f) tmpgp[f] = prob->gp[f];
398: for (f = 0; f < Nf; ++f) tmpr[f] = prob->r[f];
399: for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
400: for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
401: for (f = Nf; f < NfNew; ++f) tmpobj[f] = NULL;
402: for (f = Nf*2; f < NfNew*2; ++f) tmpf[f] = NULL;
403: for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpg[f] = NULL;
404: for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgp[f] = NULL;
405: for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgt[f] = NULL;
406: for (f = Nf; f < NfNew; ++f) tmpr[f] = NULL;
407: for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
408: for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
409: PetscFree7(prob->obj, prob->f, prob->g, prob->gp, prob->gt, prob->r, prob->ctx);
410: PetscFree(prob->update);
411: prob->obj = tmpobj;
412: prob->f = tmpf;
413: prob->g = tmpg;
414: prob->gp = tmpgp;
415: prob->gt = tmpgt;
416: prob->r = tmpr;
417: prob->update = tmpup;
418: prob->ctx = tmpctx;
419: PetscCalloc3(NfNew*2, &tmpfbd, NfNew*NfNew*4, &tmpgbd, NfNew, &tmpexactSol);
420: for (f = 0; f < Nf*2; ++f) tmpfbd[f] = prob->fBd[f];
421: for (f = 0; f < Nf*Nf*4; ++f) tmpgbd[f] = prob->gBd[f];
422: for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
423: for (f = Nf*2; f < NfNew*2; ++f) tmpfbd[f] = NULL;
424: for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgbd[f] = NULL;
425: for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
426: PetscFree3(prob->fBd, prob->gBd, prob->exactSol);
427: prob->fBd = tmpfbd;
428: prob->gBd = tmpgbd;
429: prob->exactSol = tmpexactSol;
430: return(0);
431: }
433: /*@
434: PetscDSDestroy - Destroys a PetscDS object
436: Collective on PetscDS
438: Input Parameter:
439: . prob - the PetscDS object to destroy
441: Level: developer
443: .seealso PetscDSView()
444: @*/
445: PetscErrorCode PetscDSDestroy(PetscDS *prob)
446: {
447: PetscInt f;
448: DSBoundary next;
452: if (!*prob) return(0);
455: if (--((PetscObject)(*prob))->refct > 0) {*prob = 0; return(0);}
456: ((PetscObject) (*prob))->refct = 0;
457: if ((*prob)->subprobs) {
458: PetscInt dim, d;
460: PetscDSGetSpatialDimension(*prob, &dim);
461: for (d = 0; d < dim; ++d) {PetscDSDestroy(&(*prob)->subprobs[d]);}
462: }
463: PetscFree((*prob)->subprobs);
464: PetscDSDestroyStructs_Static(*prob);
465: for (f = 0; f < (*prob)->Nf; ++f) {
466: PetscObjectDereference((*prob)->disc[f]);
467: }
468: PetscFree3((*prob)->disc, (*prob)->implicit, (*prob)->adjacency);
469: PetscFree7((*prob)->obj,(*prob)->f,(*prob)->g,(*prob)->gp,(*prob)->gt,(*prob)->r,(*prob)->ctx);
470: PetscFree((*prob)->update);
471: PetscFree3((*prob)->fBd,(*prob)->gBd,(*prob)->exactSol);
472: if ((*prob)->ops->destroy) {(*(*prob)->ops->destroy)(*prob);}
473: next = (*prob)->boundary;
474: while (next) {
475: DSBoundary b = next;
477: next = b->next;
478: PetscFree(b->comps);
479: PetscFree(b->ids);
480: PetscFree(b->name);
481: PetscFree(b->labelname);
482: PetscFree(b);
483: }
484: PetscFree((*prob)->constants);
485: PetscHeaderDestroy(prob);
486: return(0);
487: }
489: /*@
490: PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType().
492: Collective on MPI_Comm
494: Input Parameter:
495: . comm - The communicator for the PetscDS object
497: Output Parameter:
498: . prob - The PetscDS object
500: Level: beginner
502: .seealso: PetscDSSetType(), PETSCDSBASIC
503: @*/
504: PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *prob)
505: {
506: PetscDS p;
511: *prob = NULL;
512: PetscDSInitializePackage();
514: PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);
516: p->Nf = 0;
517: p->setup = PETSC_FALSE;
518: p->numConstants = 0;
519: p->constants = NULL;
520: p->dimEmbed = -1;
521: p->defaultAdj[0] = PETSC_FALSE;
522: p->defaultAdj[1] = PETSC_TRUE;
524: *prob = p;
525: return(0);
526: }
528: /*@
529: PetscDSGetNumFields - Returns the number of fields in the DS
531: Not collective
533: Input Parameter:
534: . prob - The PetscDS object
536: Output Parameter:
537: . Nf - The number of fields
539: Level: beginner
541: .seealso: PetscDSGetSpatialDimension(), PetscDSCreate()
542: @*/
543: PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
544: {
548: *Nf = prob->Nf;
549: return(0);
550: }
552: /*@
553: PetscDSGetSpatialDimension - Returns the spatial dimension of the DS, meaning the topological dimension of the discretizations
555: Not collective
557: Input Parameter:
558: . prob - The PetscDS object
560: Output Parameter:
561: . dim - The spatial dimension
563: Level: beginner
565: .seealso: PetscDSGetCoordinateDimension(), PetscDSGetNumFields(), PetscDSCreate()
566: @*/
567: PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
568: {
574: *dim = 0;
575: if (prob->Nf) {
576: PetscObject obj;
577: PetscClassId id;
579: PetscDSGetDiscretization(prob, 0, &obj);
580: PetscObjectGetClassId(obj, &id);
581: if (id == PETSCFE_CLASSID) {PetscFEGetSpatialDimension((PetscFE) obj, dim);}
582: else if (id == PETSCFV_CLASSID) {PetscFVGetSpatialDimension((PetscFV) obj, dim);}
583: else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
584: }
585: return(0);
586: }
588: /*@
589: PetscDSGetCoordinateDimension - Returns the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded
591: Not collective
593: Input Parameter:
594: . prob - The PetscDS object
596: Output Parameter:
597: . dimEmbed - The coordinate dimension
599: Level: beginner
601: .seealso: PetscDSSetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
602: @*/
603: PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
604: {
608: if (prob->dimEmbed < 0) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
609: *dimEmbed = prob->dimEmbed;
610: return(0);
611: }
613: /*@
614: PetscDSSetCoordinateDimension - Set the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded
616: Not collective
618: Input Parameters:
619: + prob - The PetscDS object
620: - dimEmbed - The coordinate dimension
622: Level: beginner
624: .seealso: PetscDSGetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
625: @*/
626: PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
627: {
630: prob->dimEmbed = dimEmbed;
631: return(0);
632: }
634: /*@
635: PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
637: Not collective
639: Input Parameter:
640: . prob - The PetscDS object
642: Output Parameter:
643: . dim - The total problem dimension
645: Level: beginner
647: .seealso: PetscDSGetNumFields(), PetscDSCreate()
648: @*/
649: PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
650: {
655: PetscDSSetUp(prob);
657: *dim = prob->totDim;
658: return(0);
659: }
661: /*@
662: PetscDSGetTotalComponents - Returns the total number of components in this system
664: Not collective
666: Input Parameter:
667: . prob - The PetscDS object
669: Output Parameter:
670: . dim - The total number of components
672: Level: beginner
674: .seealso: PetscDSGetNumFields(), PetscDSCreate()
675: @*/
676: PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
677: {
682: PetscDSSetUp(prob);
684: *Nc = prob->totComp;
685: return(0);
686: }
688: /*@
689: PetscDSGetDiscretization - Returns the discretization object for the given field
691: Not collective
693: Input Parameters:
694: + prob - The PetscDS object
695: - f - The field number
697: Output Parameter:
698: . disc - The discretization object
700: Level: beginner
702: .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
703: @*/
704: PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
705: {
709: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
710: *disc = prob->disc[f];
711: return(0);
712: }
714: /*@
715: PetscDSSetDiscretization - Sets the discretization object for the given field
717: Not collective
719: Input Parameters:
720: + prob - The PetscDS object
721: . f - The field number
722: - disc - The discretization object
724: Level: beginner
726: .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
727: @*/
728: PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
729: {
735: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
736: PetscDSEnlarge_Static(prob, f+1);
737: if (prob->disc[f]) {PetscObjectDereference(prob->disc[f]);}
738: prob->disc[f] = disc;
739: PetscObjectReference(disc);
740: {
741: PetscClassId id;
743: PetscObjectGetClassId(disc, &id);
744: if (id == PETSCFE_CLASSID) {
745: PetscDSSetImplicit(prob, f, PETSC_TRUE);
746: PetscDSSetAdjacency(prob, f, PETSC_FALSE, PETSC_TRUE);
747: } else if (id == PETSCFV_CLASSID) {
748: PetscDSSetImplicit(prob, f, PETSC_FALSE);
749: PetscDSSetAdjacency(prob, f, PETSC_TRUE, PETSC_FALSE);
750: }
751: }
752: return(0);
753: }
755: /*@
756: PetscDSAddDiscretization - Adds a discretization object
758: Not collective
760: Input Parameters:
761: + prob - The PetscDS object
762: - disc - The boundary discretization object
764: Level: beginner
766: .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
767: @*/
768: PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
769: {
773: PetscDSSetDiscretization(prob, prob->Nf, disc);
774: return(0);
775: }
777: /*@
778: PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for IMEX
780: Not collective
782: Input Parameters:
783: + prob - The PetscDS object
784: - f - The field number
786: Output Parameter:
787: . implicit - The flag indicating what kind of solve to use for this field
789: Level: developer
791: .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
792: @*/
793: PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
794: {
798: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
799: *implicit = prob->implicit[f];
800: return(0);
801: }
803: /*@
804: PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for IMEX
806: Not collective
808: Input Parameters:
809: + prob - The PetscDS object
810: . f - The field number
811: - implicit - The flag indicating what kind of solve to use for this field
813: Level: developer
815: .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
816: @*/
817: PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
818: {
821: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
822: prob->implicit[f] = implicit;
823: return(0);
824: }
826: /*@
827: PetscDSGetAdjacency - Returns the flags for determining variable influence
829: Not collective
831: Input Parameters:
832: + prob - The PetscDS object
833: - f - The field number
835: Output Parameter:
836: + useCone - Flag for variable influence starting with the cone operation
837: - useClosure - Flag for variable influence using transitive closure
839: Note: See the discussion in DMPlexGetAdjacencyUseCone() and DMPlexGetAdjacencyUseClosure()
841: Level: developer
843: .seealso: PetscDSSetAdjacency(), DMPlexGetAdjacencyUseCone(), DMPlexGetAdjacencyUseClosure(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
844: @*/
845: PetscErrorCode PetscDSGetAdjacency(PetscDS prob, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
846: {
851: if (f < 0) {
852: if (useCone) *useCone = prob->defaultAdj[0];
853: if (useClosure) *useClosure = prob->defaultAdj[1];
854: } else {
855: if (f >= prob->Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
856: if (useCone) *useCone = prob->adjacency[f*2+0];
857: if (useClosure) *useClosure = prob->adjacency[f*2+1];
858: }
859: return(0);
860: }
862: /*@
863: PetscDSSetAdjacency - Set the flags for determining variable influence
865: Not collective
867: Input Parameters:
868: + prob - The PetscDS object
869: . f - The field number
870: . useCone - Flag for variable influence starting with the cone operation
871: - useClosure - Flag for variable influence using transitive closure
873: Note: See the discussion in DMPlexGetAdjacencyUseCone() and DMPlexGetAdjacencyUseClosure()
875: Level: developer
877: .seealso: PetscDSGetAdjacency(), DMPlexGetAdjacencyUseCone(), DMPlexGetAdjacencyUseClosure(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
878: @*/
879: PetscErrorCode PetscDSSetAdjacency(PetscDS prob, PetscInt f, PetscBool useCone, PetscBool useClosure)
880: {
883: if (f < 0) {
884: prob->defaultAdj[0] = useCone;
885: prob->defaultAdj[1] = useClosure;
886: } else {
887: if (f >= prob->Nf) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
888: prob->adjacency[f*2+0] = useCone;
889: prob->adjacency[f*2+1] = useClosure;
890: }
891: return(0);
892: }
894: PetscErrorCode PetscDSGetObjective(PetscDS prob, PetscInt f,
895: void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
896: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
897: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
898: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
899: {
903: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
904: *obj = prob->obj[f];
905: return(0);
906: }
908: PetscErrorCode PetscDSSetObjective(PetscDS prob, PetscInt f,
909: void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
910: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
911: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
912: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
913: {
919: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
920: PetscDSEnlarge_Static(prob, f+1);
921: prob->obj[f] = obj;
922: return(0);
923: }
925: /*@C
926: PetscDSGetResidual - Get the pointwise residual function for a given test field
928: Not collective
930: Input Parameters:
931: + prob - The PetscDS
932: - f - The test field number
934: Output Parameters:
935: + f0 - integrand for the test function term
936: - f1 - integrand for the test function gradient term
938: Note: We are using a first order FEM model for the weak form:
940: \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)
942: The calling sequence for the callbacks f0 and f1 is given by:
944: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
945: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
946: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
947: $ PetscReal t, const PetscReal x[], PetscScalar f0[])
949: + dim - the spatial dimension
950: . Nf - the number of fields
951: . uOff - the offset into u[] and u_t[] for each field
952: . uOff_x - the offset into u_x[] for each field
953: . u - each field evaluated at the current point
954: . u_t - the time derivative of each field evaluated at the current point
955: . u_x - the gradient of each field evaluated at the current point
956: . aOff - the offset into a[] and a_t[] for each auxiliary field
957: . aOff_x - the offset into a_x[] for each auxiliary field
958: . a - each auxiliary field evaluated at the current point
959: . a_t - the time derivative of each auxiliary field evaluated at the current point
960: . a_x - the gradient of auxiliary each field evaluated at the current point
961: . t - current time
962: . x - coordinates of the current point
963: . numConstants - number of constant parameters
964: . constants - constant parameters
965: - f0 - output values at the current point
967: Level: intermediate
969: .seealso: PetscDSSetResidual()
970: @*/
971: PetscErrorCode PetscDSGetResidual(PetscDS prob, PetscInt f,
972: void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
973: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
974: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
975: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
976: void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
977: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
978: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
979: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
980: {
983: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
986: return(0);
987: }
989: /*@C
990: PetscDSSetResidual - Set the pointwise residual function for a given test field
992: Not collective
994: Input Parameters:
995: + prob - The PetscDS
996: . f - The test field number
997: . f0 - integrand for the test function term
998: - f1 - integrand for the test function gradient term
1000: Note: We are using a first order FEM model for the weak form:
1002: \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)
1004: The calling sequence for the callbacks f0 and f1 is given by:
1006: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1007: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1008: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1009: $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1011: + dim - the spatial dimension
1012: . Nf - the number of fields
1013: . uOff - the offset into u[] and u_t[] for each field
1014: . uOff_x - the offset into u_x[] for each field
1015: . u - each field evaluated at the current point
1016: . u_t - the time derivative of each field evaluated at the current point
1017: . u_x - the gradient of each field evaluated at the current point
1018: . aOff - the offset into a[] and a_t[] for each auxiliary field
1019: . aOff_x - the offset into a_x[] for each auxiliary field
1020: . a - each auxiliary field evaluated at the current point
1021: . a_t - the time derivative of each auxiliary field evaluated at the current point
1022: . a_x - the gradient of auxiliary each field evaluated at the current point
1023: . t - current time
1024: . x - coordinates of the current point
1025: . numConstants - number of constant parameters
1026: . constants - constant parameters
1027: - f0 - output values at the current point
1029: Level: intermediate
1031: .seealso: PetscDSGetResidual()
1032: @*/
1033: PetscErrorCode PetscDSSetResidual(PetscDS prob, PetscInt f,
1034: void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1035: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1036: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1037: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1038: void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1039: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1040: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1041: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1042: {
1049: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1050: PetscDSEnlarge_Static(prob, f+1);
1051: prob->f[f*2+0] = f0;
1052: prob->f[f*2+1] = f1;
1053: return(0);
1054: }
1056: /*@C
1057: PetscDSHasJacobian - Signals that Jacobian functions have been set
1059: Not collective
1061: Input Parameter:
1062: . prob - The PetscDS
1064: Output Parameter:
1065: . hasJac - flag that pointwise function for the Jacobian has been set
1067: Level: intermediate
1069: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1070: @*/
1071: PetscErrorCode PetscDSHasJacobian(PetscDS prob, PetscBool *hasJac)
1072: {
1073: PetscInt f, g, h;
1077: *hasJac = PETSC_FALSE;
1078: for (f = 0; f < prob->Nf; ++f) {
1079: for (g = 0; g < prob->Nf; ++g) {
1080: for (h = 0; h < 4; ++h) {
1081: if (prob->g[(f*prob->Nf + g)*4+h]) *hasJac = PETSC_TRUE;
1082: }
1083: }
1084: }
1085: return(0);
1086: }
1088: /*@C
1089: PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1091: Not collective
1093: Input Parameters:
1094: + prob - The PetscDS
1095: . f - The test field number
1096: - g - The field number
1098: Output Parameters:
1099: + g0 - integrand for the test and basis function term
1100: . g1 - integrand for the test function and basis function gradient term
1101: . g2 - integrand for the test function gradient and basis function term
1102: - g3 - integrand for the test function gradient and basis function gradient term
1104: Note: We are using a first order FEM model for the weak form:
1106: \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
1108: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1110: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1111: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1112: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1113: $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1115: + dim - the spatial dimension
1116: . Nf - the number of fields
1117: . uOff - the offset into u[] and u_t[] for each field
1118: . uOff_x - the offset into u_x[] for each field
1119: . u - each field evaluated at the current point
1120: . u_t - the time derivative of each field evaluated at the current point
1121: . u_x - the gradient of each field evaluated at the current point
1122: . aOff - the offset into a[] and a_t[] for each auxiliary field
1123: . aOff_x - the offset into a_x[] for each auxiliary field
1124: . a - each auxiliary field evaluated at the current point
1125: . a_t - the time derivative of each auxiliary field evaluated at the current point
1126: . a_x - the gradient of auxiliary each field evaluated at the current point
1127: . t - current time
1128: . u_tShift - the multiplier a for dF/dU_t
1129: . x - coordinates of the current point
1130: . numConstants - number of constant parameters
1131: . constants - constant parameters
1132: - g0 - output values at the current point
1134: Level: intermediate
1136: .seealso: PetscDSSetJacobian()
1137: @*/
1138: PetscErrorCode PetscDSGetJacobian(PetscDS prob, PetscInt f, PetscInt g,
1139: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1140: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1141: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1142: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1143: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1144: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1145: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1146: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1147: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1148: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1149: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1150: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1151: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1152: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1153: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1154: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1155: {
1158: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1159: if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
1164: return(0);
1165: }
1167: /*@C
1168: PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1170: Not collective
1172: Input Parameters:
1173: + prob - The PetscDS
1174: . f - The test field number
1175: . g - The field number
1176: . g0 - integrand for the test and basis function term
1177: . g1 - integrand for the test function and basis function gradient term
1178: . g2 - integrand for the test function gradient and basis function term
1179: - g3 - integrand for the test function gradient and basis function gradient term
1181: Note: We are using a first order FEM model for the weak form:
1183: \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
1185: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1187: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1188: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1189: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1190: $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1192: + dim - the spatial dimension
1193: . Nf - the number of fields
1194: . uOff - the offset into u[] and u_t[] for each field
1195: . uOff_x - the offset into u_x[] for each field
1196: . u - each field evaluated at the current point
1197: . u_t - the time derivative of each field evaluated at the current point
1198: . u_x - the gradient of each field evaluated at the current point
1199: . aOff - the offset into a[] and a_t[] for each auxiliary field
1200: . aOff_x - the offset into a_x[] for each auxiliary field
1201: . a - each auxiliary field evaluated at the current point
1202: . a_t - the time derivative of each auxiliary field evaluated at the current point
1203: . a_x - the gradient of auxiliary each field evaluated at the current point
1204: . t - current time
1205: . u_tShift - the multiplier a for dF/dU_t
1206: . x - coordinates of the current point
1207: . numConstants - number of constant parameters
1208: . constants - constant parameters
1209: - g0 - output values at the current point
1211: Level: intermediate
1213: .seealso: PetscDSGetJacobian()
1214: @*/
1215: PetscErrorCode PetscDSSetJacobian(PetscDS prob, PetscInt f, PetscInt g,
1216: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1217: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1218: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1219: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1220: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1221: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1222: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1223: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1224: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1225: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1226: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1227: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1228: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1229: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1230: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1231: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1232: {
1241: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1242: if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1243: PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
1244: prob->g[(f*prob->Nf + g)*4+0] = g0;
1245: prob->g[(f*prob->Nf + g)*4+1] = g1;
1246: prob->g[(f*prob->Nf + g)*4+2] = g2;
1247: prob->g[(f*prob->Nf + g)*4+3] = g3;
1248: return(0);
1249: }
1251: /*@C
1252: PetscDSHasJacobianPreconditioner - Signals that a Jacobian preconditioner matrix has been set
1254: Not collective
1256: Input Parameter:
1257: . prob - The PetscDS
1259: Output Parameter:
1260: . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1262: Level: intermediate
1264: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1265: @*/
1266: PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS prob, PetscBool *hasJacPre)
1267: {
1268: PetscInt f, g, h;
1272: *hasJacPre = PETSC_FALSE;
1273: for (f = 0; f < prob->Nf; ++f) {
1274: for (g = 0; g < prob->Nf; ++g) {
1275: for (h = 0; h < 4; ++h) {
1276: if (prob->gp[(f*prob->Nf + g)*4+h]) *hasJacPre = PETSC_TRUE;
1277: }
1278: }
1279: }
1280: return(0);
1281: }
1283: /*@C
1284: 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.
1286: Not collective
1288: Input Parameters:
1289: + prob - The PetscDS
1290: . f - The test field number
1291: - g - The field number
1293: Output Parameters:
1294: + g0 - integrand for the test and basis function term
1295: . g1 - integrand for the test function and basis function gradient term
1296: . g2 - integrand for the test function gradient and basis function term
1297: - g3 - integrand for the test function gradient and basis function gradient term
1299: Note: We are using a first order FEM model for the weak form:
1301: \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
1303: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1305: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1306: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1307: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1308: $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1310: + dim - the spatial dimension
1311: . Nf - the number of fields
1312: . uOff - the offset into u[] and u_t[] for each field
1313: . uOff_x - the offset into u_x[] for each field
1314: . u - each field evaluated at the current point
1315: . u_t - the time derivative of each field evaluated at the current point
1316: . u_x - the gradient of each field evaluated at the current point
1317: . aOff - the offset into a[] and a_t[] for each auxiliary field
1318: . aOff_x - the offset into a_x[] for each auxiliary field
1319: . a - each auxiliary field evaluated at the current point
1320: . a_t - the time derivative of each auxiliary field evaluated at the current point
1321: . a_x - the gradient of auxiliary each field evaluated at the current point
1322: . t - current time
1323: . u_tShift - the multiplier a for dF/dU_t
1324: . x - coordinates of the current point
1325: . numConstants - number of constant parameters
1326: . constants - constant parameters
1327: - g0 - output values at the current point
1329: Level: intermediate
1331: .seealso: PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1332: @*/
1333: PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g,
1334: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1335: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1336: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1337: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1338: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1339: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1340: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1341: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1342: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1343: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1344: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1345: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1346: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1347: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1348: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1349: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1350: {
1353: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1354: if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
1359: return(0);
1360: }
1362: /*@C
1363: 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.
1365: Not collective
1367: Input Parameters:
1368: + prob - The PetscDS
1369: . f - The test field number
1370: . g - The field number
1371: . g0 - integrand for the test and basis function term
1372: . g1 - integrand for the test function and basis function gradient term
1373: . g2 - integrand for the test function gradient and basis function term
1374: - g3 - integrand for the test function gradient and basis function gradient term
1376: Note: We are using a first order FEM model for the weak form:
1378: \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
1380: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1382: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1383: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1384: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1385: $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1387: + dim - the spatial dimension
1388: . Nf - the number of fields
1389: . uOff - the offset into u[] and u_t[] for each field
1390: . uOff_x - the offset into u_x[] for each field
1391: . u - each field evaluated at the current point
1392: . u_t - the time derivative of each field evaluated at the current point
1393: . u_x - the gradient of each field evaluated at the current point
1394: . aOff - the offset into a[] and a_t[] for each auxiliary field
1395: . aOff_x - the offset into a_x[] for each auxiliary field
1396: . a - each auxiliary field evaluated at the current point
1397: . a_t - the time derivative of each auxiliary field evaluated at the current point
1398: . a_x - the gradient of auxiliary each field evaluated at the current point
1399: . t - current time
1400: . u_tShift - the multiplier a for dF/dU_t
1401: . x - coordinates of the current point
1402: . numConstants - number of constant parameters
1403: . constants - constant parameters
1404: - g0 - output values at the current point
1406: Level: intermediate
1408: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobian()
1409: @*/
1410: PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g,
1411: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1412: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1413: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1414: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1415: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1416: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1417: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1418: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1419: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1420: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1421: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1422: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1423: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1424: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1425: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1426: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1427: {
1436: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1437: if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1438: PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
1439: prob->gp[(f*prob->Nf + g)*4+0] = g0;
1440: prob->gp[(f*prob->Nf + g)*4+1] = g1;
1441: prob->gp[(f*prob->Nf + g)*4+2] = g2;
1442: prob->gp[(f*prob->Nf + g)*4+3] = g3;
1443: return(0);
1444: }
1446: /*@C
1447: PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1449: Not collective
1451: Input Parameter:
1452: . prob - The PetscDS
1454: Output Parameter:
1455: . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1457: Level: intermediate
1459: .seealso: PetscDSGetDynamicJacobian(), PetscDSSetDynamicJacobian(), PetscDSGetJacobian()
1460: @*/
1461: PetscErrorCode PetscDSHasDynamicJacobian(PetscDS prob, PetscBool *hasDynJac)
1462: {
1463: PetscInt f, g, h;
1467: *hasDynJac = PETSC_FALSE;
1468: for (f = 0; f < prob->Nf; ++f) {
1469: for (g = 0; g < prob->Nf; ++g) {
1470: for (h = 0; h < 4; ++h) {
1471: if (prob->gt[(f*prob->Nf + g)*4+h]) *hasDynJac = PETSC_TRUE;
1472: }
1473: }
1474: }
1475: return(0);
1476: }
1478: /*@C
1479: PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1481: Not collective
1483: Input Parameters:
1484: + prob - The PetscDS
1485: . f - The test field number
1486: - g - The field number
1488: Output Parameters:
1489: + g0 - integrand for the test and basis function term
1490: . g1 - integrand for the test function and basis function gradient term
1491: . g2 - integrand for the test function gradient and basis function term
1492: - g3 - integrand for the test function gradient and basis function gradient term
1494: Note: We are using a first order FEM model for the weak form:
1496: \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
1498: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1500: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1501: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1502: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1503: $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1505: + dim - the spatial dimension
1506: . Nf - the number of fields
1507: . uOff - the offset into u[] and u_t[] for each field
1508: . uOff_x - the offset into u_x[] for each field
1509: . u - each field evaluated at the current point
1510: . u_t - the time derivative of each field evaluated at the current point
1511: . u_x - the gradient of each field evaluated at the current point
1512: . aOff - the offset into a[] and a_t[] for each auxiliary field
1513: . aOff_x - the offset into a_x[] for each auxiliary field
1514: . a - each auxiliary field evaluated at the current point
1515: . a_t - the time derivative of each auxiliary field evaluated at the current point
1516: . a_x - the gradient of auxiliary each field evaluated at the current point
1517: . t - current time
1518: . u_tShift - the multiplier a for dF/dU_t
1519: . x - coordinates of the current point
1520: . numConstants - number of constant parameters
1521: . constants - constant parameters
1522: - g0 - output values at the current point
1524: Level: intermediate
1526: .seealso: PetscDSSetJacobian()
1527: @*/
1528: PetscErrorCode PetscDSGetDynamicJacobian(PetscDS prob, PetscInt f, PetscInt g,
1529: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1530: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1531: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1532: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1533: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1534: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1535: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1536: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1537: void (**g2)(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 g2[]),
1541: void (**g3)(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 g3[]))
1545: {
1548: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1549: if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
1554: return(0);
1555: }
1557: /*@C
1558: PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1560: Not collective
1562: Input Parameters:
1563: + prob - The PetscDS
1564: . f - The test field number
1565: . g - The field number
1566: . g0 - integrand for the test and basis function term
1567: . g1 - integrand for the test function and basis function gradient term
1568: . g2 - integrand for the test function gradient and basis function term
1569: - g3 - integrand for the test function gradient and basis function gradient term
1571: Note: We are using a first order FEM model for the weak form:
1573: \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
1575: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1577: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1578: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1579: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1580: $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1582: + dim - the spatial dimension
1583: . Nf - the number of fields
1584: . uOff - the offset into u[] and u_t[] for each field
1585: . uOff_x - the offset into u_x[] for each field
1586: . u - each field evaluated at the current point
1587: . u_t - the time derivative of each field evaluated at the current point
1588: . u_x - the gradient of each field evaluated at the current point
1589: . aOff - the offset into a[] and a_t[] for each auxiliary field
1590: . aOff_x - the offset into a_x[] for each auxiliary field
1591: . a - each auxiliary field evaluated at the current point
1592: . a_t - the time derivative of each auxiliary field evaluated at the current point
1593: . a_x - the gradient of auxiliary each field evaluated at the current point
1594: . t - current time
1595: . u_tShift - the multiplier a for dF/dU_t
1596: . x - coordinates of the current point
1597: . numConstants - number of constant parameters
1598: . constants - constant parameters
1599: - g0 - output values at the current point
1601: Level: intermediate
1603: .seealso: PetscDSGetJacobian()
1604: @*/
1605: PetscErrorCode PetscDSSetDynamicJacobian(PetscDS prob, PetscInt f, PetscInt g,
1606: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1607: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1608: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1609: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1610: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1611: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1612: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1613: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1614: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1615: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1616: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1617: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1618: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1619: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1620: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1621: PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1622: {
1631: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1632: if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1633: PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
1634: prob->gt[(f*prob->Nf + g)*4+0] = g0;
1635: prob->gt[(f*prob->Nf + g)*4+1] = g1;
1636: prob->gt[(f*prob->Nf + g)*4+2] = g2;
1637: prob->gt[(f*prob->Nf + g)*4+3] = g3;
1638: return(0);
1639: }
1641: /*@C
1642: PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
1644: Not collective
1646: Input Arguments:
1647: + prob - The PetscDS object
1648: - f - The field number
1650: Output Argument:
1651: . r - Riemann solver
1653: Calling sequence for r:
1655: $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1657: + dim - The spatial dimension
1658: . Nf - The number of fields
1659: . x - The coordinates at a point on the interface
1660: . n - The normal vector to the interface
1661: . uL - The state vector to the left of the interface
1662: . uR - The state vector to the right of the interface
1663: . flux - output array of flux through the interface
1664: . numConstants - number of constant parameters
1665: . constants - constant parameters
1666: - ctx - optional user context
1668: Level: intermediate
1670: .seealso: PetscDSSetRiemannSolver()
1671: @*/
1672: PetscErrorCode PetscDSGetRiemannSolver(PetscDS prob, PetscInt f,
1673: 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))
1674: {
1677: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1679: *r = prob->r[f];
1680: return(0);
1681: }
1683: /*@C
1684: PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
1686: Not collective
1688: Input Arguments:
1689: + prob - The PetscDS object
1690: . f - The field number
1691: - r - Riemann solver
1693: Calling sequence for r:
1695: $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1697: + dim - The spatial dimension
1698: . Nf - The number of fields
1699: . x - The coordinates at a point on the interface
1700: . n - The normal vector to the interface
1701: . uL - The state vector to the left of the interface
1702: . uR - The state vector to the right of the interface
1703: . flux - output array of flux through the interface
1704: . numConstants - number of constant parameters
1705: . constants - constant parameters
1706: - ctx - optional user context
1708: Level: intermediate
1710: .seealso: PetscDSGetRiemannSolver()
1711: @*/
1712: PetscErrorCode PetscDSSetRiemannSolver(PetscDS prob, PetscInt f,
1713: 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))
1714: {
1720: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1721: PetscDSEnlarge_Static(prob, f+1);
1722: prob->r[f] = r;
1723: return(0);
1724: }
1726: /*@C
1727: PetscDSGetUpdate - Get the pointwise update function for a given field
1729: Not collective
1731: Input Parameters:
1732: + prob - The PetscDS
1733: - f - The field number
1735: Output Parameters:
1736: + update - update function
1738: Note: The calling sequence for the callback update is given by:
1740: $ update(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, const PetscReal x[], PetscScalar uNew[])
1745: + dim - the spatial dimension
1746: . Nf - the number of fields
1747: . uOff - the offset into u[] and u_t[] for each field
1748: . uOff_x - the offset into u_x[] for each field
1749: . u - each field evaluated at the current point
1750: . u_t - the time derivative of each field evaluated at the current point
1751: . u_x - the gradient of each field evaluated at the current point
1752: . aOff - the offset into a[] and a_t[] for each auxiliary field
1753: . aOff_x - the offset into a_x[] for each auxiliary field
1754: . a - each auxiliary field evaluated at the current point
1755: . a_t - the time derivative of each auxiliary field evaluated at the current point
1756: . a_x - the gradient of auxiliary each field evaluated at the current point
1757: . t - current time
1758: . x - coordinates of the current point
1759: - uNew - new value for field at the current point
1761: Level: intermediate
1763: .seealso: PetscDSSetUpdate(), PetscDSSetResidual()
1764: @*/
1765: PetscErrorCode PetscDSGetUpdate(PetscDS prob, PetscInt f,
1766: void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1767: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1768: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1769: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
1770: {
1773: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1775: return(0);
1776: }
1778: /*@C
1779: PetscDSSetUpdate - Set the pointwise update function for a given field
1781: Not collective
1783: Input Parameters:
1784: + prob - The PetscDS
1785: . f - The field number
1786: - update - update function
1788: Note: The calling sequence for the callback update is given by:
1790: $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1791: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1792: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1793: $ PetscReal t, const PetscReal x[], PetscScalar uNew[])
1795: + dim - the spatial dimension
1796: . Nf - the number of fields
1797: . uOff - the offset into u[] and u_t[] for each field
1798: . uOff_x - the offset into u_x[] for each field
1799: . u - each field evaluated at the current point
1800: . u_t - the time derivative of each field evaluated at the current point
1801: . u_x - the gradient of each field evaluated at the current point
1802: . aOff - the offset into a[] and a_t[] for each auxiliary field
1803: . aOff_x - the offset into a_x[] for each auxiliary field
1804: . a - each auxiliary field evaluated at the current point
1805: . a_t - the time derivative of each auxiliary field evaluated at the current point
1806: . a_x - the gradient of auxiliary each field evaluated at the current point
1807: . t - current time
1808: . x - coordinates of the current point
1809: - uNew - new field values at the current point
1811: Level: intermediate
1813: .seealso: PetscDSGetResidual()
1814: @*/
1815: PetscErrorCode PetscDSSetUpdate(PetscDS prob, PetscInt f,
1816: void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1817: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1818: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1819: PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
1820: {
1826: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1827: PetscDSEnlarge_Static(prob, f+1);
1828: prob->update[f] = update;
1829: return(0);
1830: }
1832: PetscErrorCode PetscDSGetContext(PetscDS prob, PetscInt f, void **ctx)
1833: {
1836: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1838: *ctx = prob->ctx[f];
1839: return(0);
1840: }
1842: PetscErrorCode PetscDSSetContext(PetscDS prob, PetscInt f, void *ctx)
1843: {
1848: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1849: PetscDSEnlarge_Static(prob, f+1);
1850: prob->ctx[f] = ctx;
1851: return(0);
1852: }
1854: /*@C
1855: PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
1857: Not collective
1859: Input Parameters:
1860: + prob - The PetscDS
1861: - f - The test field number
1863: Output Parameters:
1864: + f0 - boundary integrand for the test function term
1865: - f1 - boundary integrand for the test function gradient term
1867: Note: We are using a first order FEM model for the weak form:
1869: \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
1871: The calling sequence for the callbacks f0 and f1 is given by:
1873: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1874: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1875: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1876: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
1878: + dim - the spatial dimension
1879: . Nf - the number of fields
1880: . uOff - the offset into u[] and u_t[] for each field
1881: . uOff_x - the offset into u_x[] for each field
1882: . u - each field evaluated at the current point
1883: . u_t - the time derivative of each field evaluated at the current point
1884: . u_x - the gradient of each field evaluated at the current point
1885: . aOff - the offset into a[] and a_t[] for each auxiliary field
1886: . aOff_x - the offset into a_x[] for each auxiliary field
1887: . a - each auxiliary field evaluated at the current point
1888: . a_t - the time derivative of each auxiliary field evaluated at the current point
1889: . a_x - the gradient of auxiliary each field evaluated at the current point
1890: . t - current time
1891: . x - coordinates of the current point
1892: . n - unit normal at the current point
1893: . numConstants - number of constant parameters
1894: . constants - constant parameters
1895: - f0 - output values at the current point
1897: Level: intermediate
1899: .seealso: PetscDSSetBdResidual()
1900: @*/
1901: PetscErrorCode PetscDSGetBdResidual(PetscDS prob, PetscInt f,
1902: void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1903: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1904: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1905: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1906: void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1907: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1908: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1909: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1910: {
1913: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1916: return(0);
1917: }
1919: /*@C
1920: PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
1922: Not collective
1924: Input Parameters:
1925: + prob - The PetscDS
1926: . f - The test field number
1927: . f0 - boundary integrand for the test function term
1928: - f1 - boundary integrand for the test function gradient term
1930: Note: We are using a first order FEM model for the weak form:
1932: \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
1934: The calling sequence for the callbacks f0 and f1 is given by:
1936: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1937: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1938: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1939: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
1941: + dim - the spatial dimension
1942: . Nf - the number of fields
1943: . uOff - the offset into u[] and u_t[] for each field
1944: . uOff_x - the offset into u_x[] for each field
1945: . u - each field evaluated at the current point
1946: . u_t - the time derivative of each field evaluated at the current point
1947: . u_x - the gradient of each field evaluated at the current point
1948: . aOff - the offset into a[] and a_t[] for each auxiliary field
1949: . aOff_x - the offset into a_x[] for each auxiliary field
1950: . a - each auxiliary field evaluated at the current point
1951: . a_t - the time derivative of each auxiliary field evaluated at the current point
1952: . a_x - the gradient of auxiliary each field evaluated at the current point
1953: . t - current time
1954: . x - coordinates of the current point
1955: . n - unit normal at the current point
1956: . numConstants - number of constant parameters
1957: . constants - constant parameters
1958: - f0 - output values at the current point
1960: Level: intermediate
1962: .seealso: PetscDSGetBdResidual()
1963: @*/
1964: PetscErrorCode PetscDSSetBdResidual(PetscDS prob, PetscInt f,
1965: void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1966: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1967: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1968: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1969: void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1970: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1971: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1972: PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1973: {
1978: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1979: PetscDSEnlarge_Static(prob, f+1);
1982: return(0);
1983: }
1985: /*@C
1986: PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
1988: Not collective
1990: Input Parameters:
1991: + prob - The PetscDS
1992: . f - The test field number
1993: - g - The field number
1995: Output Parameters:
1996: + g0 - integrand for the test and basis function term
1997: . g1 - integrand for the test function and basis function gradient term
1998: . g2 - integrand for the test function gradient and basis function term
1999: - g3 - integrand for the test function gradient and basis function gradient term
2001: Note: We are using a first order FEM model for the weak form:
2003: \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
2005: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2007: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2008: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2009: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2010: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2012: + dim - the spatial dimension
2013: . Nf - the number of fields
2014: . uOff - the offset into u[] and u_t[] for each field
2015: . uOff_x - the offset into u_x[] for each field
2016: . u - each field evaluated at the current point
2017: . u_t - the time derivative of each field evaluated at the current point
2018: . u_x - the gradient of each field evaluated at the current point
2019: . aOff - the offset into a[] and a_t[] for each auxiliary field
2020: . aOff_x - the offset into a_x[] for each auxiliary field
2021: . a - each auxiliary field evaluated at the current point
2022: . a_t - the time derivative of each auxiliary field evaluated at the current point
2023: . a_x - the gradient of auxiliary each field evaluated at the current point
2024: . t - current time
2025: . u_tShift - the multiplier a for dF/dU_t
2026: . x - coordinates of the current point
2027: . n - normal at the current point
2028: . numConstants - number of constant parameters
2029: . constants - constant parameters
2030: - g0 - output values at the current point
2032: Level: intermediate
2034: .seealso: PetscDSSetBdJacobian()
2035: @*/
2036: PetscErrorCode PetscDSGetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
2037: void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2038: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2039: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2040: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2041: void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2042: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2043: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2044: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2045: void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2046: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2047: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2048: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2049: void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2050: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2051: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2052: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2053: {
2056: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2057: if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
2062: return(0);
2063: }
2065: /*@C
2066: PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2068: Not collective
2070: Input Parameters:
2071: + prob - The PetscDS
2072: . f - The test field number
2073: . g - The field number
2074: . g0 - integrand for the test and basis function term
2075: . g1 - integrand for the test function and basis function gradient term
2076: . g2 - integrand for the test function gradient and basis function term
2077: - g3 - integrand for the test function gradient and basis function gradient term
2079: Note: We are using a first order FEM model for the weak form:
2081: \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
2083: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2085: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2086: $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2087: $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2088: $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2090: + dim - the spatial dimension
2091: . Nf - the number of fields
2092: . uOff - the offset into u[] and u_t[] for each field
2093: . uOff_x - the offset into u_x[] for each field
2094: . u - each field evaluated at the current point
2095: . u_t - the time derivative of each field evaluated at the current point
2096: . u_x - the gradient of each field evaluated at the current point
2097: . aOff - the offset into a[] and a_t[] for each auxiliary field
2098: . aOff_x - the offset into a_x[] for each auxiliary field
2099: . a - each auxiliary field evaluated at the current point
2100: . a_t - the time derivative of each auxiliary field evaluated at the current point
2101: . a_x - the gradient of auxiliary each field evaluated at the current point
2102: . t - current time
2103: . u_tShift - the multiplier a for dF/dU_t
2104: . x - coordinates of the current point
2105: . n - normal at the current point
2106: . numConstants - number of constant parameters
2107: . constants - constant parameters
2108: - g0 - output values at the current point
2110: Level: intermediate
2112: .seealso: PetscDSGetBdJacobian()
2113: @*/
2114: PetscErrorCode PetscDSSetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
2115: void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2116: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2117: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2118: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2119: void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2120: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2121: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2122: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2123: void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2124: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2125: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2126: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2127: void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2128: const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2129: const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2130: PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2131: {
2140: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2141: if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
2142: PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
2143: prob->gBd[(f*prob->Nf + g)*4+0] = g0;
2144: prob->gBd[(f*prob->Nf + g)*4+1] = g1;
2145: prob->gBd[(f*prob->Nf + g)*4+2] = g2;
2146: prob->gBd[(f*prob->Nf + g)*4+3] = g3;
2147: return(0);
2148: }
2150: /*@C
2151: PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2153: Not collective
2155: Input Parameters:
2156: + prob - The PetscDS
2157: - f - The test field number
2159: Output Parameter:
2160: . exactSol - exact solution for the test field
2162: Note: The calling sequence for the solution functions is given by:
2164: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2166: + dim - the spatial dimension
2167: . t - current time
2168: . x - coordinates of the current point
2169: . Nc - the number of field components
2170: . u - the solution field evaluated at the current point
2171: - ctx - a user context
2173: Level: intermediate
2175: .seealso: PetscDSSetExactSolution()
2176: @*/
2177: PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx))
2178: {
2181: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2183: return(0);
2184: }
2186: /*@C
2187: PetscDSSetExactSolution - Get the pointwise exact solution function for a given test field
2189: Not collective
2191: Input Parameters:
2192: + prob - The PetscDS
2193: . f - The test field number
2194: - sol - solution function for the test fields
2196: Note: The calling sequence for solution functions is given by:
2198: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2200: + dim - the spatial dimension
2201: . t - current time
2202: . x - coordinates of the current point
2203: . Nc - the number of field components
2204: . u - the solution field evaluated at the current point
2205: - ctx - a user context
2207: Level: intermediate
2209: .seealso: PetscDSGetExactSolution()
2210: @*/
2211: PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx))
2212: {
2217: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2218: PetscDSEnlarge_Static(prob, f+1);
2220: return(0);
2221: }
2223: /*@C
2224: PetscDSGetConstants - Returns the array of constants passed to point functions
2226: Not collective
2228: Input Parameter:
2229: . prob - The PetscDS object
2231: Output Parameters:
2232: + numConstants - The number of constants
2233: - constants - The array of constants, NULL if there are none
2235: Level: intermediate
2237: .seealso: PetscDSSetConstants(), PetscDSCreate()
2238: @*/
2239: PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2240: {
2245: return(0);
2246: }
2248: /*@C
2249: PetscDSSetConstants - Set the array of constants passed to point functions
2251: Not collective
2253: Input Parameters:
2254: + prob - The PetscDS object
2255: . numConstants - The number of constants
2256: - constants - The array of constants, NULL if there are none
2258: Level: intermediate
2260: .seealso: PetscDSGetConstants(), PetscDSCreate()
2261: @*/
2262: PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2263: {
2268: if (numConstants != prob->numConstants) {
2269: PetscFree(prob->constants);
2270: prob->numConstants = numConstants;
2271: if (prob->numConstants) {
2272: PetscMalloc1(prob->numConstants, &prob->constants);
2273: } else {
2274: prob->constants = NULL;
2275: }
2276: }
2277: if (prob->numConstants) {
2279: PetscMemcpy(prob->constants, constants, prob->numConstants * sizeof(PetscScalar));
2280: }
2281: return(0);
2282: }
2284: /*@
2285: PetscDSGetFieldIndex - Returns the index of the given field
2287: Not collective
2289: Input Parameters:
2290: + prob - The PetscDS object
2291: - disc - The discretization object
2293: Output Parameter:
2294: . f - The field number
2296: Level: beginner
2298: .seealso: PetscGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
2299: @*/
2300: PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2301: {
2302: PetscInt g;
2307: *f = -1;
2308: for (g = 0; g < prob->Nf; ++g) {if (disc == prob->disc[g]) break;}
2309: if (g == prob->Nf) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
2310: *f = g;
2311: return(0);
2312: }
2314: /*@
2315: PetscDSGetFieldSize - Returns the size of the given field in the full space basis
2317: Not collective
2319: Input Parameters:
2320: + prob - The PetscDS object
2321: - f - The field number
2323: Output Parameter:
2324: . size - The size
2326: Level: beginner
2328: .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
2329: @*/
2330: PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2331: {
2337: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2338: PetscDSSetUp(prob);
2339: *size = prob->Nb[f];
2340: return(0);
2341: }
2343: /*@
2344: PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2346: Not collective
2348: Input Parameters:
2349: + prob - The PetscDS object
2350: - f - The field number
2352: Output Parameter:
2353: . off - The offset
2355: Level: beginner
2357: .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate()
2358: @*/
2359: PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2360: {
2361: PetscInt size, g;
2367: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2368: *off = 0;
2369: for (g = 0; g < f; ++g) {
2370: PetscDSGetFieldSize(prob, g, &size);
2371: *off += size;
2372: }
2373: return(0);
2374: }
2376: /*@
2377: PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2379: Not collective
2381: Input Parameter:
2382: . prob - The PetscDS object
2384: Output Parameter:
2385: . dimensions - The number of dimensions
2387: Level: beginner
2389: .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
2390: @*/
2391: PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2392: {
2397: PetscDSSetUp(prob);
2399: *dimensions = prob->Nb;
2400: return(0);
2401: }
2403: /*@
2404: PetscDSGetComponents - Returns the number of components for each field on an evaluation point
2406: Not collective
2408: Input Parameter:
2409: . prob - The PetscDS object
2411: Output Parameter:
2412: . components - The number of components
2414: Level: beginner
2416: .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
2417: @*/
2418: PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
2419: {
2424: PetscDSSetUp(prob);
2426: *components = prob->Nc;
2427: return(0);
2428: }
2430: /*@
2431: PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
2433: Not collective
2435: Input Parameters:
2436: + prob - The PetscDS object
2437: - f - The field number
2439: Output Parameter:
2440: . off - The offset
2442: Level: beginner
2444: .seealso: PetscDSGetNumFields(), PetscDSCreate()
2445: @*/
2446: PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
2447: {
2451: if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2452: *off = prob->off[f];
2453: return(0);
2454: }
2456: /*@
2457: PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
2459: Not collective
2461: Input Parameter:
2462: . prob - The PetscDS object
2464: Output Parameter:
2465: . offsets - The offsets
2467: Level: beginner
2469: .seealso: PetscDSGetNumFields(), PetscDSCreate()
2470: @*/
2471: PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
2472: {
2476: *offsets = prob->off;
2477: return(0);
2478: }
2480: /*@
2481: PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
2483: Not collective
2485: Input Parameter:
2486: . prob - The PetscDS object
2488: Output Parameter:
2489: . offsets - The offsets
2491: Level: beginner
2493: .seealso: PetscDSGetNumFields(), PetscDSCreate()
2494: @*/
2495: PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
2496: {
2500: *offsets = prob->offDer;
2501: return(0);
2502: }
2504: /*@C
2505: PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
2507: Not collective
2509: Input Parameter:
2510: . prob - The PetscDS object
2512: Output Parameters:
2513: + basis - The basis function tabulation at quadrature points
2514: - basisDer - The basis function derivative tabulation at quadrature points
2516: Level: intermediate
2518: .seealso: PetscDSCreate()
2519: @*/
2520: PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer)
2521: {
2526: PetscDSSetUp(prob);
2529: return(0);
2530: }
2532: /*@C
2533: PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
2535: Not collective
2537: Input Parameter:
2538: . prob - The PetscDS object
2540: Output Parameters:
2541: + basisFace - The basis function tabulation at quadrature points
2542: - basisDerFace - The basis function derivative tabulation at quadrature points
2544: Level: intermediate
2546: .seealso: PetscDSGetTabulation(), PetscDSCreate()
2547: @*/
2548: PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer)
2549: {
2554: PetscDSSetUp(prob);
2557: return(0);
2558: }
2560: PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
2561: {
2566: PetscDSSetUp(prob);
2570: return(0);
2571: }
2573: PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
2574: {
2579: PetscDSSetUp(prob);
2586: return(0);
2587: }
2589: PetscErrorCode PetscDSGetRefCoordArrays(PetscDS prob, PetscReal **x, PetscScalar **refSpaceDer)
2590: {
2595: PetscDSSetUp(prob);
2598: return(0);
2599: }
2601: /*@C
2602: PetscDSAddBoundary - Add a boundary condition to the model
2604: Input Parameters:
2605: + ds - The PetscDS object
2606: . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
2607: . name - The BC name
2608: . labelname - The label defining constrained points
2609: . field - The field to constrain
2610: . numcomps - The number of constrained field components
2611: . comps - An array of constrained component numbers
2612: . bcFunc - A pointwise function giving boundary values
2613: . numids - The number of DMLabel ids for constrained points
2614: . ids - An array of ids for constrained points
2615: - ctx - An optional user context for bcFunc
2617: Options Database Keys:
2618: + -bc_<boundary name> <num> - Overrides the boundary ids
2619: - -bc_<boundary name>_comp <num> - Overrides the boundary components
2621: Level: developer
2623: .seealso: PetscDSGetBoundary()
2624: @*/
2625: PetscErrorCode PetscDSAddBoundary(PetscDS ds, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), PetscInt numids, const PetscInt *ids, void *ctx)
2626: {
2627: DSBoundary b;
2632: PetscNew(&b);
2633: PetscStrallocpy(name, (char **) &b->name);
2634: PetscStrallocpy(labelname, (char **) &b->labelname);
2635: PetscMalloc1(numcomps, &b->comps);
2636: if (numcomps) {PetscMemcpy(b->comps, comps, numcomps*sizeof(PetscInt));}
2637: PetscMalloc1(numids, &b->ids);
2638: if (numids) {PetscMemcpy(b->ids, ids, numids*sizeof(PetscInt));}
2639: b->type = type;
2640: b->field = field;
2641: b->numcomps = numcomps;
2642: b->func = bcFunc;
2643: b->numids = numids;
2644: b->ctx = ctx;
2645: b->next = ds->boundary;
2646: ds->boundary = b;
2647: return(0);
2648: }
2650: /*@
2651: PetscDSGetNumBoundary - Get the number of registered BC
2653: Input Parameters:
2654: . ds - The PetscDS object
2656: Output Parameters:
2657: . numBd - The number of BC
2659: Level: intermediate
2661: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary()
2662: @*/
2663: PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
2664: {
2665: DSBoundary b = ds->boundary;
2670: *numBd = 0;
2671: while (b) {++(*numBd); b = b->next;}
2672: return(0);
2673: }
2675: /*@C
2676: PetscDSGetBoundary - Add a boundary condition to the model
2678: Input Parameters:
2679: + ds - The PetscDS object
2680: - bd - The BC number
2682: Output Parameters:
2683: + type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
2684: . name - The BC name
2685: . labelname - The label defining constrained points
2686: . field - The field to constrain
2687: . numcomps - The number of constrained field components
2688: . comps - An array of constrained component numbers
2689: . bcFunc - A pointwise function giving boundary values
2690: . numids - The number of DMLabel ids for constrained points
2691: . ids - An array of ids for constrained points
2692: - ctx - An optional user context for bcFunc
2694: Options Database Keys:
2695: + -bc_<boundary name> <num> - Overrides the boundary ids
2696: - -bc_<boundary name>_comp <num> - Overrides the boundary components
2698: Level: developer
2700: .seealso: PetscDSAddBoundary()
2701: @*/
2702: PetscErrorCode PetscDSGetBoundary(PetscDS ds, PetscInt bd, DMBoundaryConditionType *type, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(void), PetscInt *numids, const PetscInt **ids, void **ctx)
2703: {
2704: DSBoundary b = ds->boundary;
2705: PetscInt n = 0;
2709: while (b) {
2710: if (n == bd) break;
2711: b = b->next;
2712: ++n;
2713: }
2714: if (!b) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %d is not in [0, %d)", bd, n);
2715: if (type) {
2717: *type = b->type;
2718: }
2719: if (name) {
2721: *name = b->name;
2722: }
2723: if (labelname) {
2725: *labelname = b->labelname;
2726: }
2727: if (field) {
2729: *field = b->field;
2730: }
2731: if (numcomps) {
2733: *numcomps = b->numcomps;
2734: }
2735: if (comps) {
2737: *comps = b->comps;
2738: }
2739: if (func) {
2741: *func = b->func;
2742: }
2743: if (numids) {
2745: *numids = b->numids;
2746: }
2747: if (ids) {
2749: *ids = b->ids;
2750: }
2751: if (ctx) {
2753: *ctx = b->ctx;
2754: }
2755: return(0);
2756: }
2758: PetscErrorCode PetscDSCopyBoundary(PetscDS probA, PetscDS probB)
2759: {
2760: DSBoundary b, next, *lastnext;
2766: if (probA == probB) return(0);
2767: next = probB->boundary;
2768: while (next) {
2769: DSBoundary b = next;
2771: next = b->next;
2772: PetscFree(b->comps);
2773: PetscFree(b->ids);
2774: PetscFree(b->name);
2775: PetscFree(b->labelname);
2776: PetscFree(b);
2777: }
2778: lastnext = &(probB->boundary);
2779: for (b = probA->boundary; b; b = b->next) {
2780: DSBoundary bNew;
2782: PetscNew(&bNew);
2783: bNew->numcomps = b->numcomps;
2784: PetscMalloc1(bNew->numcomps, &bNew->comps);
2785: PetscMemcpy(bNew->comps, b->comps, bNew->numcomps*sizeof(PetscInt));
2786: bNew->numids = b->numids;
2787: PetscMalloc1(bNew->numids, &bNew->ids);
2788: PetscMemcpy(bNew->ids, b->ids, bNew->numids*sizeof(PetscInt));
2789: PetscStrallocpy(b->labelname,(char **) &(bNew->labelname));
2790: PetscStrallocpy(b->name,(char **) &(bNew->name));
2791: bNew->ctx = b->ctx;
2792: bNew->type = b->type;
2793: bNew->field = b->field;
2794: bNew->func = b->func;
2796: *lastnext = bNew;
2797: lastnext = &(bNew->next);
2798: }
2799: return(0);
2800: }
2802: /*@
2803: PetscDSCopyEquations - Copy all pointwise function pointers to the new problem
2805: Not collective
2807: Input Parameter:
2808: . prob - The PetscDS object
2810: Output Parameter:
2811: . newprob - The PetscDS copy
2813: Level: intermediate
2815: .seealso: PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
2816: @*/
2817: PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
2818: {
2819: PetscInt Nf, Ng, f, g;
2825: PetscDSGetNumFields(prob, &Nf);
2826: PetscDSGetNumFields(newprob, &Ng);
2827: if (Nf != Ng) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %D != %D", Nf, Ng);
2828: for (f = 0; f < Nf; ++f) {
2829: PetscPointFunc obj;
2830: PetscPointFunc f0, f1;
2831: PetscPointJac g0, g1, g2, g3;
2832: PetscBdPointFunc f0Bd, f1Bd;
2833: PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
2834: PetscRiemannFunc r;
2836: PetscDSGetObjective(prob, f, &obj);
2837: PetscDSGetResidual(prob, f, &f0, &f1);
2838: PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd);
2839: PetscDSGetRiemannSolver(prob, f, &r);
2840: PetscDSSetObjective(newprob, f, obj);
2841: PetscDSSetResidual(newprob, f, f0, f1);
2842: PetscDSSetBdResidual(newprob, f, f0Bd, f1Bd);
2843: PetscDSSetRiemannSolver(newprob, f, r);
2844: for (g = 0; g < Nf; ++g) {
2845: PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3);
2846: PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd);
2847: PetscDSSetJacobian(newprob, f, g, g0, g1, g2, g3);
2848: PetscDSSetBdJacobian(newprob, f, g, g0Bd, g1Bd, g2Bd, g3Bd);
2849: }
2850: }
2851: return(0);
2852: }
2854: PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
2855: {
2856: PetscInt dim, Nf, f;
2862: if (height == 0) {*subprob = prob; return(0);}
2863: PetscDSGetNumFields(prob, &Nf);
2864: PetscDSGetSpatialDimension(prob, &dim);
2865: if (height > dim) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_OUTOFRANGE, "DS can only handle height in [0, %D], not %D", dim, height);
2866: if (!prob->subprobs) {PetscCalloc1(dim, &prob->subprobs);}
2867: if (!prob->subprobs[height-1]) {
2868: PetscInt cdim;
2870: PetscDSCreate(PetscObjectComm((PetscObject) prob), &prob->subprobs[height-1]);
2871: PetscDSGetCoordinateDimension(prob, &cdim);
2872: PetscDSSetCoordinateDimension(prob->subprobs[height-1], cdim);
2873: for (f = 0; f < Nf; ++f) {
2874: PetscFE subfe;
2875: PetscObject obj;
2876: PetscClassId id;
2878: PetscDSGetDiscretization(prob, f, &obj);
2879: PetscObjectGetClassId(obj, &id);
2880: if (id == PETSCFE_CLASSID) {PetscFEGetHeightSubspace((PetscFE) obj, height, &subfe);}
2881: else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %d", f);
2882: PetscDSSetDiscretization(prob->subprobs[height-1], f, (PetscObject) subfe);
2883: }
2884: }
2885: *subprob = prob->subprobs[height-1];
2886: return(0);
2887: }
2889: static PetscErrorCode PetscDSDestroy_Basic(PetscDS prob)
2890: {
2891: PetscErrorCode ierr;
2894: PetscFree(prob->data);
2895: return(0);
2896: }
2898: static PetscErrorCode PetscDSInitialize_Basic(PetscDS prob)
2899: {
2901: prob->ops->setfromoptions = NULL;
2902: prob->ops->setup = NULL;
2903: prob->ops->view = NULL;
2904: prob->ops->destroy = PetscDSDestroy_Basic;
2905: return(0);
2906: }
2908: /*MC
2909: PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
2911: Level: intermediate
2913: .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType()
2914: M*/
2916: PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS prob)
2917: {
2918: PetscDS_Basic *b;
2919: PetscErrorCode ierr;
2923: PetscNewLog(prob, &b);
2924: prob->data = b;
2926: PetscDSInitialize_Basic(prob);
2927: return(0);
2928: }