Actual source code: dtds.c

petsc-3.5.2 2014-09-08
Report Typos and Errors
  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: }