Actual source code: dtds.c
petsc-3.5.4 2015-05-23
1: #include <petsc-private/petscdsimpl.h> /*I "petscds.h" I*/
3: PetscClassId PETSCDS_CLASSID = 0;
5: PetscFunctionList PetscDSList = NULL;
6: PetscBool PetscDSRegisterAllCalled = PETSC_FALSE;
10: /*@C
11: PetscDSRegister - Adds a new PetscDS implementation
13: Not Collective
15: Input Parameters:
16: + name - The name of a new user-defined creation routine
17: - create_func - The creation routine itself
19: Notes:
20: PetscDSRegister() may be called multiple times to add several user-defined PetscDSs
22: Sample usage:
23: .vb
24: PetscDSRegister("my_ds", MyPetscDSCreate);
25: .ve
27: Then, your PetscDS type can be chosen with the procedural interface via
28: .vb
29: PetscDSCreate(MPI_Comm, PetscDS *);
30: PetscDSSetType(PetscDS, "my_ds");
31: .ve
32: or at runtime via the option
33: .vb
34: -petscds_type my_ds
35: .ve
37: Level: advanced
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: }
54: /*@C
55: PetscDSSetType - Builds a particular PetscDS
57: Collective on PetscDS
59: Input Parameters:
60: + prob - The PetscDS object
61: - name - The kind of system
63: Options Database Key:
64: . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
66: Level: intermediate
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: if (!PetscDSRegisterAllCalled) {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: }
97: /*@C
98: PetscDSGetType - Gets the PetscDS type name (as a string) from the object.
100: Not Collective
102: Input Parameter:
103: . prob - The PetscDS
105: Output Parameter:
106: . name - The PetscDS type name
108: Level: intermediate
110: .keywords: PetscDS, get, type, name
111: .seealso: PetscDSSetType(), PetscDSCreate()
112: @*/
113: PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
114: {
120: if (!PetscDSRegisterAllCalled) {PetscDSRegisterAll();}
121: *name = ((PetscObject) prob)->type_name;
122: return(0);
123: }
127: /*@C
128: PetscDSView - Views a PetscDS
130: Collective on PetscDS
132: Input Parameter:
133: + prob - the PetscDS object to view
134: - v - the viewer
136: Level: developer
138: .seealso PetscDSDestroy()
139: @*/
140: PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
141: {
146: if (!v) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);}
147: if (prob->ops->view) {(*prob->ops->view)(prob, v);}
148: return(0);
149: }
153: /*
154: PetscDSViewFromOptions - Processes command line options to determine if/how a PetscDS is to be viewed.
156: Collective on PetscDS
158: Input Parameters:
159: + prob - the PetscDS
160: . prefix - prefix to use for viewing, or NULL to use prefix of 'rnd'
161: - optionname - option to activate viewing
163: Level: intermediate
165: .keywords: PetscDS, view, options, database
166: .seealso: VecViewFromOptions(), MatViewFromOptions()
167: */
168: PetscErrorCode PetscDSViewFromOptions(PetscDS prob, const char prefix[], const char optionname[])
169: {
170: PetscViewer viewer;
171: PetscViewerFormat format;
172: PetscBool flg;
173: PetscErrorCode ierr;
176: if (prefix) {PetscOptionsGetViewer(PetscObjectComm((PetscObject) prob), prefix, optionname, &viewer, &format, &flg);}
177: else {PetscOptionsGetViewer(PetscObjectComm((PetscObject) prob), ((PetscObject) prob)->prefix, optionname, &viewer, &format, &flg);}
178: if (flg) {
179: PetscViewerPushFormat(viewer, format);
180: PetscDSView(prob, viewer);
181: PetscViewerPopFormat(viewer);
182: PetscViewerDestroy(&viewer);
183: }
184: return(0);
185: }
189: /*@
190: PetscDSSetFromOptions - sets parameters in a PetscDS from the options database
192: Collective on PetscDS
194: Input Parameter:
195: . prob - the PetscDS object to set options for
197: Options Database:
199: Level: developer
201: .seealso PetscDSView()
202: @*/
203: PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
204: {
205: const char *defaultType;
206: char name[256];
207: PetscBool flg;
212: if (!((PetscObject) prob)->type_name) {
213: defaultType = PETSCDSBASIC;
214: } else {
215: defaultType = ((PetscObject) prob)->type_name;
216: }
217: if (!PetscDSRegisterAllCalled) {PetscDSRegisterAll();}
219: PetscObjectOptionsBegin((PetscObject) prob);
220: PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);
221: if (flg) {
222: PetscDSSetType(prob, name);
223: } else if (!((PetscObject) prob)->type_name) {
224: PetscDSSetType(prob, defaultType);
225: }
226: if (prob->ops->setfromoptions) {(*prob->ops->setfromoptions)(prob);}
227: /* process any options handlers added with PetscObjectAddOptionsHandler() */
228: PetscObjectProcessOptionsHandlers((PetscObject) prob);
229: PetscOptionsEnd();
230: PetscDSViewFromOptions(prob, NULL, "-petscds_view");
231: return(0);
232: }
236: /*@C
237: PetscDSSetUp - Construct data structures for the PetscDS
239: Collective on PetscDS
241: Input Parameter:
242: . prob - the PetscDS object to setup
244: Level: developer
246: .seealso PetscDSView(), PetscDSDestroy()
247: @*/
248: PetscErrorCode PetscDSSetUp(PetscDS prob)
249: {
250: const PetscInt Nf = prob->Nf;
251: PetscInt dim, work, NcMax = 0, NqMax = 0, f;
256: if (prob->setup) return(0);
257: /* Calculate sizes */
258: PetscDSGetSpatialDimension(prob, &dim);
259: prob->totDim = prob->totDimBd = prob->totComp = 0;
260: PetscMalloc4(Nf,&prob->basis,Nf,&prob->basisDer,Nf,&prob->basisBd,Nf,&prob->basisDerBd);
261: for (f = 0; f < Nf; ++f) {
262: PetscFE fe = (PetscFE) prob->disc[f];
263: PetscFE feBd = (PetscFE) prob->discBd[f];
264: PetscQuadrature q;
265: PetscInt Nq, Nb, Nc;
267: /* TODO Dispatch on discretization type*/
268: PetscFEGetQuadrature(fe, &q);
269: PetscQuadratureGetData(q, NULL, &Nq, NULL, NULL);
270: PetscFEGetDimension(fe, &Nb);
271: PetscFEGetNumComponents(fe, &Nc);
272: PetscFEGetDefaultTabulation(fe, &prob->basis[f], &prob->basisDer[f], NULL);
273: NqMax = PetscMax(NqMax, Nq);
274: NcMax = PetscMax(NcMax, Nc);
275: prob->totDim += Nb*Nc;
276: prob->totComp += Nc;
277: if (feBd) {
278: PetscFEGetDimension(feBd, &Nb);
279: PetscFEGetNumComponents(feBd, &Nc);
280: PetscFEGetDefaultTabulation(feBd, &prob->basisBd[f], &prob->basisDerBd[f], NULL);
281: prob->totDimBd += Nb*Nc;
282: }
283: }
284: work = PetscMax(prob->totComp*dim, PetscSqr(NcMax*dim));
285: /* Allocate works space */
286: PetscMalloc5(prob->totComp,&prob->u,prob->totComp,&prob->u_t,prob->totComp*dim,&prob->u_x,dim,&prob->x,work,&prob->refSpaceDer);
287: 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);
288: if (prob->ops->setup) {(*prob->ops->setup)(prob);}
289: prob->setup = PETSC_TRUE;
290: return(0);
291: }
295: static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
296: {
300: PetscFree4(prob->basis,prob->basisDer,prob->basisBd,prob->basisDerBd);
301: PetscFree5(prob->u,prob->u_t,prob->u_x,prob->x,prob->refSpaceDer);
302: PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);
303: return(0);
304: }
308: static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
309: {
310: PetscObject *tmpd, *tmpdbd;
311: PointFunc *tmpobj, *tmpf, *tmpg;
312: BdPointFunc *tmpfbd, *tmpgbd;
313: PetscInt Nf = prob->Nf, f;
317: if (Nf >= NfNew) return(0);
318: prob->setup = PETSC_FALSE;
319: PetscDSDestroyStructs_Static(prob);
320: PetscMalloc1(NfNew, &tmpd);
321: for (f = 0; f < Nf; ++f) tmpd[f] = prob->disc[f];
322: for (f = Nf; f < NfNew; ++f) {PetscContainerCreate(PetscObjectComm((PetscObject) prob), (PetscContainer *) &tmpd[f]);}
323: PetscFree(prob->disc);
324: prob->Nf = NfNew;
325: prob->disc = tmpd;
326: PetscCalloc3(NfNew, &tmpobj, NfNew*2, &tmpf, NfNew*NfNew*4, &tmpg);
327: for (f = 0; f < Nf; ++f) tmpobj[f] = prob->obj[f];
328: for (f = 0; f < Nf*2; ++f) tmpf[f] = prob->f[f];
329: for (f = 0; f < Nf*Nf*4; ++f) tmpg[f] = prob->g[f];
330: for (f = Nf; f < NfNew; ++f) tmpobj[f] = NULL;
331: for (f = Nf*2; f < NfNew*2; ++f) tmpf[f] = NULL;
332: for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpg[f] = NULL;
333: PetscFree3(prob->obj, prob->f, prob->g);
334: prob->obj = tmpobj;
335: prob->f = tmpf;
336: prob->g = tmpg;
337: PetscMalloc1(NfNew, &tmpdbd);
338: for (f = 0; f < Nf; ++f) tmpdbd[f] = prob->discBd[f];
339: for (f = Nf; f < NfNew; ++f) tmpdbd[f] = NULL;
340: PetscFree(prob->discBd);
341: prob->discBd = tmpdbd;
342: PetscCalloc2(NfNew*2, &tmpfbd, NfNew*NfNew*4, &tmpgbd);
343: for (f = 0; f < Nf*2; ++f) tmpfbd[f] = prob->fBd[f];
344: for (f = 0; f < Nf*Nf*4; ++f) tmpgbd[f] = prob->gBd[f];
345: for (f = Nf*2; f < NfNew*2; ++f) tmpfbd[f] = NULL;
346: for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgbd[f] = NULL;
347: PetscFree2(prob->fBd, prob->gBd);
348: prob->fBd = tmpfbd;
349: prob->gBd = tmpgbd;
350: return(0);
351: }
355: /*@
356: PetscDSDestroy - Destroys a PetscDS object
358: Collective on PetscDS
360: Input Parameter:
361: . prob - the PetscDS object to destroy
363: Level: developer
365: .seealso PetscDSView()
366: @*/
367: PetscErrorCode PetscDSDestroy(PetscDS *prob)
368: {
369: PetscInt f;
373: if (!*prob) return(0);
376: if (--((PetscObject)(*prob))->refct > 0) {*prob = 0; return(0);}
377: ((PetscObject) (*prob))->refct = 0;
378: PetscDSDestroyStructs_Static(*prob);
379: for (f = 0; f < (*prob)->Nf; ++f) {
380: PetscObjectDereference((*prob)->disc[f]);
381: PetscObjectDereference((*prob)->discBd[f]);
382: }
383: PetscFree((*prob)->disc);
384: PetscFree((*prob)->discBd);
385: PetscFree3((*prob)->obj,(*prob)->f,(*prob)->g);
386: PetscFree2((*prob)->fBd,(*prob)->gBd);
387: if ((*prob)->ops->destroy) {(*(*prob)->ops->destroy)(*prob);}
388: PetscHeaderDestroy(prob);
389: return(0);
390: }
394: /*@
395: PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType().
397: Collective on MPI_Comm
399: Input Parameter:
400: . comm - The communicator for the PetscDS object
402: Output Parameter:
403: . prob - The PetscDS object
405: Level: beginner
407: .seealso: PetscDSSetType(), PETSCDSBASIC
408: @*/
409: PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *prob)
410: {
411: PetscDS p;
416: *prob = NULL;
417: PetscDSInitializePackage();
419: PetscHeaderCreate(p, _p_PetscDS, struct _PetscDSOps, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);
420: PetscMemzero(p->ops, sizeof(struct _PetscDSOps));
422: p->Nf = 0;
423: p->setup = PETSC_FALSE;
425: *prob = p;
426: return(0);
427: }
431: PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
432: {
436: *Nf = prob->Nf;
437: return(0);
438: }
442: PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
443: {
449: *dim = 0;
450: if (prob->Nf) {PetscFEGetSpatialDimension((PetscFE) prob->disc[0], dim);}
451: return(0);
452: }
456: PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
457: {
462: PetscDSSetUp(prob);
464: *dim = prob->totDim;
465: return(0);
466: }
470: PetscErrorCode PetscDSGetTotalBdDimension(PetscDS prob, PetscInt *dim)
471: {
476: PetscDSSetUp(prob);
478: *dim = prob->totDimBd;
479: return(0);
480: }
484: PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
485: {
490: PetscDSSetUp(prob);
492: *Nc = prob->totComp;
493: return(0);
494: }
498: PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
499: {
503: 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);
504: *disc = prob->disc[f];
505: return(0);
506: }
510: PetscErrorCode PetscDSGetBdDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
511: {
515: 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);
516: *disc = prob->discBd[f];
517: return(0);
518: }
522: PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
523: {
529: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
530: PetscDSEnlarge_Static(prob, f+1);
531: if (prob->disc[f]) {PetscObjectDereference(prob->disc[f]);}
532: prob->disc[f] = disc;
533: PetscObjectReference(disc);
534: return(0);
535: }
539: PetscErrorCode PetscDSSetBdDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
540: {
546: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
547: PetscDSEnlarge_Static(prob, f+1);
548: if (prob->discBd[f]) {PetscObjectDereference(prob->discBd[f]);}
549: prob->discBd[f] = disc;
550: PetscObjectReference(disc);
551: return(0);
552: }
556: PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
557: {
561: PetscDSSetDiscretization(prob, prob->Nf, disc);
562: return(0);
563: }
567: PetscErrorCode PetscDSAddBdDiscretization(PetscDS prob, PetscObject disc)
568: {
572: PetscDSSetBdDiscretization(prob, prob->Nf, disc);
573: return(0);
574: }
578: PetscErrorCode PetscDSGetObjective(PetscDS prob, PetscInt f,
579: void (**obj)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar obj[]))
580: {
584: 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);
585: *obj = prob->obj[f];
586: return(0);
587: }
591: PetscErrorCode PetscDSSetObjective(PetscDS prob, PetscInt f,
592: void (*obj)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar obj[]))
593: {
599: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
600: PetscDSEnlarge_Static(prob, f+1);
601: prob->obj[f] = obj;
602: return(0);
603: }
607: PetscErrorCode PetscDSGetResidual(PetscDS prob, PetscInt f,
608: void (**f0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar f0[]),
609: void (**f1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar f1[]))
610: {
613: 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);
616: return(0);
617: }
621: PetscErrorCode PetscDSSetResidual(PetscDS prob, PetscInt f,
622: void (*f0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar f0[]),
623: void (*f1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar f1[]))
624: {
631: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
632: PetscDSEnlarge_Static(prob, f+1);
633: prob->f[f*2+0] = f0;
634: prob->f[f*2+1] = f1;
635: return(0);
636: }
640: PetscErrorCode PetscDSGetJacobian(PetscDS prob, PetscInt f, PetscInt g,
641: void (**g0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g0[]),
642: void (**g1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g1[]),
643: void (**g2)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g2[]),
644: void (**g3)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g3[]))
645: {
648: 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);
649: 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);
654: return(0);
655: }
659: PetscErrorCode PetscDSSetJacobian(PetscDS prob, PetscInt f, PetscInt g,
660: void (*g0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g0[]),
661: void (*g1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g1[]),
662: void (*g2)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g2[]),
663: void (*g3)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], PetscScalar g3[]))
664: {
673: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
674: if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
675: PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
676: prob->g[(f*prob->Nf + g)*4+0] = g0;
677: prob->g[(f*prob->Nf + g)*4+1] = g1;
678: prob->g[(f*prob->Nf + g)*4+2] = g2;
679: prob->g[(f*prob->Nf + g)*4+3] = g3;
680: return(0);
681: }
685: PetscErrorCode PetscDSGetBdResidual(PetscDS prob, PetscInt f,
686: void (**f0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar f0[]),
687: void (**f1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar f1[]))
688: {
691: 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);
694: return(0);
695: }
699: PetscErrorCode PetscDSSetBdResidual(PetscDS prob, PetscInt f,
700: void (*f0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar f0[]),
701: void (*f1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar f1[]))
702: {
707: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
708: PetscDSEnlarge_Static(prob, f+1);
711: return(0);
712: }
716: PetscErrorCode PetscDSGetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
717: void (**g0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g0[]),
718: void (**g1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g1[]),
719: void (**g2)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g2[]),
720: void (**g3)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g3[]))
721: {
724: 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);
725: 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);
730: return(0);
731: }
735: PetscErrorCode PetscDSSetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
736: void (*g0)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g0[]),
737: void (*g1)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g1[]),
738: void (*g2)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g2[]),
739: void (*g3)(const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], const PetscReal x[], const PetscReal n[], PetscScalar g3[]))
740: {
749: if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
750: if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
751: PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
752: prob->gBd[(f*prob->Nf + g)*4+0] = g0;
753: prob->gBd[(f*prob->Nf + g)*4+1] = g1;
754: prob->gBd[(f*prob->Nf + g)*4+2] = g2;
755: prob->gBd[(f*prob->Nf + g)*4+3] = g3;
756: return(0);
757: }
761: PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
762: {
763: PetscInt g;
769: 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);
770: *off = 0;
771: for (g = 0; g < f; ++g) {
772: PetscFE fe = (PetscFE) prob->disc[g];
773: PetscInt Nb, Nc;
775: PetscFEGetDimension(fe, &Nb);
776: PetscFEGetNumComponents(fe, &Nc);
777: *off += Nb*Nc;
778: }
779: return(0);
780: }
784: PetscErrorCode PetscDSGetBdFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
785: {
786: PetscInt g;
792: 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);
793: *off = 0;
794: for (g = 0; g < f; ++g) {
795: PetscFE fe = (PetscFE) prob->discBd[g];
796: PetscInt Nb, Nc;
798: PetscFEGetDimension(fe, &Nb);
799: PetscFEGetNumComponents(fe, &Nc);
800: *off += Nb*Nc;
801: }
802: return(0);
803: }
807: PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer)
808: {
813: PetscDSSetUp(prob);
816: return(0);
817: }
821: PetscErrorCode PetscDSGetBdTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer)
822: {
827: PetscDSSetUp(prob);
830: return(0);
831: }
835: PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
836: {
841: PetscDSSetUp(prob);
845: return(0);
846: }
850: PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
851: {
856: PetscDSSetUp(prob);
863: return(0);
864: }
868: PetscErrorCode PetscDSGetRefCoordArrays(PetscDS prob, PetscReal **x, PetscScalar **refSpaceDer)
869: {
874: PetscDSSetUp(prob);
877: return(0);
878: }
882: PetscErrorCode PetscDSDestroy_Basic(PetscDS prob)
883: {
885: return(0);
886: }
890: PetscErrorCode PetscDSInitialize_Basic(PetscDS prob)
891: {
893: prob->ops->setfromoptions = NULL;
894: prob->ops->setup = NULL;
895: prob->ops->view = NULL;
896: prob->ops->destroy = PetscDSDestroy_Basic;
897: return(0);
898: }
900: /*MC
901: PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
903: Level: intermediate
905: .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType()
906: M*/
910: PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS prob)
911: {
912: PetscDS_Basic *b;
913: PetscErrorCode ierr;
917: PetscNewLog(prob, &b);
918: prob->data = b;
920: PetscDSInitialize_Basic(prob);
921: return(0);
922: }