Actual source code: dtds.c

petsc-3.6.4 2016-04-12
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:   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:   PetscDSRegisterAll();
121:   *name = ((PetscObject) prob)->type_name;
122:   return(0);
123: }

127: static PetscErrorCode PetscDSView_Ascii(PetscDS prob, PetscViewer viewer)
128: {
129:   PetscViewerFormat format;
130:   PetscInt          f;
131:   PetscErrorCode    ierr;

134:   PetscViewerGetFormat(viewer, &format);
135:   PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", prob->Nf);
136:   PetscViewerASCIIPushTab(viewer);
137:   for (f = 0; f < prob->Nf; ++f) {
138:     PetscObject  obj;
139:     PetscClassId id;
140:     const char  *name;
141:     PetscInt     Nc;

143:     PetscDSGetDiscretization(prob, f, &obj);
144:     PetscObjectGetClassId(obj, &id);
145:     PetscObjectGetName(obj, &name);
146:     PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");
147:     if (id == PETSCFE_CLASSID)      {
148:       PetscFEGetNumComponents((PetscFE) obj, &Nc);
149:       PetscViewerASCIIPrintf(viewer, " FEM");
150:     } else if (id == PETSCFV_CLASSID) {
151:       PetscFVGetNumComponents((PetscFV) obj, &Nc);
152:       PetscViewerASCIIPrintf(viewer, " FVM");
153:     }
154:     else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
155:     if (Nc > 1) {PetscViewerASCIIPrintf(viewer, "%d components", Nc);}
156:     else        {PetscViewerASCIIPrintf(viewer, "%d component ", Nc);}
157:     if (prob->implicit[f]) {PetscViewerASCIIPrintf(viewer, " (implicit)");}
158:     else                   {PetscViewerASCIIPrintf(viewer, " (explicit)");}
159:     if (prob->adjacency[f*2+0]) {
160:       if (prob->adjacency[f*2+1]) {PetscViewerASCIIPrintf(viewer, " (adj FVM++)");}
161:       else                        {PetscViewerASCIIPrintf(viewer, " (adj FVM)");}
162:     } else {
163:       if (prob->adjacency[f*2+1]) {PetscViewerASCIIPrintf(viewer, " (adj FEM)");}
164:       else                        {PetscViewerASCIIPrintf(viewer, " (adj FUNKY)");}
165:     }
166:     PetscViewerASCIIPrintf(viewer, "\n");
167:     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
168:       if (id == PETSCFE_CLASSID)      {PetscFEView((PetscFE) obj, viewer);}
169:       else if (id == PETSCFV_CLASSID) {PetscFVView((PetscFV) obj, viewer);}
170:     }
171:   }
172:   PetscViewerASCIIPopTab(viewer);
173:   return(0);
174: }

178: /*@C
179:   PetscDSView - Views a PetscDS

181:   Collective on PetscDS

183:   Input Parameter:
184: + prob - the PetscDS object to view
185: - v  - the viewer

187:   Level: developer

189: .seealso PetscDSDestroy()
190: @*/
191: PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
192: {
193:   PetscBool      iascii;

198:   if (!v) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);}
200:   PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
201:   if (iascii) {PetscDSView_Ascii(prob, v);}
202:   if (prob->ops->view) {(*prob->ops->view)(prob, v);}
203:   return(0);
204: }

208: /*@
209:   PetscDSSetFromOptions - sets parameters in a PetscDS from the options database

211:   Collective on PetscDS

213:   Input Parameter:
214: . prob - the PetscDS object to set options for

216:   Options Database:

218:   Level: developer

220: .seealso PetscDSView()
221: @*/
222: PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
223: {
224:   const char    *defaultType;
225:   char           name[256];
226:   PetscBool      flg;

231:   if (!((PetscObject) prob)->type_name) {
232:     defaultType = PETSCDSBASIC;
233:   } else {
234:     defaultType = ((PetscObject) prob)->type_name;
235:   }
236:   PetscDSRegisterAll();

238:   PetscObjectOptionsBegin((PetscObject) prob);
239:   PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);
240:   if (flg) {
241:     PetscDSSetType(prob, name);
242:   } else if (!((PetscObject) prob)->type_name) {
243:     PetscDSSetType(prob, defaultType);
244:   }
245:   if (prob->ops->setfromoptions) {(*prob->ops->setfromoptions)(prob);}
246:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
247:   PetscObjectProcessOptionsHandlers((PetscObject) prob);
248:   PetscOptionsEnd();
249:   PetscDSViewFromOptions(prob, NULL, "-petscds_view");
250:   return(0);
251: }

255: /*@C
256:   PetscDSSetUp - Construct data structures for the PetscDS

258:   Collective on PetscDS

260:   Input Parameter:
261: . prob - the PetscDS object to setup

263:   Level: developer

265: .seealso PetscDSView(), PetscDSDestroy()
266: @*/
267: PetscErrorCode PetscDSSetUp(PetscDS prob)
268: {
269:   const PetscInt Nf = prob->Nf;
270:   PetscInt       dim, work, NcMax = 0, NqMax = 0, f;

275:   if (prob->setup) return(0);
276:   /* Calculate sizes */
277:   PetscDSGetSpatialDimension(prob, &dim);
278:   prob->totDim = prob->totDimBd = prob->totComp = 0;
279:   PetscCalloc4(Nf+1,&prob->off,Nf+1,&prob->offDer,Nf+1,&prob->offBd,Nf+1,&prob->offDerBd);
280:   PetscMalloc4(Nf,&prob->basis,Nf,&prob->basisDer,Nf,&prob->basisBd,Nf,&prob->basisDerBd);
281:   for (f = 0; f < Nf; ++f) {
282:     PetscFE         feBd = (PetscFE) prob->discBd[f];
283:     PetscObject     obj;
284:     PetscClassId    id;
285:     PetscQuadrature q;
286:     PetscInt        Nq = 0, Nb, Nc;

288:     PetscDSGetDiscretization(prob, f, &obj);
289:     PetscObjectGetClassId(obj, &id);
290:     if (id == PETSCFE_CLASSID)      {
291:       PetscFE fe = (PetscFE) obj;

293:       PetscFEGetQuadrature(fe, &q);
294:       PetscFEGetDimension(fe, &Nb);
295:       PetscFEGetNumComponents(fe, &Nc);
296:       PetscFEGetDefaultTabulation(fe, &prob->basis[f], &prob->basisDer[f], NULL);
297:     } else if (id == PETSCFV_CLASSID) {
298:       PetscFV fv = (PetscFV) obj;

300:       PetscFVGetQuadrature(fv, &q);
301:       Nb   = 1;
302:       PetscFVGetNumComponents(fv, &Nc);
303:       PetscFVGetDefaultTabulation(fv, &prob->basis[f], &prob->basisDer[f], NULL);
304:     } else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
305:     prob->off[f+1]    = Nc     + prob->off[f];
306:     prob->offDer[f+1] = Nc*dim + prob->offDer[f];
307:     if (q) {PetscQuadratureGetData(q, NULL, &Nq, NULL, NULL);}
308:     NqMax          = PetscMax(NqMax, Nq);
309:     NcMax          = PetscMax(NcMax, Nc);
310:     prob->totDim  += Nb*Nc;
311:     prob->totComp += Nc;
312:     if (feBd) {
313:       PetscFEGetDimension(feBd, &Nb);
314:       PetscFEGetNumComponents(feBd, &Nc);
315:       PetscFEGetDefaultTabulation(feBd, &prob->basisBd[f], &prob->basisDerBd[f], NULL);
316:       prob->totDimBd += Nb*Nc;
317:       prob->offBd[f+1]    = Nc     + prob->offBd[f];
318:       prob->offDerBd[f+1] = Nc*dim + prob->offDerBd[f];
319:     }
320:   }
321:   work = PetscMax(prob->totComp*dim, PetscSqr(NcMax*dim));
322:   /* Allocate works space */
323:   PetscMalloc5(prob->totComp,&prob->u,prob->totComp,&prob->u_t,prob->totComp*dim,&prob->u_x,dim,&prob->x,work,&prob->refSpaceDer);
324:   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);
325:   if (prob->ops->setup) {(*prob->ops->setup)(prob);}
326:   prob->setup = PETSC_TRUE;
327:   return(0);
328: }

332: static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
333: {

337:   PetscFree4(prob->off,prob->offDer,prob->offBd,prob->offDerBd);
338:   PetscFree4(prob->basis,prob->basisDer,prob->basisBd,prob->basisDerBd);
339:   PetscFree5(prob->u,prob->u_t,prob->u_x,prob->x,prob->refSpaceDer);
340:   PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);
341:   return(0);
342: }

346: static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
347: {
348:   PetscObject      *tmpd, *tmpdbd;
349:   PetscBool        *tmpi, *tmpa;
350:   PetscPointFunc   *tmpobj, *tmpf;
351:   PetscPointJac    *tmpg;
352:   PetscBdPointFunc *tmpfbd;
353:   PetscBdPointJac  *tmpgbd;
354:   PetscRiemannFunc *tmpr;
355:   void            **tmpctx;
356:   PetscInt          Nf = prob->Nf, f, i;
357:   PetscErrorCode    ierr;

360:   if (Nf >= NfNew) return(0);
361:   prob->setup = PETSC_FALSE;
362:   PetscDSDestroyStructs_Static(prob);
363:   PetscMalloc4(NfNew, &tmpd, NfNew, &tmpdbd, NfNew, &tmpi, NfNew*2, &tmpa);
364:   for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpdbd[f] = prob->discBd[f]; tmpi[f] = prob->implicit[f]; for (i = 0; i < 2; ++i) tmpa[f*2+i] = prob->adjacency[f*2+i];}
365:   for (f = Nf; f < NfNew; ++f) {PetscContainerCreate(PetscObjectComm((PetscObject) prob), (PetscContainer *) &tmpd[f]);
366:     tmpdbd[f] = NULL; tmpi[f] = PETSC_TRUE; tmpa[f*2+0] = PETSC_FALSE; tmpa[f*2+1] = PETSC_TRUE;}
367:   PetscFree4(prob->disc, prob->discBd, prob->implicit, prob->adjacency);
368:   prob->Nf        = NfNew;
369:   prob->disc      = tmpd;
370:   prob->discBd    = tmpdbd;
371:   prob->implicit  = tmpi;
372:   prob->adjacency = tmpa;
373:   PetscCalloc5(NfNew, &tmpobj, NfNew*2, &tmpf, NfNew*NfNew*4, &tmpg, NfNew, &tmpr, NfNew, &tmpctx);
374:   for (f = 0; f < Nf; ++f) tmpobj[f] = prob->obj[f];
375:   for (f = 0; f < Nf*2; ++f) tmpf[f] = prob->f[f];
376:   for (f = 0; f < Nf*Nf*4; ++f) tmpg[f] = prob->g[f];
377:   for (f = 0; f < Nf; ++f) tmpr[f] = prob->r[f];
378:   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
379:   for (f = Nf; f < NfNew; ++f) tmpobj[f] = NULL;
380:   for (f = Nf*2; f < NfNew*2; ++f) tmpf[f] = NULL;
381:   for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpg[f] = NULL;
382:   for (f = Nf; f < NfNew; ++f) tmpr[f] = NULL;
383:   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
384:   PetscFree5(prob->obj, prob->f, prob->g, prob->r, prob->ctx);
385:   prob->obj = tmpobj;
386:   prob->f   = tmpf;
387:   prob->g   = tmpg;
388:   prob->r   = tmpr;
389:   prob->ctx = tmpctx;
390:   PetscCalloc2(NfNew*2, &tmpfbd, NfNew*NfNew*4, &tmpgbd);
391:   for (f = 0; f < Nf*2; ++f) tmpfbd[f] = prob->fBd[f];
392:   for (f = 0; f < Nf*Nf*4; ++f) tmpgbd[f] = prob->gBd[f];
393:   for (f = Nf*2; f < NfNew*2; ++f) tmpfbd[f] = NULL;
394:   for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgbd[f] = NULL;
395:   PetscFree2(prob->fBd, prob->gBd);
396:   prob->fBd = tmpfbd;
397:   prob->gBd = tmpgbd;
398:   return(0);
399: }

403: /*@
404:   PetscDSDestroy - Destroys a PetscDS object

406:   Collective on PetscDS

408:   Input Parameter:
409: . prob - the PetscDS object to destroy

411:   Level: developer

413: .seealso PetscDSView()
414: @*/
415: PetscErrorCode PetscDSDestroy(PetscDS *prob)
416: {
417:   PetscInt       f;

421:   if (!*prob) return(0);

424:   if (--((PetscObject)(*prob))->refct > 0) {*prob = 0; return(0);}
425:   ((PetscObject) (*prob))->refct = 0;
426:   PetscDSDestroyStructs_Static(*prob);
427:   for (f = 0; f < (*prob)->Nf; ++f) {
428:     PetscObjectDereference((*prob)->disc[f]);
429:     PetscObjectDereference((*prob)->discBd[f]);
430:   }
431:   PetscFree4((*prob)->disc, (*prob)->discBd, (*prob)->implicit, (*prob)->adjacency);
432:   PetscFree5((*prob)->obj,(*prob)->f,(*prob)->g,(*prob)->r,(*prob)->ctx);
433:   PetscFree2((*prob)->fBd,(*prob)->gBd);
434:   if ((*prob)->ops->destroy) {(*(*prob)->ops->destroy)(*prob);}
435:   PetscHeaderDestroy(prob);
436:   return(0);
437: }

441: /*@
442:   PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType().

444:   Collective on MPI_Comm

446:   Input Parameter:
447: . comm - The communicator for the PetscDS object

449:   Output Parameter:
450: . prob - The PetscDS object

452:   Level: beginner

454: .seealso: PetscDSSetType(), PETSCDSBASIC
455: @*/
456: PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *prob)
457: {
458:   PetscDS   p;

463:   *prob  = NULL;
464:   PetscDSInitializePackage();

466:   PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);

468:   p->Nf    = 0;
469:   p->setup = PETSC_FALSE;

471:   *prob = p;
472:   return(0);
473: }

477: /*@
478:   PetscDSGetNumFields - Returns the number of fields in the DS

480:   Not collective

482:   Input Parameter:
483: . prob - The PetscDS object

485:   Output Parameter:
486: . Nf - The number of fields

488:   Level: beginner

490: .seealso: PetscDSGetSpatialDimension(), PetscDSCreate()
491: @*/
492: PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
493: {
497:   *Nf = prob->Nf;
498:   return(0);
499: }

503: /*@
504:   PetscDSGetSpatialDimension - Returns the spatial dimension of the DS

506:   Not collective

508:   Input Parameter:
509: . prob - The PetscDS object

511:   Output Parameter:
512: . dim - The spatial dimension

514:   Level: beginner

516: .seealso: PetscDSGetNumFields(), PetscDSCreate()
517: @*/
518: PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
519: {

525:   *dim = 0;
526:   if (prob->Nf) {
527:     PetscObject  obj;
528:     PetscClassId id;

530:     PetscDSGetDiscretization(prob, 0, &obj);
531:     PetscObjectGetClassId(obj, &id);
532:     if (id == PETSCFE_CLASSID)      {PetscFEGetSpatialDimension((PetscFE) obj, dim);}
533:     else if (id == PETSCFV_CLASSID) {PetscFVGetSpatialDimension((PetscFV) obj, dim);}
534:     else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
535:   }
536:   return(0);
537: }

541: /*@
542:   PetscDSGetTotalDimension - Returns the total size of the approximation space for this system

544:   Not collective

546:   Input Parameter:
547: . prob - The PetscDS object

549:   Output Parameter:
550: . dim - The total problem dimension

552:   Level: beginner

554: .seealso: PetscDSGetNumFields(), PetscDSCreate()
555: @*/
556: PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
557: {

562:   PetscDSSetUp(prob);
564:   *dim = prob->totDim;
565:   return(0);
566: }

570: /*@
571:   PetscDSGetTotalBdDimension - Returns the total size of the boundary approximation space for this system

573:   Not collective

575:   Input Parameter:
576: . prob - The PetscDS object

578:   Output Parameter:
579: . dim - The total boundary problem dimension

581:   Level: beginner

583: .seealso: PetscDSGetNumFields(), PetscDSCreate()
584: @*/
585: PetscErrorCode PetscDSGetTotalBdDimension(PetscDS prob, PetscInt *dim)
586: {

591:   PetscDSSetUp(prob);
593:   *dim = prob->totDimBd;
594:   return(0);
595: }

599: /*@
600:   PetscDSGetTotalComponents - Returns the total number of components in this system

602:   Not collective

604:   Input Parameter:
605: . prob - The PetscDS object

607:   Output Parameter:
608: . dim - The total number of components

610:   Level: beginner

612: .seealso: PetscDSGetNumFields(), PetscDSCreate()
613: @*/
614: PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
615: {

620:   PetscDSSetUp(prob);
622:   *Nc = prob->totComp;
623:   return(0);
624: }

628: /*@
629:   PetscDSGetDiscretization - Returns the discretization object for the given field

631:   Not collective

633:   Input Parameters:
634: + prob - The PetscDS object
635: - f - The field number

637:   Output Parameter:
638: . disc - The discretization object

640:   Level: beginner

642: .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
643: @*/
644: PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
645: {
649:   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);
650:   *disc = prob->disc[f];
651:   return(0);
652: }

656: /*@
657:   PetscDSGetBdDiscretization - Returns the boundary discretization object for the given field

659:   Not collective

661:   Input Parameters:
662: + prob - The PetscDS object
663: - f - The field number

665:   Output Parameter:
666: . disc - The boundary discretization object

668:   Level: beginner

670: .seealso: PetscDSSetBdDiscretization(), PetscDSAddBdDiscretization(), PetscDSGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
671: @*/
672: PetscErrorCode PetscDSGetBdDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
673: {
677:   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);
678:   *disc = prob->discBd[f];
679:   return(0);
680: }

684: /*@
685:   PetscDSSetDiscretization - Sets the discretization object for the given field

687:   Not collective

689:   Input Parameters:
690: + prob - The PetscDS object
691: . f - The field number
692: - disc - The discretization object

694:   Level: beginner

696: .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
697: @*/
698: PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
699: {

705:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
706:   PetscDSEnlarge_Static(prob, f+1);
707:   if (prob->disc[f]) {PetscObjectDereference(prob->disc[f]);}
708:   prob->disc[f] = disc;
709:   PetscObjectReference(disc);
710:   {
711:     PetscClassId id;

713:     PetscObjectGetClassId(disc, &id);
714:     if (id == PETSCFV_CLASSID) {
715:       prob->implicit[f]      = PETSC_FALSE;
716:       prob->adjacency[f*2+0] = PETSC_TRUE;
717:       prob->adjacency[f*2+1] = PETSC_FALSE;
718:     }
719:   }
720:   return(0);
721: }

725: /*@
726:   PetscDSSetBdDiscretization - Sets the boundary discretization object for the given field

728:   Not collective

730:   Input Parameters:
731: + prob - The PetscDS object
732: . f - The field number
733: - disc - The boundary discretization object

735:   Level: beginner

737: .seealso: PetscDSGetBdDiscretization(), PetscDSAddBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
738: @*/
739: PetscErrorCode PetscDSSetBdDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
740: {

746:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
747:   PetscDSEnlarge_Static(prob, f+1);
748:   if (prob->discBd[f]) {PetscObjectDereference(prob->discBd[f]);}
749:   prob->discBd[f] = disc;
750:   PetscObjectReference(disc);
751:   return(0);
752: }

756: /*@
757:   PetscDSAddDiscretization - Adds a discretization object

759:   Not collective

761:   Input Parameters:
762: + prob - The PetscDS object
763: - disc - The boundary discretization object

765:   Level: beginner

767: .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
768: @*/
769: PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
770: {

774:   PetscDSSetDiscretization(prob, prob->Nf, disc);
775:   return(0);
776: }

780: /*@
781:   PetscDSAddBdDiscretization - Adds a boundary discretization object

783:   Not collective

785:   Input Parameters:
786: + prob - The PetscDS object
787: - disc - The boundary discretization object

789:   Level: beginner

791: .seealso: PetscDSGetBdDiscretization(), PetscDSSetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
792: @*/
793: PetscErrorCode PetscDSAddBdDiscretization(PetscDS prob, PetscObject disc)
794: {

798:   PetscDSSetBdDiscretization(prob, prob->Nf, disc);
799:   return(0);
800: }

804: /*@
805:   PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for IMEX

807:   Not collective

809:   Input Parameters:
810: + prob - The PetscDS object
811: - f - The field number

813:   Output Parameter:
814: . implicit - The flag indicating what kind of solve to use for this field

816:   Level: developer

818: .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
819: @*/
820: PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
821: {
825:   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);
826:   *implicit = prob->implicit[f];
827:   return(0);
828: }

832: /*@
833:   PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for IMEX

835:   Not collective

837:   Input Parameters:
838: + prob - The PetscDS object
839: . f - The field number
840: - implicit - The flag indicating what kind of solve to use for this field

842:   Level: developer

844: .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
845: @*/
846: PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
847: {
850:   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);
851:   prob->implicit[f] = implicit;
852:   return(0);
853: }

857: /*@
858:   PetscDSGetAdjacency - Returns the flags for determining variable influence

860:   Not collective

862:   Input Parameters:
863: + prob - The PetscDS object
864: - f - The field number

866:   Output Parameter:
867: + useCone    - Flag for variable influence starting with the cone operation
868: - useClosure - Flag for variable influence using transitive closure

870:   Note: See the discussion in DMPlexGetAdjacencyUseCone() and DMPlexGetAdjacencyUseClosure()

872:   Level: developer

874: .seealso: PetscDSSetAdjacency(), DMPlexGetAdjacencyUseCone(), DMPlexGetAdjacencyUseClosure(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
875: @*/
876: PetscErrorCode PetscDSGetAdjacency(PetscDS prob, PetscInt f, PetscBool *useCone, PetscBool *useClosure)
877: {
882:   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);
883:   *useCone    = prob->adjacency[f*2+0];
884:   *useClosure = prob->adjacency[f*2+1];
885:   return(0);
886: }

890: /*@
891:   PetscDSSetAdjacency - Set the flags for determining variable influence

893:   Not collective

895:   Input Parameters:
896: + prob - The PetscDS object
897: . f - The field number
898: . useCone    - Flag for variable influence starting with the cone operation
899: - useClosure - Flag for variable influence using transitive closure

901:   Note: See the discussion in DMPlexGetAdjacencyUseCone() and DMPlexGetAdjacencyUseClosure()

903:   Level: developer

905: .seealso: PetscDSGetAdjacency(), DMPlexGetAdjacencyUseCone(), DMPlexGetAdjacencyUseClosure(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetBdDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
906: @*/
907: PetscErrorCode PetscDSSetAdjacency(PetscDS prob, PetscInt f, PetscBool useCone, PetscBool useClosure)
908: {
911:   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);
912:   prob->adjacency[f*2+0] = useCone;
913:   prob->adjacency[f*2+1] = useClosure;
914:   return(0);
915: }

919: PetscErrorCode PetscDSGetObjective(PetscDS prob, PetscInt f,
920:                                    void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
921:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
922:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
923:                                                 PetscReal t, const PetscReal x[], PetscScalar obj[]))
924: {
928:   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);
929:   *obj = prob->obj[f];
930:   return(0);
931: }

935: PetscErrorCode PetscDSSetObjective(PetscDS prob, PetscInt f,
936:                                    void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
937:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
938:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
939:                                                PetscReal t, const PetscReal x[], PetscScalar obj[]))
940: {

946:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
947:   PetscDSEnlarge_Static(prob, f+1);
948:   prob->obj[f] = obj;
949:   return(0);
950: }

954: /*@C
955:   PetscDSGetResidual - Get the pointwise residual function for a given test field

957:   Not collective

959:   Input Parameters:
960: + prob - The PetscDS
961: - f    - The test field number

963:   Output Parameters:
964: + f0 - integrand for the test function term
965: - f1 - integrand for the test function gradient term

967:   Note: We are using a first order FEM model for the weak form:

969:   \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)

971: The calling sequence for the callbacks f0 and f1 is given by:

973: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
974: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
975: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
976: $    PetscReal t, const PetscReal x[], PetscScalar f0[])

978: + dim - the spatial dimension
979: . Nf - the number of fields
980: . uOff - the offset into u[] and u_t[] for each field
981: . uOff_x - the offset into u_x[] for each field
982: . u - each field evaluated at the current point
983: . u_t - the time derivative of each field evaluated at the current point
984: . u_x - the gradient of each field evaluated at the current point
985: . aOff - the offset into a[] and a_t[] for each auxiliary field
986: . aOff_x - the offset into a_x[] for each auxiliary field
987: . a - each auxiliary field evaluated at the current point
988: . a_t - the time derivative of each auxiliary field evaluated at the current point
989: . a_x - the gradient of auxiliary each field evaluated at the current point
990: . t - current time
991: . x - coordinates of the current point
992: - f0 - output values at the current point

994:   Level: intermediate

996: .seealso: PetscDSSetResidual()
997: @*/
998: PetscErrorCode PetscDSGetResidual(PetscDS prob, PetscInt f,
999:                                   void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1000:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1001:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1002:                                               PetscReal t, const PetscReal x[], PetscScalar f0[]),
1003:                                   void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1004:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1005:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1006:                                               PetscReal t, const PetscReal x[], PetscScalar f1[]))
1007: {
1010:   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);
1013:   return(0);
1014: }

1018: /*@C
1019:   PetscDSSetResidual - Set the pointwise residual function for a given test field

1021:   Not collective

1023:   Input Parameters:
1024: + prob - The PetscDS
1025: . f    - The test field number
1026: . f0 - integrand for the test function term
1027: - f1 - integrand for the test function gradient term

1029:   Note: We are using a first order FEM model for the weak form:

1031:   \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)

1033: The calling sequence for the callbacks f0 and f1 is given by:

1035: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1036: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1037: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1038: $    PetscReal t, const PetscReal x[], PetscScalar f0[])

1040: + dim - the spatial dimension
1041: . Nf - the number of fields
1042: . uOff - the offset into u[] and u_t[] for each field
1043: . uOff_x - the offset into u_x[] for each field
1044: . u - each field evaluated at the current point
1045: . u_t - the time derivative of each field evaluated at the current point
1046: . u_x - the gradient of each field evaluated at the current point
1047: . aOff - the offset into a[] and a_t[] for each auxiliary field
1048: . aOff_x - the offset into a_x[] for each auxiliary field
1049: . a - each auxiliary field evaluated at the current point
1050: . a_t - the time derivative of each auxiliary field evaluated at the current point
1051: . a_x - the gradient of auxiliary each field evaluated at the current point
1052: . t - current time
1053: . x - coordinates of the current point
1054: - f0 - output values at the current point

1056:   Level: intermediate

1058: .seealso: PetscDSGetResidual()
1059: @*/
1060: PetscErrorCode PetscDSSetResidual(PetscDS prob, PetscInt f,
1061:                                   void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1062:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1063:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1064:                                              PetscReal t, const PetscReal x[], PetscScalar f0[]),
1065:                                   void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1066:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1067:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1068:                                              PetscReal t, const PetscReal x[], PetscScalar f1[]))
1069: {

1076:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1077:   PetscDSEnlarge_Static(prob, f+1);
1078:   prob->f[f*2+0] = f0;
1079:   prob->f[f*2+1] = f1;
1080:   return(0);
1081: }

1085: /*@C
1086:   PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field

1088:   Not collective

1090:   Input Parameters:
1091: + prob - The PetscDS
1092: . f    - The test field number
1093: - g    - The field number

1095:   Output Parameters:
1096: + g0 - integrand for the test and basis function term
1097: . g1 - integrand for the test function and basis function gradient term
1098: . g2 - integrand for the test function gradient and basis function term
1099: - g3 - integrand for the test function gradient and basis function gradient term

1101:   Note: We are using a first order FEM model for the weak form:

1103:   \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

1105: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:

1107: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1108: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1109: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1110: $    PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])

1112: + dim - the spatial dimension
1113: . Nf - the number of fields
1114: . uOff - the offset into u[] and u_t[] for each field
1115: . uOff_x - the offset into u_x[] for each field
1116: . u - each field evaluated at the current point
1117: . u_t - the time derivative of each field evaluated at the current point
1118: . u_x - the gradient of each field evaluated at the current point
1119: . aOff - the offset into a[] and a_t[] for each auxiliary field
1120: . aOff_x - the offset into a_x[] for each auxiliary field
1121: . a - each auxiliary field evaluated at the current point
1122: . a_t - the time derivative of each auxiliary field evaluated at the current point
1123: . a_x - the gradient of auxiliary each field evaluated at the current point
1124: . t - current time
1125: . u_tShift - the multiplier a for dF/dU_t
1126: . x - coordinates of the current point
1127: - g0 - output values at the current point

1129:   Level: intermediate

1131: .seealso: PetscDSSetJacobian()
1132: @*/
1133: PetscErrorCode PetscDSGetJacobian(PetscDS prob, PetscInt f, PetscInt g,
1134:                                   void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1135:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1136:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1137:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]),
1138:                                   void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1139:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1140:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1141:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]),
1142:                                   void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1143:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1144:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1145:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]),
1146:                                   void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1147:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1148:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1149:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[]))
1150: {
1153:   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);
1154:   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);
1159:   return(0);
1160: }

1164: /*@C
1165:   PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields

1167:   Not collective

1169:   Input Parameters:
1170: + prob - The PetscDS
1171: . f    - The test field number
1172: . g    - The field number
1173: . g0 - integrand for the test and basis function term
1174: . g1 - integrand for the test function and basis function gradient term
1175: . g2 - integrand for the test function gradient and basis function term
1176: - g3 - integrand for the test function gradient and basis function gradient term

1178:   Note: We are using a first order FEM model for the weak form:

1180:   \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

1182: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:

1184: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1185: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1186: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1187: $    PetscReal t, const PetscReal x[], PetscScalar g0[])

1189: + dim - the spatial dimension
1190: . Nf - the number of fields
1191: . uOff - the offset into u[] and u_t[] for each field
1192: . uOff_x - the offset into u_x[] for each field
1193: . u - each field evaluated at the current point
1194: . u_t - the time derivative of each field evaluated at the current point
1195: . u_x - the gradient of each field evaluated at the current point
1196: . aOff - the offset into a[] and a_t[] for each auxiliary field
1197: . aOff_x - the offset into a_x[] for each auxiliary field
1198: . a - each auxiliary field evaluated at the current point
1199: . a_t - the time derivative of each auxiliary field evaluated at the current point
1200: . a_x - the gradient of auxiliary each field evaluated at the current point
1201: . t - current time
1202: . u_tShift - the multiplier a for dF/dU_t
1203: . x - coordinates of the current point
1204: - g0 - output values at the current point

1206:   Level: intermediate

1208: .seealso: PetscDSGetJacobian()
1209: @*/
1210: PetscErrorCode PetscDSSetJacobian(PetscDS prob, PetscInt f, PetscInt g,
1211:                                   void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1212:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1213:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1214:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g0[]),
1215:                                   void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1216:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1217:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1218:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g1[]),
1219:                                   void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1220:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1221:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1222:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g2[]),
1223:                                   void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1224:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1225:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1226:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscScalar g3[]))
1227: {

1236:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1237:   if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1238:   PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
1239:   prob->g[(f*prob->Nf + g)*4+0] = g0;
1240:   prob->g[(f*prob->Nf + g)*4+1] = g1;
1241:   prob->g[(f*prob->Nf + g)*4+2] = g2;
1242:   prob->g[(f*prob->Nf + g)*4+3] = g3;
1243:   return(0);
1244: }

1248: /*@C
1249:   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field

1251:   Not collective

1253:   Input Arguments:
1254: + prob - The PetscDS object
1255: - f    - The field number

1257:   Output Argument:
1258: . r    - Riemann solver

1260:   Calling sequence for r:

1262: $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)

1264: + dim  - The spatial dimension
1265: . Nf   - The number of fields
1266: . x    - The coordinates at a point on the interface
1267: . n    - The normal vector to the interface
1268: . uL   - The state vector to the left of the interface
1269: . uR   - The state vector to the right of the interface
1270: . flux - output array of flux through the interface
1271: - ctx  - optional user context

1273:   Level: intermediate

1275: .seealso: PetscDSSetRiemannSolver()
1276: @*/
1277: PetscErrorCode PetscDSGetRiemannSolver(PetscDS prob, PetscInt f,
1278:                                        void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx))
1279: {
1282:   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);
1284:   *r = prob->r[f];
1285:   return(0);
1286: }

1290: /*@C
1291:   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field

1293:   Not collective

1295:   Input Arguments:
1296: + prob - The PetscDS object
1297: . f    - The field number
1298: - r    - Riemann solver

1300:   Calling sequence for r:

1302: $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)

1304: + dim  - The spatial dimension
1305: . Nf   - The number of fields
1306: . x    - The coordinates at a point on the interface
1307: . n    - The normal vector to the interface
1308: . uL   - The state vector to the left of the interface
1309: . uR   - The state vector to the right of the interface
1310: . flux - output array of flux through the interface
1311: - ctx  - optional user context

1313:   Level: intermediate

1315: .seealso: PetscDSGetRiemannSolver()
1316: @*/
1317: PetscErrorCode PetscDSSetRiemannSolver(PetscDS prob, PetscInt f,
1318:                                        void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx))
1319: {

1325:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1326:   PetscDSEnlarge_Static(prob, f+1);
1327:   prob->r[f] = r;
1328:   return(0);
1329: }

1333: PetscErrorCode PetscDSGetContext(PetscDS prob, PetscInt f, void **ctx)
1334: {
1337:   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);
1339:   *ctx = prob->ctx[f];
1340:   return(0);
1341: }

1345: PetscErrorCode PetscDSSetContext(PetscDS prob, PetscInt f, void *ctx)
1346: {

1351:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1352:   PetscDSEnlarge_Static(prob, f+1);
1353:   prob->ctx[f] = ctx;
1354:   return(0);
1355: }

1359: /*@C
1360:   PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field

1362:   Not collective

1364:   Input Parameters:
1365: + prob - The PetscDS
1366: - f    - The test field number

1368:   Output Parameters:
1369: + f0 - boundary integrand for the test function term
1370: - f1 - boundary integrand for the test function gradient term

1372:   Note: We are using a first order FEM model for the weak form:

1374:   \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

1376: The calling sequence for the callbacks f0 and f1 is given by:

1378: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1379: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1380: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1381: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])

1383: + dim - the spatial dimension
1384: . Nf - the number of fields
1385: . uOff - the offset into u[] and u_t[] for each field
1386: . uOff_x - the offset into u_x[] for each field
1387: . u - each field evaluated at the current point
1388: . u_t - the time derivative of each field evaluated at the current point
1389: . u_x - the gradient of each field evaluated at the current point
1390: . aOff - the offset into a[] and a_t[] for each auxiliary field
1391: . aOff_x - the offset into a_x[] for each auxiliary field
1392: . a - each auxiliary field evaluated at the current point
1393: . a_t - the time derivative of each auxiliary field evaluated at the current point
1394: . a_x - the gradient of auxiliary each field evaluated at the current point
1395: . t - current time
1396: . x - coordinates of the current point
1397: . n - unit normal at the current point
1398: - f0 - output values at the current point

1400:   Level: intermediate

1402: .seealso: PetscDSSetBdResidual()
1403: @*/
1404: PetscErrorCode PetscDSGetBdResidual(PetscDS prob, PetscInt f,
1405:                                     void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1406:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1407:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1408:                                                 PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]),
1409:                                     void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1410:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1411:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1412:                                                 PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f1[]))
1413: {
1416:   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);
1419:   return(0);
1420: }

1424: /*@C
1425:   PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field

1427:   Not collective

1429:   Input Parameters:
1430: + prob - The PetscDS
1431: . f    - The test field number
1432: . f0 - boundary integrand for the test function term
1433: - f1 - boundary integrand for the test function gradient term

1435:   Note: We are using a first order FEM model for the weak form:

1437:   \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

1439: The calling sequence for the callbacks f0 and f1 is given by:

1441: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1442: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1443: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1444: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])

1446: + dim - the spatial dimension
1447: . Nf - the number of fields
1448: . uOff - the offset into u[] and u_t[] for each field
1449: . uOff_x - the offset into u_x[] for each field
1450: . u - each field evaluated at the current point
1451: . u_t - the time derivative of each field evaluated at the current point
1452: . u_x - the gradient of each field evaluated at the current point
1453: . aOff - the offset into a[] and a_t[] for each auxiliary field
1454: . aOff_x - the offset into a_x[] for each auxiliary field
1455: . a - each auxiliary field evaluated at the current point
1456: . a_t - the time derivative of each auxiliary field evaluated at the current point
1457: . a_x - the gradient of auxiliary each field evaluated at the current point
1458: . t - current time
1459: . x - coordinates of the current point
1460: . n - unit normal at the current point
1461: - f0 - output values at the current point

1463:   Level: intermediate

1465: .seealso: PetscDSGetBdResidual()
1466: @*/
1467: PetscErrorCode PetscDSSetBdResidual(PetscDS prob, PetscInt f,
1468:                                     void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1469:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1470:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1471:                                                PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[]),
1472:                                     void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1473:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1474:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1475:                                                PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f1[]))
1476: {

1481:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1482:   PetscDSEnlarge_Static(prob, f+1);
1485:   return(0);
1486: }

1490: /*@C
1491:   PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field

1493:   Not collective

1495:   Input Parameters:
1496: + prob - The PetscDS
1497: . f    - The test field number
1498: - g    - The field number

1500:   Output Parameters:
1501: + g0 - integrand for the test and basis function term
1502: . g1 - integrand for the test function and basis function gradient term
1503: . g2 - integrand for the test function gradient and basis function term
1504: - g3 - integrand for the test function gradient and basis function gradient term

1506:   Note: We are using a first order FEM model for the weak form:

1508:   \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

1510: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:

1512: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1513: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1514: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1515: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])

1517: + dim - the spatial dimension
1518: . Nf - the number of fields
1519: . uOff - the offset into u[] and u_t[] for each field
1520: . uOff_x - the offset into u_x[] for each field
1521: . u - each field evaluated at the current point
1522: . u_t - the time derivative of each field evaluated at the current point
1523: . u_x - the gradient of each field evaluated at the current point
1524: . aOff - the offset into a[] and a_t[] for each auxiliary field
1525: . aOff_x - the offset into a_x[] for each auxiliary field
1526: . a - each auxiliary field evaluated at the current point
1527: . a_t - the time derivative of each auxiliary field evaluated at the current point
1528: . a_x - the gradient of auxiliary each field evaluated at the current point
1529: . t - current time
1530: . u_tShift - the multiplier a for dF/dU_t
1531: . x - coordinates of the current point
1532: . n - normal at the current point
1533: - g0 - output values at the current point

1535:   Level: intermediate

1537: .seealso: PetscDSSetBdJacobian()
1538: @*/
1539: PetscErrorCode PetscDSGetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
1540:                                     void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1541:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1542:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1543:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g0[]),
1544:                                     void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1545:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1546:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1547:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g1[]),
1548:                                     void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1549:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1550:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1551:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g2[]),
1552:                                     void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1553:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1554:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1555:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g3[]))
1556: {
1559:   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);
1560:   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);
1565:   return(0);
1566: }

1570: /*@C
1571:   PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field

1573:   Not collective

1575:   Input Parameters:
1576: + prob - The PetscDS
1577: . f    - The test field number
1578: . g    - The field number
1579: . g0 - integrand for the test and basis function term
1580: . g1 - integrand for the test function and basis function gradient term
1581: . g2 - integrand for the test function gradient and basis function term
1582: - g3 - integrand for the test function gradient and basis function gradient term

1584:   Note: We are using a first order FEM model for the weak form:

1586:   \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

1588: The calling sequence for the callbacks g0, g1, g2 and g3 is given by:

1590: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1591: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1592: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1593: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])

1595: + dim - the spatial dimension
1596: . Nf - the number of fields
1597: . uOff - the offset into u[] and u_t[] for each field
1598: . uOff_x - the offset into u_x[] for each field
1599: . u - each field evaluated at the current point
1600: . u_t - the time derivative of each field evaluated at the current point
1601: . u_x - the gradient of each field evaluated at the current point
1602: . aOff - the offset into a[] and a_t[] for each auxiliary field
1603: . aOff_x - the offset into a_x[] for each auxiliary field
1604: . a - each auxiliary field evaluated at the current point
1605: . a_t - the time derivative of each auxiliary field evaluated at the current point
1606: . a_x - the gradient of auxiliary each field evaluated at the current point
1607: . t - current time
1608: . u_tShift - the multiplier a for dF/dU_t
1609: . x - coordinates of the current point
1610: . n - normal at the current point
1611: - g0 - output values at the current point

1613:   Level: intermediate

1615: .seealso: PetscDSGetBdJacobian()
1616: @*/
1617: PetscErrorCode PetscDSSetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
1618:                                     void (*g0)(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[], const PetscReal n[], PetscScalar g0[]),
1622:                                     void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1623:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1624:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1625:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g1[]),
1626:                                     void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1627:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1628:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1629:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g2[]),
1630:                                     void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1631:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1632:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1633:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscScalar g3[]))
1634: {

1643:   if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1644:   if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1645:   PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);
1646:   prob->gBd[(f*prob->Nf + g)*4+0] = g0;
1647:   prob->gBd[(f*prob->Nf + g)*4+1] = g1;
1648:   prob->gBd[(f*prob->Nf + g)*4+2] = g2;
1649:   prob->gBd[(f*prob->Nf + g)*4+3] = g3;
1650:   return(0);
1651: }

1655: /*@
1656:   PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis

1658:   Not collective

1660:   Input Parameters:
1661: + prob - The PetscDS object
1662: - f - The field number

1664:   Output Parameter:
1665: . off - The offset

1667:   Level: beginner

1669: .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1670: @*/
1671: PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
1672: {
1673:   PetscInt       g;

1679:   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);
1680:   *off = 0;
1681:   for (g = 0; g < f; ++g) {
1682:     PetscFE  fe = (PetscFE) prob->disc[g];
1683:     PetscInt Nb, Nc;

1685:     PetscFEGetDimension(fe, &Nb);
1686:     PetscFEGetNumComponents(fe, &Nc);
1687:     *off += Nb*Nc;
1688:   }
1689:   return(0);
1690: }

1694: /*@
1695:   PetscDSGetBdFieldOffset - Returns the offset of the given field in the full space boundary basis

1697:   Not collective

1699:   Input Parameters:
1700: + prob - The PetscDS object
1701: - f - The field number

1703:   Output Parameter:
1704: . off - The boundary offset

1706:   Level: beginner

1708: .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1709: @*/
1710: PetscErrorCode PetscDSGetBdFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
1711: {
1712:   PetscInt       g;

1718:   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);
1719:   *off = 0;
1720:   for (g = 0; g < f; ++g) {
1721:     PetscFE  fe = (PetscFE) prob->discBd[g];
1722:     PetscInt Nb, Nc;

1724:     PetscFEGetDimension(fe, &Nb);
1725:     PetscFEGetNumComponents(fe, &Nc);
1726:     *off += Nb*Nc;
1727:   }
1728:   return(0);
1729: }

1733: /*@
1734:   PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point

1736:   Not collective

1738:   Input Parameters:
1739: + prob - The PetscDS object
1740: - f - The field number

1742:   Output Parameter:
1743: . off - The offset

1745:   Level: beginner

1747: .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1748: @*/
1749: PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
1750: {
1751:   PetscInt       g;

1757:   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);
1758:   *off = 0;
1759:   for (g = 0; g < f; ++g) {
1760:     PetscFE  fe = (PetscFE) prob->disc[g];
1761:     PetscInt Nc;

1763:     PetscFEGetNumComponents(fe, &Nc);
1764:     *off += Nc;
1765:   }
1766:   return(0);
1767: }

1771: /*@
1772:   PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point

1774:   Not collective

1776:   Input Parameter:
1777: . prob - The PetscDS object

1779:   Output Parameter:
1780: . offsets - The offsets

1782:   Level: beginner

1784: .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1785: @*/
1786: PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
1787: {
1791:   *offsets = prob->off;
1792:   return(0);
1793: }

1797: /*@
1798:   PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point

1800:   Not collective

1802:   Input Parameter:
1803: . prob - The PetscDS object

1805:   Output Parameter:
1806: . offsets - The offsets

1808:   Level: beginner

1810: .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1811: @*/
1812: PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
1813: {
1817:   *offsets = prob->offDer;
1818:   return(0);
1819: }

1823: /*@
1824:   PetscDSGetComponentBdOffsets - Returns the offset of each field on a boundary evaluation point

1826:   Not collective

1828:   Input Parameter:
1829: . prob - The PetscDS object

1831:   Output Parameter:
1832: . offsets - The offsets

1834:   Level: beginner

1836: .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1837: @*/
1838: PetscErrorCode PetscDSGetComponentBdOffsets(PetscDS prob, PetscInt *offsets[])
1839: {
1843:   *offsets = prob->offBd;
1844:   return(0);
1845: }

1849: /*@
1850:   PetscDSGetComponentBdDerivativeOffsets - Returns the offset of each field derivative on a boundary evaluation point

1852:   Not collective

1854:   Input Parameter:
1855: . prob - The PetscDS object

1857:   Output Parameter:
1858: . offsets - The offsets

1860:   Level: beginner

1862: .seealso: PetscDSGetBdFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
1863: @*/
1864: PetscErrorCode PetscDSGetComponentBdDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
1865: {
1869:   *offsets = prob->offDerBd;
1870:   return(0);
1871: }

1875: /*@C
1876:   PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization

1878:   Not collective

1880:   Input Parameter:
1881: . prob - The PetscDS object

1883:   Output Parameters:
1884: + basis - The basis function tabulation at quadrature points
1885: - basisDer - The basis function derivative tabulation at quadrature points

1887:   Level: intermediate

1889: .seealso: PetscDSGetBdTabulation(), PetscDSCreate()
1890: @*/
1891: PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer)
1892: {

1897:   PetscDSSetUp(prob);
1900:   return(0);
1901: }

1905: /*@C
1906:   PetscDSGetBdTabulation - Return the basis tabulation at quadrature points for the boundary discretization

1908:   Not collective

1910:   Input Parameter:
1911: . prob - The PetscDS object

1913:   Output Parameters:
1914: + basis - The basis function tabulation at quadrature points
1915: - basisDer - The basis function derivative tabulation at quadrature points

1917:   Level: intermediate

1919: .seealso: PetscDSGetTabulation(), PetscDSCreate()
1920: @*/
1921: PetscErrorCode PetscDSGetBdTabulation(PetscDS prob, PetscReal ***basis, PetscReal ***basisDer)
1922: {

1927:   PetscDSSetUp(prob);
1930:   return(0);
1931: }

1935: PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
1936: {

1941:   PetscDSSetUp(prob);
1945:   return(0);
1946: }

1950: PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
1951: {

1956:   PetscDSSetUp(prob);
1963:   return(0);
1964: }

1968: PetscErrorCode PetscDSGetRefCoordArrays(PetscDS prob, PetscReal **x, PetscScalar **refSpaceDer)
1969: {

1974:   PetscDSSetUp(prob);
1977:   return(0);
1978: }

1982: static PetscErrorCode PetscDSDestroy_Basic(PetscDS prob)
1983: {
1985:   return(0);
1986: }

1990: static PetscErrorCode PetscDSInitialize_Basic(PetscDS prob)
1991: {
1993:   prob->ops->setfromoptions = NULL;
1994:   prob->ops->setup          = NULL;
1995:   prob->ops->view           = NULL;
1996:   prob->ops->destroy        = PetscDSDestroy_Basic;
1997:   return(0);
1998: }

2000: /*MC
2001:   PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions

2003:   Level: intermediate

2005: .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType()
2006: M*/

2010: PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS prob)
2011: {
2012:   PetscDS_Basic *b;
2013:   PetscErrorCode      ierr;

2017:   PetscNewLog(prob, &b);
2018:   prob->data = b;

2020:   PetscDSInitialize_Basic(prob);
2021:   return(0);
2022: }