Actual source code: dtds.c

  1: #include <petsc/private/petscdsimpl.h>

  3: PetscClassId PETSCDS_CLASSID = 0;

  5: PetscFunctionList PetscDSList              = NULL;
  6: PetscBool         PetscDSRegisterAllCalled = PETSC_FALSE;

  8: /* A PetscDS (Discrete System) encodes a set of equations posed in a discrete space, which represents a set of
  9:    nonlinear continuum equations. The equations can have multiple fields, each field having a different
 10:    discretization. In addition, different pieces of the domain can have different field combinations and equations.

 12:    The DS provides the user a description of the approximation space on any given cell. It also gives pointwise
 13:    functions representing the equations.

 15:    Each field is associated with a label, marking the cells on which it is supported. Note that a field can be
 16:    supported on the closure of a cell not in the label due to overlap of the boundary of neighboring cells. The DM
 17:    then creates a DS for each set of cells with identical approximation spaces. When assembling, the user asks for
 18:    the space associated with a given cell. DMPlex uses the labels associated with each DS in the default integration loop.
 19: */

 21: /*@C
 22:   PetscDSRegister - Adds a new PetscDS implementation

 24:   Not Collective

 26:   Input Parameters:
 27: + name        - The name of a new user-defined creation routine
 28: - create_func - The creation routine itself

 30:   Notes:
 31:   PetscDSRegister() may be called multiple times to add several user-defined PetscDSs

 33:   Sample usage:
 34: .vb
 35:     PetscDSRegister("my_ds", MyPetscDSCreate);
 36: .ve

 38:   Then, your PetscDS type can be chosen with the procedural interface via
 39: .vb
 40:     PetscDSCreate(MPI_Comm, PetscDS *);
 41:     PetscDSSetType(PetscDS, "my_ds");
 42: .ve
 43:    or at runtime via the option
 44: .vb
 45:     -petscds_type my_ds
 46: .ve

 48:   Level: advanced

 50:    Not available from Fortran

 52: .seealso: PetscDSRegisterAll(), PetscDSRegisterDestroy()

 54: @*/
 55: PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
 56: {
 57:   PetscFunctionListAdd(&PetscDSList, sname, function);
 58:   return 0;
 59: }

 61: /*@C
 62:   PetscDSSetType - Builds a particular PetscDS

 64:   Collective on prob

 66:   Input Parameters:
 67: + prob - The PetscDS object
 68: - name - The kind of system

 70:   Options Database Key:
 71: . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types

 73:   Level: intermediate

 75:    Not available from Fortran

 77: .seealso: PetscDSGetType(), PetscDSCreate()
 78: @*/
 79: PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
 80: {
 81:   PetscErrorCode (*r)(PetscDS);
 82:   PetscBool      match;

 85:   PetscObjectTypeCompare((PetscObject) prob, name, &match);
 86:   if (match) return 0;

 88:   PetscDSRegisterAll();
 89:   PetscFunctionListFind(PetscDSList, name, &r);

 92:   if (prob->ops->destroy) {
 93:     (*prob->ops->destroy)(prob);
 94:     prob->ops->destroy = NULL;
 95:   }
 96:   (*r)(prob);
 97:   PetscObjectChangeTypeName((PetscObject) prob, name);
 98:   return 0;
 99: }

101: /*@C
102:   PetscDSGetType - Gets the PetscDS type name (as a string) from the object.

104:   Not Collective

106:   Input Parameter:
107: . prob  - The PetscDS

109:   Output Parameter:
110: . name - The PetscDS type name

112:   Level: intermediate

114:    Not available from Fortran

116: .seealso: PetscDSSetType(), PetscDSCreate()
117: @*/
118: PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
119: {
122:   PetscDSRegisterAll();
123:   *name = ((PetscObject) prob)->type_name;
124:   return 0;
125: }

127: static PetscErrorCode PetscDSView_Ascii(PetscDS ds, PetscViewer viewer)
128: {
129:   PetscViewerFormat  format;
130:   const PetscScalar *constants;
131:   PetscInt           Nf, numConstants, f;

133:   PetscDSGetNumFields(ds, &Nf);
134:   PetscViewerGetFormat(viewer, &format);
135:   PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", Nf);
136:   PetscViewerASCIIPushTab(viewer);
137:   PetscViewerASCIIPrintf(viewer, "  cell total dim %D total comp %D\n", ds->totDim, ds->totComp);
138:   if (ds->isCohesive) PetscViewerASCIIPrintf(viewer, "  cohesive cell\n");
139:   for (f = 0; f < Nf; ++f) {
140:     DSBoundary      b;
141:     PetscObject     obj;
142:     PetscClassId    id;
143:     PetscQuadrature q;
144:     const char     *name;
145:     PetscInt        Nc, Nq, Nqc;

147:     PetscDSGetDiscretization(ds, f, &obj);
148:     PetscObjectGetClassId(obj, &id);
149:     PetscObjectGetName(obj, &name);
150:     PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");
151:     PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
152:     if (id == PETSCFE_CLASSID)      {
153:       PetscFEGetNumComponents((PetscFE) obj, &Nc);
154:       PetscFEGetQuadrature((PetscFE) obj, &q);
155:       PetscViewerASCIIPrintf(viewer, " FEM");
156:     } else if (id == PETSCFV_CLASSID) {
157:       PetscFVGetNumComponents((PetscFV) obj, &Nc);
158:       PetscFVGetQuadrature((PetscFV) obj, &q);
159:       PetscViewerASCIIPrintf(viewer, " FVM");
160:     }
161:     else SETERRQ(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %D", f);
162:     if (Nc > 1) PetscViewerASCIIPrintf(viewer, " %D components", Nc);
163:     else        PetscViewerASCIIPrintf(viewer, " %D component ", Nc);
164:     if (ds->implicit[f]) PetscViewerASCIIPrintf(viewer, " (implicit)");
165:     else                 PetscViewerASCIIPrintf(viewer, " (explicit)");
166:     if (q) {
167:       PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL);
168:       PetscViewerASCIIPrintf(viewer, " (Nq %D Nqc %D)", Nq, Nqc);
169:     }
170:     PetscViewerASCIIPrintf(viewer, " %D-jet", ds->jetDegree[f]);
171:     PetscViewerASCIIPrintf(viewer, "\n");
172:     PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
173:     PetscViewerASCIIPushTab(viewer);
174:     if (id == PETSCFE_CLASSID)      PetscFEView((PetscFE) obj, viewer);
175:     else if (id == PETSCFV_CLASSID) PetscFVView((PetscFV) obj, viewer);
176:     PetscViewerASCIIPopTab(viewer);

178:     for (b = ds->boundary; b; b = b->next) {
179:       char     *name;
180:       PetscInt  c, i;

182:       if (b->field != f) continue;
183:       PetscViewerASCIIPushTab(viewer);
184:       PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->lname, DMBoundaryConditionTypes[b->type]);
185:       if (!b->Nc) {
186:         PetscViewerASCIIPrintf(viewer, "  all components\n");
187:       } else {
188:         PetscViewerASCIIPrintf(viewer, "  components: ");
189:         PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
190:         for (c = 0; c < b->Nc; ++c) {
191:           if (c > 0) PetscViewerASCIIPrintf(viewer, ", ");
192:           PetscViewerASCIIPrintf(viewer, "%D", b->comps[c]);
193:         }
194:         PetscViewerASCIIPrintf(viewer, "\n");
195:         PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
196:       }
197:       PetscViewerASCIIPrintf(viewer, "  values: ");
198:       PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);
199:       for (i = 0; i < b->Nv; ++i) {
200:         if (i > 0) PetscViewerASCIIPrintf(viewer, ", ");
201:         PetscViewerASCIIPrintf(viewer, "%D", b->values[i]);
202:       }
203:       PetscViewerASCIIPrintf(viewer, "\n");
204:       PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);
205:       if (b->func) {
206:         PetscDLAddr(b->func, &name);
207:         if (name) PetscViewerASCIIPrintf(viewer, "  func: %s\n", name);
208:         else      PetscViewerASCIIPrintf(viewer, "  func: %p\n", b->func);
209:         PetscFree(name);
210:       }
211:       if (b->func_t) {
212:         PetscDLAddr(b->func_t, &name);
213:         if (name) PetscViewerASCIIPrintf(viewer, "  func_t: %s\n", name);
214:         else      PetscViewerASCIIPrintf(viewer, "  func_t: %p\n", b->func_t);
215:         PetscFree(name);
216:       }
217:       PetscWeakFormView(b->wf, viewer);
218:       PetscViewerASCIIPopTab(viewer);
219:     }
220:   }
221:   PetscDSGetConstants(ds, &numConstants, &constants);
222:   if (numConstants) {
223:     PetscViewerASCIIPrintf(viewer, "%D constants\n", numConstants);
224:     PetscViewerASCIIPushTab(viewer);
225:     for (f = 0; f < numConstants; ++f) PetscViewerASCIIPrintf(viewer, "%g\n", (double) PetscRealPart(constants[f]));
226:     PetscViewerASCIIPopTab(viewer);
227:   }
228:   PetscWeakFormView(ds->wf, viewer);
229:   PetscViewerASCIIPopTab(viewer);
230:   return 0;
231: }

233: /*@C
234:    PetscDSViewFromOptions - View from Options

236:    Collective on PetscDS

238:    Input Parameters:
239: +  A - the PetscDS object
240: .  obj - Optional object
241: -  name - command line option

243:    Level: intermediate
244: .seealso:  PetscDS, PetscDSView, PetscObjectViewFromOptions(), PetscDSCreate()
245: @*/
246: PetscErrorCode  PetscDSViewFromOptions(PetscDS A,PetscObject obj,const char name[])
247: {
249:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
250:   return 0;
251: }

253: /*@C
254:   PetscDSView - Views a PetscDS

256:   Collective on prob

258:   Input Parameters:
259: + prob - the PetscDS object to view
260: - v  - the viewer

262:   Level: developer

264: .seealso PetscDSDestroy()
265: @*/
266: PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
267: {
268:   PetscBool      iascii;

271:   if (!v) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);
273:   PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);
274:   if (iascii) PetscDSView_Ascii(prob, v);
275:   if (prob->ops->view) (*prob->ops->view)(prob, v);
276:   return 0;
277: }

279: /*@
280:   PetscDSSetFromOptions - sets parameters in a PetscDS from the options database

282:   Collective on prob

284:   Input Parameter:
285: . prob - the PetscDS object to set options for

287:   Options Database:
288: + -petscds_type <type>     - Set the DS type
289: . -petscds_view <view opt> - View the DS
290: . -petscds_jac_pre         - Turn formation of a separate Jacobian preconditioner on or off
291: . -bc_<name> <ids>         - Specify a list of label ids for a boundary condition
292: - -bc_<name>_comp <comps>  - Specify a list of field components to constrain for a boundary condition

294:   Level: developer

296: .seealso PetscDSView()
297: @*/
298: PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
299: {
300:   DSBoundary     b;
301:   const char    *defaultType;
302:   char           name[256];
303:   PetscBool      flg;

307:   if (!((PetscObject) prob)->type_name) {
308:     defaultType = PETSCDSBASIC;
309:   } else {
310:     defaultType = ((PetscObject) prob)->type_name;
311:   }
312:   PetscDSRegisterAll();

314:   PetscObjectOptionsBegin((PetscObject) prob);
315:   for (b = prob->boundary; b; b = b->next) {
316:     char       optname[1024];
317:     PetscInt   ids[1024], len = 1024;
318:     PetscBool  flg;

320:     PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name);
321:     PetscMemzero(ids, sizeof(ids));
322:     PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg);
323:     if (flg) {
324:       b->Nv = len;
325:       PetscFree(b->values);
326:       PetscMalloc1(len, &b->values);
327:       PetscArraycpy(b->values, ids, len);
328:       PetscWeakFormRewriteKeys(b->wf, b->label, len, b->values);
329:     }
330:     len = 1024;
331:     PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name);
332:     PetscMemzero(ids, sizeof(ids));
333:     PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg);
334:     if (flg) {
335:       b->Nc = len;
336:       PetscFree(b->comps);
337:       PetscMalloc1(len, &b->comps);
338:       PetscArraycpy(b->comps, ids, len);
339:     }
340:   }
341:   PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);
342:   if (flg) {
343:     PetscDSSetType(prob, name);
344:   } else if (!((PetscObject) prob)->type_name) {
345:     PetscDSSetType(prob, defaultType);
346:   }
347:   PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg);
348:   if (prob->ops->setfromoptions) (*prob->ops->setfromoptions)(prob);
349:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
350:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) prob);
351:   PetscOptionsEnd();
352:   if (prob->Nf) PetscDSViewFromOptions(prob, NULL, "-petscds_view");
353:   return 0;
354: }

356: /*@C
357:   PetscDSSetUp - Construct data structures for the PetscDS

359:   Collective on prob

361:   Input Parameter:
362: . prob - the PetscDS object to setup

364:   Level: developer

366: .seealso PetscDSView(), PetscDSDestroy()
367: @*/
368: PetscErrorCode PetscDSSetUp(PetscDS prob)
369: {
370:   const PetscInt Nf   = prob->Nf;
371:   PetscBool      hasH = PETSC_FALSE;
372:   PetscInt       dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;

376:   if (prob->setup) return 0;
377:   /* Calculate sizes */
378:   PetscDSGetSpatialDimension(prob, &dim);
379:   PetscDSGetCoordinateDimension(prob, &dimEmbed);
380:   prob->totDim = prob->totComp = 0;
381:   PetscMalloc2(Nf,&prob->Nc,Nf,&prob->Nb);
382:   PetscCalloc2(Nf+1,&prob->off,Nf+1,&prob->offDer);
383:   PetscCalloc6(Nf+1,&prob->offCohesive[0],Nf+1,&prob->offCohesive[1],Nf+1,&prob->offCohesive[2],Nf+1,&prob->offDerCohesive[0],Nf+1,&prob->offDerCohesive[1],Nf+1,&prob->offDerCohesive[2]);
384:   PetscMalloc2(Nf,&prob->T,Nf,&prob->Tf);
385:   for (f = 0; f < Nf; ++f) {
386:     PetscObject     obj;
387:     PetscClassId    id;
388:     PetscQuadrature q = NULL;
389:     PetscInt        Nq = 0, Nb, Nc;

391:     PetscDSGetDiscretization(prob, f, &obj);
392:     if (prob->jetDegree[f] > 1) hasH = PETSC_TRUE;
393:     if (!obj) {
394:       /* Empty mesh */
395:       Nb = Nc = 0;
396:       prob->T[f] = prob->Tf[f] = NULL;
397:     } else {
398:       PetscObjectGetClassId(obj, &id);
399:       if (id == PETSCFE_CLASSID)      {
400:         PetscFE fe = (PetscFE) obj;

402:         PetscFEGetQuadrature(fe, &q);
403:         PetscFEGetDimension(fe, &Nb);
404:         PetscFEGetNumComponents(fe, &Nc);
405:         PetscFEGetCellTabulation(fe, prob->jetDegree[f], &prob->T[f]);
406:         PetscFEGetFaceTabulation(fe, prob->jetDegree[f], &prob->Tf[f]);
407:       } else if (id == PETSCFV_CLASSID) {
408:         PetscFV fv = (PetscFV) obj;

410:         PetscFVGetQuadrature(fv, &q);
411:         PetscFVGetNumComponents(fv, &Nc);
412:         Nb   = Nc;
413:         PetscFVGetCellTabulation(fv, &prob->T[f]);
414:         /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
415:       } else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
416:     }
417:     prob->Nc[f]       = Nc;
418:     prob->Nb[f]       = Nb;
419:     prob->off[f+1]    = Nc     + prob->off[f];
420:     prob->offDer[f+1] = Nc*dim + prob->offDer[f];
421:     prob->offCohesive[0][f+1]    = (prob->cohesive[f] ? Nc : Nc*2)          + prob->offCohesive[0][f];
422:     prob->offDerCohesive[0][f+1] = (prob->cohesive[f] ? Nc : Nc*2)*dimEmbed + prob->offDerCohesive[0][f];
423:     prob->offCohesive[1][f]      = (prob->cohesive[f] ? 0 : Nc)             + prob->offCohesive[0][f];
424:     prob->offDerCohesive[1][f]   = (prob->cohesive[f] ? 0 : Nc)*dimEmbed    + prob->offDerCohesive[0][f];
425:     prob->offCohesive[2][f+1]    = (prob->cohesive[f] ? Nc : Nc*2)          + prob->offCohesive[2][f];
426:     prob->offDerCohesive[2][f+1] = (prob->cohesive[f] ? Nc : Nc*2)*dimEmbed + prob->offDerCohesive[2][f];
427:     if (q) PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL);
428:     NqMax          = PetscMax(NqMax, Nq);
429:     NbMax          = PetscMax(NbMax, Nb);
430:     NcMax          = PetscMax(NcMax, Nc);
431:     prob->totDim  += Nb;
432:     prob->totComp += Nc;
433:     /* There are two faces for all fields on a cohesive cell, except for cohesive fields */
434:     if (prob->isCohesive && !prob->cohesive[f]) prob->totDim += Nb;
435:   }
436:   prob->offCohesive[1][Nf]    = prob->offCohesive[0][Nf];
437:   prob->offDerCohesive[1][Nf] = prob->offDerCohesive[0][Nf];
438:   /* Allocate works space */
439:   NsMax = 2; /* A non-cohesive discretizations can be used on a cohesive cell, so we need this extra workspace for all DS */
440:   PetscMalloc3(NsMax*prob->totComp,&prob->u,NsMax*prob->totComp,&prob->u_t,NsMax*prob->totComp*dimEmbed + (hasH ? NsMax*prob->totComp*dimEmbed*dimEmbed : 0),&prob->u_x);
441:   PetscMalloc5(dimEmbed,&prob->x,NbMax*NcMax,&prob->basisReal,NbMax*NcMax*dimEmbed,&prob->basisDerReal,NbMax*NcMax,&prob->testReal,NbMax*NcMax*dimEmbed,&prob->testDerReal);
442:   PetscMalloc6(NsMax*NqMax*NcMax,&prob->f0,NsMax*NqMax*NcMax*dimEmbed,&prob->f1,
443:                       NsMax*NsMax*NqMax*NcMax*NcMax,&prob->g0,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g1,
444:                       NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g2,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed*dimEmbed,&prob->g3);
445:   if (prob->ops->setup) (*prob->ops->setup)(prob);
446:   prob->setup = PETSC_TRUE;
447:   return 0;
448: }

450: static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
451: {
452:   PetscFree2(prob->Nc,prob->Nb);
453:   PetscFree2(prob->off,prob->offDer);
454:   PetscFree6(prob->offCohesive[0],prob->offCohesive[1],prob->offCohesive[2],prob->offDerCohesive[0],prob->offDerCohesive[1],prob->offDerCohesive[2]);
455:   PetscFree2(prob->T,prob->Tf);
456:   PetscFree3(prob->u,prob->u_t,prob->u_x);
457:   PetscFree5(prob->x,prob->basisReal, prob->basisDerReal,prob->testReal,prob->testDerReal);
458:   PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);
459:   return 0;
460: }

462: static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
463: {
464:   PetscObject      *tmpd;
465:   PetscBool        *tmpi;
466:   PetscInt         *tmpk;
467:   PetscBool        *tmpc;
468:   PetscPointFunc   *tmpup;
469:   PetscSimplePointFunc *tmpexactSol,  *tmpexactSol_t;
470:   void                **tmpexactCtx, **tmpexactCtx_t;
471:   void            **tmpctx;
472:   PetscInt          Nf = prob->Nf, f;

474:   if (Nf >= NfNew) return 0;
475:   prob->setup = PETSC_FALSE;
476:   PetscDSDestroyStructs_Static(prob);
477:   PetscMalloc4(NfNew, &tmpd, NfNew, &tmpi, NfNew, &tmpc, NfNew, &tmpk);
478:   for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpi[f] = prob->implicit[f]; tmpc[f] = prob->cohesive[f]; tmpk[f] = prob->jetDegree[f];}
479:   for (f = Nf; f < NfNew; ++f) {tmpd[f] = NULL; tmpi[f] = PETSC_TRUE, tmpc[f] = PETSC_FALSE; tmpk[f] = 1;}
480:   PetscFree4(prob->disc, prob->implicit, prob->cohesive, prob->jetDegree);
481:   PetscWeakFormSetNumFields(prob->wf, NfNew);
482:   prob->Nf        = NfNew;
483:   prob->disc      = tmpd;
484:   prob->implicit  = tmpi;
485:   prob->cohesive  = tmpc;
486:   prob->jetDegree = tmpk;
487:   PetscCalloc2(NfNew, &tmpup, NfNew, &tmpctx);
488:   for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
489:   for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
490:   for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
491:   for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
492:   PetscFree2(prob->update, prob->ctx);
493:   prob->update = tmpup;
494:   prob->ctx = tmpctx;
495:   PetscCalloc4(NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t);
496:   for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
497:   for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
498:   for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
499:   for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
500:   for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
501:   for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
502:   for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
503:   for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
504:   PetscFree4(prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t);
505:   prob->exactSol = tmpexactSol;
506:   prob->exactCtx = tmpexactCtx;
507:   prob->exactSol_t = tmpexactSol_t;
508:   prob->exactCtx_t = tmpexactCtx_t;
509:   return 0;
510: }

512: /*@
513:   PetscDSDestroy - Destroys a PetscDS object

515:   Collective on prob

517:   Input Parameter:
518: . prob - the PetscDS object to destroy

520:   Level: developer

522: .seealso PetscDSView()
523: @*/
524: PetscErrorCode PetscDSDestroy(PetscDS *ds)
525: {
526:   PetscInt       f;

528:   if (!*ds) return 0;

531:   if (--((PetscObject)(*ds))->refct > 0) {*ds = NULL; return 0;}
532:   ((PetscObject) (*ds))->refct = 0;
533:   if ((*ds)->subprobs) {
534:     PetscInt dim, d;

536:     PetscDSGetSpatialDimension(*ds, &dim);
537:     for (d = 0; d < dim; ++d) PetscDSDestroy(&(*ds)->subprobs[d]);
538:   }
539:   PetscFree((*ds)->subprobs);
540:   PetscDSDestroyStructs_Static(*ds);
541:   for (f = 0; f < (*ds)->Nf; ++f) {
542:     PetscObjectDereference((*ds)->disc[f]);
543:   }
544:   PetscFree4((*ds)->disc, (*ds)->implicit, (*ds)->cohesive, (*ds)->jetDegree);
545:   PetscWeakFormDestroy(&(*ds)->wf);
546:   PetscFree2((*ds)->update,(*ds)->ctx);
547:   PetscFree4((*ds)->exactSol,(*ds)->exactCtx,(*ds)->exactSol_t,(*ds)->exactCtx_t);
548:   if ((*ds)->ops->destroy) (*(*ds)->ops->destroy)(*ds);
549:   PetscDSDestroyBoundary(*ds);
550:   PetscFree((*ds)->constants);
551:   PetscHeaderDestroy(ds);
552:   return 0;
553: }

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

558:   Collective

560:   Input Parameter:
561: . comm - The communicator for the PetscDS object

563:   Output Parameter:
564: . ds   - The PetscDS object

566:   Level: beginner

568: .seealso: PetscDSSetType(), PETSCDSBASIC
569: @*/
570: PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *ds)
571: {
572:   PetscDS        p;

575:   *ds  = NULL;
576:   PetscDSInitializePackage();

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

580:   p->Nf           = 0;
581:   p->setup        = PETSC_FALSE;
582:   p->numConstants = 0;
583:   p->constants    = NULL;
584:   p->dimEmbed     = -1;
585:   p->useJacPre    = PETSC_TRUE;
586:   PetscWeakFormCreate(comm, &p->wf);

588:   *ds = p;
589:   return 0;
590: }

592: /*@
593:   PetscDSGetNumFields - Returns the number of fields in the DS

595:   Not collective

597:   Input Parameter:
598: . prob - The PetscDS object

600:   Output Parameter:
601: . Nf - The number of fields

603:   Level: beginner

605: .seealso: PetscDSGetSpatialDimension(), PetscDSCreate()
606: @*/
607: PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
608: {
611:   *Nf = prob->Nf;
612:   return 0;
613: }

615: /*@
616:   PetscDSGetSpatialDimension - Returns the spatial dimension of the DS, meaning the topological dimension of the discretizations

618:   Not collective

620:   Input Parameter:
621: . prob - The PetscDS object

623:   Output Parameter:
624: . dim - The spatial dimension

626:   Level: beginner

628: .seealso: PetscDSGetCoordinateDimension(), PetscDSGetNumFields(), PetscDSCreate()
629: @*/
630: PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
631: {
634:   *dim = 0;
635:   if (prob->Nf) {
636:     PetscObject  obj;
637:     PetscClassId id;

639:     PetscDSGetDiscretization(prob, 0, &obj);
640:     if (obj) {
641:       PetscObjectGetClassId(obj, &id);
642:       if (id == PETSCFE_CLASSID)      PetscFEGetSpatialDimension((PetscFE) obj, dim);
643:       else if (id == PETSCFV_CLASSID) PetscFVGetSpatialDimension((PetscFV) obj, dim);
644:       else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
645:     }
646:   }
647:   return 0;
648: }

650: /*@
651:   PetscDSGetCoordinateDimension - Returns the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded

653:   Not collective

655:   Input Parameter:
656: . prob - The PetscDS object

658:   Output Parameter:
659: . dimEmbed - The coordinate dimension

661:   Level: beginner

663: .seealso: PetscDSSetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
664: @*/
665: PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
666: {
670:   *dimEmbed = prob->dimEmbed;
671:   return 0;
672: }

674: /*@
675:   PetscDSSetCoordinateDimension - Set the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded

677:   Logically collective on prob

679:   Input Parameters:
680: + prob - The PetscDS object
681: - dimEmbed - The coordinate dimension

683:   Level: beginner

685: .seealso: PetscDSGetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
686: @*/
687: PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
688: {
691:   prob->dimEmbed = dimEmbed;
692:   return 0;
693: }

695: /*@
696:   PetscDSIsCohesive - Returns the flag indicating that this DS is for a cohesive cell

698:   Not collective

700:   Input Parameter:
701: . ds - The PetscDS object

703:   Output Parameter:
704: . isCohesive - The flag

706:   Level: developer

708: .seealso: PetscDSGetNumCohesive(), PetscDSGetCohesive(), PetscDSSetCohesive(), PetscDSCreate()
709: @*/
710: PetscErrorCode PetscDSIsCohesive(PetscDS ds, PetscBool *isCohesive)
711: {
714:   *isCohesive = ds->isCohesive;
715:   return 0;
716: }

718: /*@
719:   PetscDSGetNumCohesive - Returns the numer of cohesive fields, meaning those defined on the interior of a cohesive cell

721:   Not collective

723:   Input Parameter:
724: . ds - The PetscDS object

726:   Output Parameter:
727: . numCohesive - The number of cohesive fields

729:   Level: developer

731: .seealso: PetscDSSetCohesive(), PetscDSCreate()
732: @*/
733: PetscErrorCode PetscDSGetNumCohesive(PetscDS ds, PetscInt *numCohesive)
734: {
735:   PetscInt f;

739:   *numCohesive = 0;
740:   for (f = 0;  f < ds->Nf; ++f) *numCohesive += ds->cohesive[f] ? 1 : 0;
741:   return 0;
742: }

744: /*@
745:   PetscDSGetCohesive - Returns the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell

747:   Not collective

749:   Input Parameters:
750: + ds - The PetscDS object
751: - f  - The field index

753:   Output Parameter:
754: . isCohesive - The flag

756:   Level: developer

758: .seealso: PetscDSSetCohesive(), PetscDSIsCohesive(), PetscDSCreate()
759: @*/
760: PetscErrorCode PetscDSGetCohesive(PetscDS ds, PetscInt f, PetscBool *isCohesive)
761: {
765:   *isCohesive = ds->cohesive[f];
766:   return 0;
767: }

769: /*@
770:   PetscDSSetCohesive - Set the flag indicating that a field is cohesive, meaning it is defined on the interior of a cohesive cell

772:   Not collective

774:   Input Parameters:
775: + ds - The PetscDS object
776: . f  - The field index
777: - isCohesive - The flag for a cohesive field

779:   Level: developer

781: .seealso: PetscDSGetCohesive(), PetscDSIsCohesive(), PetscDSCreate()
782: @*/
783: PetscErrorCode PetscDSSetCohesive(PetscDS ds, PetscInt f, PetscBool isCohesive)
784: {
785:   PetscInt i;

789:   ds->cohesive[f] = isCohesive;
790:   ds->isCohesive = PETSC_FALSE;
791:   for (i = 0; i < ds->Nf; ++i) ds->isCohesive = ds->isCohesive || ds->cohesive[f] ? PETSC_TRUE : PETSC_FALSE;
792:   return 0;
793: }

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

798:   Not collective

800:   Input Parameter:
801: . prob - The PetscDS object

803:   Output Parameter:
804: . dim - The total problem dimension

806:   Level: beginner

808: .seealso: PetscDSGetNumFields(), PetscDSCreate()
809: @*/
810: PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
811: {
813:   PetscDSSetUp(prob);
815:   *dim = prob->totDim;
816:   return 0;
817: }

819: /*@
820:   PetscDSGetTotalComponents - Returns the total number of components in this system

822:   Not collective

824:   Input Parameter:
825: . prob - The PetscDS object

827:   Output Parameter:
828: . dim - The total number of components

830:   Level: beginner

832: .seealso: PetscDSGetNumFields(), PetscDSCreate()
833: @*/
834: PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
835: {
837:   PetscDSSetUp(prob);
839:   *Nc = prob->totComp;
840:   return 0;
841: }

843: /*@
844:   PetscDSGetDiscretization - Returns the discretization object for the given field

846:   Not collective

848:   Input Parameters:
849: + prob - The PetscDS object
850: - f - The field number

852:   Output Parameter:
853: . disc - The discretization object

855:   Level: beginner

857: .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
858: @*/
859: PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
860: {
865:   *disc = prob->disc[f];
866:   return 0;
867: }

869: /*@
870:   PetscDSSetDiscretization - Sets the discretization object for the given field

872:   Not collective

874:   Input Parameters:
875: + prob - The PetscDS object
876: . f - The field number
877: - disc - The discretization object

879:   Level: beginner

881: .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
882: @*/
883: PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
884: {
888:   PetscDSEnlarge_Static(prob, f+1);
889:   PetscObjectDereference(prob->disc[f]);
890:   prob->disc[f] = disc;
891:   PetscObjectReference(disc);
892:   if (disc) {
893:     PetscClassId id;

895:     PetscObjectGetClassId(disc, &id);
896:     if (id == PETSCFE_CLASSID) {
897:       PetscDSSetImplicit(prob, f, PETSC_TRUE);
898:     } else if (id == PETSCFV_CLASSID) {
899:       PetscDSSetImplicit(prob, f, PETSC_FALSE);
900:     }
901:     PetscDSSetJetDegree(prob, f, 1);
902:   }
903:   return 0;
904: }

906: /*@
907:   PetscDSGetWeakForm - Returns the weak form object

909:   Not collective

911:   Input Parameter:
912: . ds - The PetscDS object

914:   Output Parameter:
915: . wf - The weak form object

917:   Level: beginner

919: .seealso: PetscDSSetWeakForm(), PetscDSGetNumFields(), PetscDSCreate()
920: @*/
921: PetscErrorCode PetscDSGetWeakForm(PetscDS ds, PetscWeakForm *wf)
922: {
925:   *wf = ds->wf;
926:   return 0;
927: }

929: /*@
930:   PetscDSSetWeakForm - Sets the weak form object

932:   Not collective

934:   Input Parameters:
935: + ds - The PetscDS object
936: - wf - The weak form object

938:   Level: beginner

940: .seealso: PetscDSGetWeakForm(), PetscDSGetNumFields(), PetscDSCreate()
941: @*/
942: PetscErrorCode PetscDSSetWeakForm(PetscDS ds, PetscWeakForm wf)
943: {
946:   PetscObjectDereference((PetscObject) ds->wf);
947:   ds->wf = wf;
948:   PetscObjectReference((PetscObject) wf);
949:   PetscWeakFormSetNumFields(wf, ds->Nf);
950:   return 0;
951: }

953: /*@
954:   PetscDSAddDiscretization - Adds a discretization object

956:   Not collective

958:   Input Parameters:
959: + prob - The PetscDS object
960: - disc - The boundary discretization object

962:   Level: beginner

964: .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
965: @*/
966: PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
967: {
968:   PetscDSSetDiscretization(prob, prob->Nf, disc);
969:   return 0;
970: }

972: /*@
973:   PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the DS

975:   Not collective

977:   Input Parameter:
978: . prob - The PetscDS object

980:   Output Parameter:
981: . q - The quadrature object

983: Level: intermediate

985: .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
986: @*/
987: PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
988: {
989:   PetscObject    obj;
990:   PetscClassId   id;

992:   *q = NULL;
993:   if (!prob->Nf) return 0;
994:   PetscDSGetDiscretization(prob, 0, &obj);
995:   PetscObjectGetClassId(obj, &id);
996:   if      (id == PETSCFE_CLASSID) PetscFEGetQuadrature((PetscFE) obj, q);
997:   else if (id == PETSCFV_CLASSID) PetscFVGetQuadrature((PetscFV) obj, q);
998:   else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
999:   return 0;
1000: }

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

1005:   Not collective

1007:   Input Parameters:
1008: + prob - The PetscDS object
1009: - f - The field number

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

1014:   Level: developer

1016: .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1017: @*/
1018: PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
1019: {
1023:   *implicit = prob->implicit[f];
1024:   return 0;
1025: }

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

1030:   Not collective

1032:   Input Parameters:
1033: + prob - The PetscDS object
1034: . f - The field number
1035: - implicit - The flag indicating what kind of solve to use for this field

1037:   Level: developer

1039: .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1040: @*/
1041: PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
1042: {
1045:   prob->implicit[f] = implicit;
1046:   return 0;
1047: }

1049: /*@
1050:   PetscDSGetJetDegree - Returns the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.

1052:   Not collective

1054:   Input Parameters:
1055: + ds - The PetscDS object
1056: - f  - The field number

1058:   Output Parameter:
1059: . k  - The highest derivative we need to tabulate

1061:   Level: developer

1063: .seealso: PetscDSSetJetDegree(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1064: @*/
1065: PetscErrorCode PetscDSGetJetDegree(PetscDS ds, PetscInt f, PetscInt *k)
1066: {
1070:   *k = ds->jetDegree[f];
1071:   return 0;
1072: }

1074: /*@
1075:   PetscDSSetJetDegree - Set the highest derivative for this field equation, or the k-jet that the discretization needs to tabulate.

1077:   Not collective

1079:   Input Parameters:
1080: + ds - The PetscDS object
1081: . f  - The field number
1082: - k  - The highest derivative we need to tabulate

1084:   Level: developer

1086: .seealso: PetscDSGetJetDegree(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
1087: @*/
1088: PetscErrorCode PetscDSSetJetDegree(PetscDS ds, PetscInt f, PetscInt k)
1089: {
1092:   ds->jetDegree[f] = k;
1093:   return 0;
1094: }

1096: PetscErrorCode PetscDSGetObjective(PetscDS ds, PetscInt f,
1097:                                    void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1098:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1099:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1100:                                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1101: {
1102:   PetscPointFunc *tmp;
1103:   PetscInt        n;

1108:   PetscWeakFormGetObjective(ds->wf, NULL, 0, f, 0, &n, &tmp);
1109:   *obj = tmp ? tmp[0] : NULL;
1110:   return 0;
1111: }

1113: PetscErrorCode PetscDSSetObjective(PetscDS ds, PetscInt f,
1114:                                    void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1115:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1116:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1117:                                                PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1118: {
1122:   PetscWeakFormSetIndexObjective(ds->wf, NULL, 0, f, 0, 0, obj);
1123:   return 0;
1124: }

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

1129:   Not collective

1131:   Input Parameters:
1132: + ds - The PetscDS
1133: - f  - The test field number

1135:   Output Parameters:
1136: + f0 - integrand for the test function term
1137: - f1 - integrand for the test function gradient term

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

1141:   \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)

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

1145: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1146: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1147: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1148: $    PetscReal t, const PetscReal x[], PetscScalar f0[])

1150: + dim - the spatial dimension
1151: . Nf - the number of fields
1152: . uOff - the offset into u[] and u_t[] for each field
1153: . uOff_x - the offset into u_x[] for each field
1154: . u - each field evaluated at the current point
1155: . u_t - the time derivative of each field evaluated at the current point
1156: . u_x - the gradient of each field evaluated at the current point
1157: . aOff - the offset into a[] and a_t[] for each auxiliary field
1158: . aOff_x - the offset into a_x[] for each auxiliary field
1159: . a - each auxiliary field evaluated at the current point
1160: . a_t - the time derivative of each auxiliary field evaluated at the current point
1161: . a_x - the gradient of auxiliary each field evaluated at the current point
1162: . t - current time
1163: . x - coordinates of the current point
1164: . numConstants - number of constant parameters
1165: . constants - constant parameters
1166: - f0 - output values at the current point

1168:   Level: intermediate

1170: .seealso: PetscDSSetResidual()
1171: @*/
1172: PetscErrorCode PetscDSGetResidual(PetscDS ds, PetscInt f,
1173:                                   void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1174:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1175:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1176:                                               PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1177:                                   void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1178:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1179:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1180:                                               PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1181: {
1182:   PetscPointFunc *tmp0, *tmp1;
1183:   PetscInt        n0, n1;

1187:   PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1);
1188:   *f0  = tmp0 ? tmp0[0] : NULL;
1189:   *f1  = tmp1 ? tmp1[0] : NULL;
1190:   return 0;
1191: }

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

1196:   Not collective

1198:   Input Parameters:
1199: + ds - The PetscDS
1200: . f  - The test field number
1201: . f0 - integrand for the test function term
1202: - f1 - integrand for the test function gradient term

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

1206:   \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)

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

1210: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1211: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1212: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1213: $    PetscReal t, const PetscReal x[], PetscScalar f0[])

1215: + dim - the spatial dimension
1216: . Nf - the number of fields
1217: . uOff - the offset into u[] and u_t[] for each field
1218: . uOff_x - the offset into u_x[] for each field
1219: . u - each field evaluated at the current point
1220: . u_t - the time derivative of each field evaluated at the current point
1221: . u_x - the gradient of each field evaluated at the current point
1222: . aOff - the offset into a[] and a_t[] for each auxiliary field
1223: . aOff_x - the offset into a_x[] for each auxiliary field
1224: . a - each auxiliary field evaluated at the current point
1225: . a_t - the time derivative of each auxiliary field evaluated at the current point
1226: . a_x - the gradient of auxiliary each field evaluated at the current point
1227: . t - current time
1228: . x - coordinates of the current point
1229: . numConstants - number of constant parameters
1230: . constants - constant parameters
1231: - f0 - output values at the current point

1233:   Level: intermediate

1235: .seealso: PetscDSGetResidual()
1236: @*/
1237: PetscErrorCode PetscDSSetResidual(PetscDS ds, PetscInt f,
1238:                                   void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1239:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1240:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1241:                                              PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1242:                                   void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1243:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1244:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1245:                                              PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1246: {
1251:   PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1);
1252:   return 0;
1253: }

1255: /*@C
1256:   PetscDSGetRHSResidual - Get the pointwise RHS residual function for explicit timestepping for a given test field

1258:   Not collective

1260:   Input Parameters:
1261: + ds - The PetscDS
1262: - f  - The test field number

1264:   Output Parameters:
1265: + f0 - integrand for the test function term
1266: - f1 - integrand for the test function gradient term

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

1270:   \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)

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

1274: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1275: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1276: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1277: $    PetscReal t, const PetscReal x[], PetscScalar f0[])

1279: + dim - the spatial dimension
1280: . Nf - the number of fields
1281: . uOff - the offset into u[] and u_t[] for each field
1282: . uOff_x - the offset into u_x[] for each field
1283: . u - each field evaluated at the current point
1284: . u_t - the time derivative of each field evaluated at the current point
1285: . u_x - the gradient of each field evaluated at the current point
1286: . aOff - the offset into a[] and a_t[] for each auxiliary field
1287: . aOff_x - the offset into a_x[] for each auxiliary field
1288: . a - each auxiliary field evaluated at the current point
1289: . a_t - the time derivative of each auxiliary field evaluated at the current point
1290: . a_x - the gradient of auxiliary each field evaluated at the current point
1291: . t - current time
1292: . x - coordinates of the current point
1293: . numConstants - number of constant parameters
1294: . constants - constant parameters
1295: - f0 - output values at the current point

1297:   Level: intermediate

1299: .seealso: PetscDSSetRHSResidual()
1300: @*/
1301: PetscErrorCode PetscDSGetRHSResidual(PetscDS ds, PetscInt f,
1302:                                      void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1303:                                                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1304:                                                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1305:                                                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1306:                                      void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1307:                                                  const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1308:                                                  const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1309:                                                  PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1310: {
1311:   PetscPointFunc *tmp0, *tmp1;
1312:   PetscInt        n0, n1;

1316:   PetscWeakFormGetResidual(ds->wf, NULL, 0, f, 100, &n0, &tmp0, &n1, &tmp1);
1317:   *f0  = tmp0 ? tmp0[0] : NULL;
1318:   *f1  = tmp1 ? tmp1[0] : NULL;
1319:   return 0;
1320: }

1322: /*@C
1323:   PetscDSSetRHSResidual - Set the pointwise residual function for explicit timestepping for a given test field

1325:   Not collective

1327:   Input Parameters:
1328: + ds - The PetscDS
1329: . f  - The test field number
1330: . f0 - integrand for the test function term
1331: - f1 - integrand for the test function gradient term

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

1335:   \int_\Omega \phi f_0(u, u_t, \nabla u, x, t) + \nabla\phi \cdot {\vec f}_1(u, u_t, \nabla u, x, t)

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

1339: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1340: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1341: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1342: $    PetscReal t, const PetscReal x[], PetscScalar f0[])

1344: + dim - the spatial dimension
1345: . Nf - the number of fields
1346: . uOff - the offset into u[] and u_t[] for each field
1347: . uOff_x - the offset into u_x[] for each field
1348: . u - each field evaluated at the current point
1349: . u_t - the time derivative of each field evaluated at the current point
1350: . u_x - the gradient of each field evaluated at the current point
1351: . aOff - the offset into a[] and a_t[] for each auxiliary field
1352: . aOff_x - the offset into a_x[] for each auxiliary field
1353: . a - each auxiliary field evaluated at the current point
1354: . a_t - the time derivative of each auxiliary field evaluated at the current point
1355: . a_x - the gradient of auxiliary each field evaluated at the current point
1356: . t - current time
1357: . x - coordinates of the current point
1358: . numConstants - number of constant parameters
1359: . constants - constant parameters
1360: - f0 - output values at the current point

1362:   Level: intermediate

1364: .seealso: PetscDSGetResidual()
1365: @*/
1366: PetscErrorCode PetscDSSetRHSResidual(PetscDS ds, PetscInt f,
1367:                                      void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1368:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1369:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1370:                                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1371:                                      void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1372:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1373:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1374:                                                 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1375: {
1380:   PetscWeakFormSetIndexResidual(ds->wf, NULL, 0, f, 100, 0, f0, 0, f1);
1381:   return 0;
1382: }

1384: /*@C
1385:   PetscDSHasJacobian - Signals that Jacobian functions have been set

1387:   Not collective

1389:   Input Parameter:
1390: . prob - The PetscDS

1392:   Output Parameter:
1393: . hasJac - flag that pointwise function for the Jacobian has been set

1395:   Level: intermediate

1397: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1398: @*/
1399: PetscErrorCode PetscDSHasJacobian(PetscDS ds, PetscBool *hasJac)
1400: {
1402:   PetscWeakFormHasJacobian(ds->wf, hasJac);
1403:   return 0;
1404: }

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

1409:   Not collective

1411:   Input Parameters:
1412: + ds - The PetscDS
1413: . f  - The test field number
1414: - g  - The field number

1416:   Output Parameters:
1417: + g0 - integrand for the test and basis function term
1418: . g1 - integrand for the test function and basis function gradient term
1419: . g2 - integrand for the test function gradient and basis function term
1420: - g3 - integrand for the test function gradient and basis function gradient term

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

1424:   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi

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

1428: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1429: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1430: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1431: $    PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])

1433: + dim - the spatial dimension
1434: . Nf - the number of fields
1435: . uOff - the offset into u[] and u_t[] for each field
1436: . uOff_x - the offset into u_x[] for each field
1437: . u - each field evaluated at the current point
1438: . u_t - the time derivative of each field evaluated at the current point
1439: . u_x - the gradient of each field evaluated at the current point
1440: . aOff - the offset into a[] and a_t[] for each auxiliary field
1441: . aOff_x - the offset into a_x[] for each auxiliary field
1442: . a - each auxiliary field evaluated at the current point
1443: . a_t - the time derivative of each auxiliary field evaluated at the current point
1444: . a_x - the gradient of auxiliary each field evaluated at the current point
1445: . t - current time
1446: . u_tShift - the multiplier a for dF/dU_t
1447: . x - coordinates of the current point
1448: . numConstants - number of constant parameters
1449: . constants - constant parameters
1450: - g0 - output values at the current point

1452:   Level: intermediate

1454: .seealso: PetscDSSetJacobian()
1455: @*/
1456: PetscErrorCode PetscDSGetJacobian(PetscDS ds, PetscInt f, PetscInt g,
1457:                                   void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1458:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1459:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1460:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1461:                                   void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1462:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1463:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1464:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1465:                                   void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1466:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1467:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1468:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1469:                                   void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1470:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1471:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1472:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1473: {
1474:   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
1475:   PetscInt       n0, n1, n2, n3;

1480:   PetscWeakFormGetJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
1481:   *g0  = tmp0 ? tmp0[0] : NULL;
1482:   *g1  = tmp1 ? tmp1[0] : NULL;
1483:   *g2  = tmp2 ? tmp2[0] : NULL;
1484:   *g3  = tmp3 ? tmp3[0] : NULL;
1485:   return 0;
1486: }

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

1491:   Not collective

1493:   Input Parameters:
1494: + ds - The PetscDS
1495: . f  - The test field number
1496: . g  - The field number
1497: . g0 - integrand for the test and basis function term
1498: . g1 - integrand for the test function and basis function gradient term
1499: . g2 - integrand for the test function gradient and basis function term
1500: - g3 - integrand for the test function gradient and basis function gradient term

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

1504:   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi

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

1508: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1509: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1510: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1511: $    PetscReal t, const PetscReal x[], PetscScalar g0[])

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

1532:   Level: intermediate

1534: .seealso: PetscDSGetJacobian()
1535: @*/
1536: PetscErrorCode PetscDSSetJacobian(PetscDS ds, PetscInt f, PetscInt g,
1537:                                   void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1538:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1539:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1540:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1541:                                   void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1542:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1543:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1544:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1545:                                   void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1546:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1547:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1548:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1549:                                   void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1550:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1551:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1552:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1553: {
1561:   PetscWeakFormSetIndexJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
1562:   return 0;
1563: }

1565: /*@C
1566:   PetscDSUseJacobianPreconditioner - Whether to construct a Jacobian preconditioner

1568:   Not collective

1570:   Input Parameters:
1571: + prob - The PetscDS
1572: - useJacPre - flag that enables construction of a Jacobian preconditioner

1574:   Level: intermediate

1576: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1577: @*/
1578: PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1579: {
1581:   prob->useJacPre = useJacPre;
1582:   return 0;
1583: }

1585: /*@C
1586:   PetscDSHasJacobianPreconditioner - Signals that a Jacobian preconditioner matrix has been set

1588:   Not collective

1590:   Input Parameter:
1591: . prob - The PetscDS

1593:   Output Parameter:
1594: . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set

1596:   Level: intermediate

1598: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1599: @*/
1600: PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS ds, PetscBool *hasJacPre)
1601: {
1603:   *hasJacPre = PETSC_FALSE;
1604:   if (!ds->useJacPre) return 0;
1605:   PetscWeakFormHasJacobianPreconditioner(ds->wf, hasJacPre);
1606:   return 0;
1607: }

1609: /*@C
1610:   PetscDSGetJacobianPreconditioner - Get the pointwise Jacobian preconditioner function for given test and basis field. If this is missing, the system matrix is used to build the preconditioner.

1612:   Not collective

1614:   Input Parameters:
1615: + ds - The PetscDS
1616: . f  - The test field number
1617: - g  - The field number

1619:   Output Parameters:
1620: + g0 - integrand for the test and basis function term
1621: . g1 - integrand for the test function and basis function gradient term
1622: . g2 - integrand for the test function gradient and basis function term
1623: - g3 - integrand for the test function gradient and basis function gradient term

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

1627:   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi

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

1631: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1632: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1633: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1634: $    PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])

1636: + dim - the spatial dimension
1637: . Nf - the number of fields
1638: . uOff - the offset into u[] and u_t[] for each field
1639: . uOff_x - the offset into u_x[] for each field
1640: . u - each field evaluated at the current point
1641: . u_t - the time derivative of each field evaluated at the current point
1642: . u_x - the gradient of each field evaluated at the current point
1643: . aOff - the offset into a[] and a_t[] for each auxiliary field
1644: . aOff_x - the offset into a_x[] for each auxiliary field
1645: . a - each auxiliary field evaluated at the current point
1646: . a_t - the time derivative of each auxiliary field evaluated at the current point
1647: . a_x - the gradient of auxiliary each field evaluated at the current point
1648: . t - current time
1649: . u_tShift - the multiplier a for dF/dU_t
1650: . x - coordinates of the current point
1651: . numConstants - number of constant parameters
1652: . constants - constant parameters
1653: - g0 - output values at the current point

1655:   Level: intermediate

1657: .seealso: PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1658: @*/
1659: PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
1660:                                   void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1661:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1662:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1663:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1664:                                   void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1665:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1666:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1667:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1668:                                   void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1669:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1670:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1671:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1672:                                   void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1673:                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1674:                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1675:                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1676: {
1677:   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
1678:   PetscInt       n0, n1, n2, n3;

1683:   PetscWeakFormGetJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
1684:   *g0  = tmp0 ? tmp0[0] : NULL;
1685:   *g1  = tmp1 ? tmp1[0] : NULL;
1686:   *g2  = tmp2 ? tmp2[0] : NULL;
1687:   *g3  = tmp3 ? tmp3[0] : NULL;
1688:   return 0;
1689: }

1691: /*@C
1692:   PetscDSSetJacobianPreconditioner - Set the pointwise Jacobian preconditioner function for given test and basis fields. If this is missing, the system matrix is used to build the preconditioner.

1694:   Not collective

1696:   Input Parameters:
1697: + ds - The PetscDS
1698: . f  - The test field number
1699: . g  - The field number
1700: . g0 - integrand for the test and basis function term
1701: . g1 - integrand for the test function and basis function gradient term
1702: . g2 - integrand for the test function gradient and basis function term
1703: - g3 - integrand for the test function gradient and basis function gradient term

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

1707:   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi

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

1711: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1712: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1713: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1714: $    PetscReal t, const PetscReal x[], PetscScalar g0[])

1716: + dim - the spatial dimension
1717: . Nf - the number of fields
1718: . uOff - the offset into u[] and u_t[] for each field
1719: . uOff_x - the offset into u_x[] for each field
1720: . u - each field evaluated at the current point
1721: . u_t - the time derivative of each field evaluated at the current point
1722: . u_x - the gradient of each field evaluated at the current point
1723: . aOff - the offset into a[] and a_t[] for each auxiliary field
1724: . aOff_x - the offset into a_x[] for each auxiliary field
1725: . a - each auxiliary field evaluated at the current point
1726: . a_t - the time derivative of each auxiliary field evaluated at the current point
1727: . a_x - the gradient of auxiliary each field evaluated at the current point
1728: . t - current time
1729: . u_tShift - the multiplier a for dF/dU_t
1730: . x - coordinates of the current point
1731: . numConstants - number of constant parameters
1732: . constants - constant parameters
1733: - g0 - output values at the current point

1735:   Level: intermediate

1737: .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobian()
1738: @*/
1739: PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
1740:                                   void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1741:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1742:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1743:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1744:                                   void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1745:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1746:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1747:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1748:                                   void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1749:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1750:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1751:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1752:                                   void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1753:                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1754:                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1755:                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1756: {
1764:   PetscWeakFormSetIndexJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
1765:   return 0;
1766: }

1768: /*@C
1769:   PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set

1771:   Not collective

1773:   Input Parameter:
1774: . ds - The PetscDS

1776:   Output Parameter:
1777: . hasDynJac - flag that pointwise function for dynamic Jacobian has been set

1779:   Level: intermediate

1781: .seealso: PetscDSGetDynamicJacobian(), PetscDSSetDynamicJacobian(), PetscDSGetJacobian()
1782: @*/
1783: PetscErrorCode PetscDSHasDynamicJacobian(PetscDS ds, PetscBool *hasDynJac)
1784: {
1786:   PetscWeakFormHasDynamicJacobian(ds->wf, hasDynJac);
1787:   return 0;
1788: }

1790: /*@C
1791:   PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field

1793:   Not collective

1795:   Input Parameters:
1796: + ds - The PetscDS
1797: . f  - The test field number
1798: - g  - The field number

1800:   Output Parameters:
1801: + g0 - integrand for the test and basis function term
1802: . g1 - integrand for the test function and basis function gradient term
1803: . g2 - integrand for the test function gradient and basis function term
1804: - g3 - integrand for the test function gradient and basis function gradient term

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

1808:   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi

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

1812: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1813: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1814: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1815: $    PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])

1817: + dim - the spatial dimension
1818: . Nf - the number of fields
1819: . uOff - the offset into u[] and u_t[] for each field
1820: . uOff_x - the offset into u_x[] for each field
1821: . u - each field evaluated at the current point
1822: . u_t - the time derivative of each field evaluated at the current point
1823: . u_x - the gradient of each field evaluated at the current point
1824: . aOff - the offset into a[] and a_t[] for each auxiliary field
1825: . aOff_x - the offset into a_x[] for each auxiliary field
1826: . a - each auxiliary field evaluated at the current point
1827: . a_t - the time derivative of each auxiliary field evaluated at the current point
1828: . a_x - the gradient of auxiliary each field evaluated at the current point
1829: . t - current time
1830: . u_tShift - the multiplier a for dF/dU_t
1831: . x - coordinates of the current point
1832: . numConstants - number of constant parameters
1833: . constants - constant parameters
1834: - g0 - output values at the current point

1836:   Level: intermediate

1838: .seealso: PetscDSSetJacobian()
1839: @*/
1840: PetscErrorCode PetscDSGetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g,
1841:                                          void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1842:                                                      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1843:                                                      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1844:                                                      PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1845:                                          void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1846:                                                      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1847:                                                      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1848:                                                      PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1849:                                          void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1850:                                                      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1851:                                                      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1852:                                                      PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1853:                                          void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1854:                                                      const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1855:                                                      const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1856:                                                      PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1857: {
1858:   PetscPointJac *tmp0, *tmp1, *tmp2, *tmp3;
1859:   PetscInt       n0, n1, n2, n3;

1864:   PetscWeakFormGetDynamicJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
1865:   *g0  = tmp0 ? tmp0[0] : NULL;
1866:   *g1  = tmp1 ? tmp1[0] : NULL;
1867:   *g2  = tmp2 ? tmp2[0] : NULL;
1868:   *g3  = tmp3 ? tmp3[0] : NULL;
1869:   return 0;
1870: }

1872: /*@C
1873:   PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields

1875:   Not collective

1877:   Input Parameters:
1878: + ds - The PetscDS
1879: . f  - The test field number
1880: . g  - The field number
1881: . g0 - integrand for the test and basis function term
1882: . g1 - integrand for the test function and basis function gradient term
1883: . g2 - integrand for the test function gradient and basis function term
1884: - g3 - integrand for the test function gradient and basis function gradient term

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

1888:   \int_\Omega \phi g_0(u, u_t, \nabla u, x, t) \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \nabla \psi

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

1892: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1893: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1894: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1895: $    PetscReal t, const PetscReal x[], PetscScalar g0[])

1897: + dim - the spatial dimension
1898: . Nf - the number of fields
1899: . uOff - the offset into u[] and u_t[] for each field
1900: . uOff_x - the offset into u_x[] for each field
1901: . u - each field evaluated at the current point
1902: . u_t - the time derivative of each field evaluated at the current point
1903: . u_x - the gradient of each field evaluated at the current point
1904: . aOff - the offset into a[] and a_t[] for each auxiliary field
1905: . aOff_x - the offset into a_x[] for each auxiliary field
1906: . a - each auxiliary field evaluated at the current point
1907: . a_t - the time derivative of each auxiliary field evaluated at the current point
1908: . a_x - the gradient of auxiliary each field evaluated at the current point
1909: . t - current time
1910: . u_tShift - the multiplier a for dF/dU_t
1911: . x - coordinates of the current point
1912: . numConstants - number of constant parameters
1913: . constants - constant parameters
1914: - g0 - output values at the current point

1916:   Level: intermediate

1918: .seealso: PetscDSGetJacobian()
1919: @*/
1920: PetscErrorCode PetscDSSetDynamicJacobian(PetscDS ds, PetscInt f, PetscInt g,
1921:                                          void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1922:                                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1923:                                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1924:                                                     PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1925:                                          void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1926:                                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1927:                                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1928:                                                     PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1929:                                          void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1930:                                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1931:                                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1932:                                                     PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1933:                                          void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1934:                                                     const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1935:                                                     const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1936:                                                     PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1937: {
1945:   PetscWeakFormSetIndexDynamicJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
1946:   return 0;
1947: }

1949: /*@C
1950:   PetscDSGetRiemannSolver - Returns the Riemann solver for the given field

1952:   Not collective

1954:   Input Parameters:
1955: + ds - The PetscDS object
1956: - f  - The field number

1958:   Output Parameter:
1959: . r    - Riemann solver

1961:   Calling sequence for r:

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

1965: + dim  - The spatial dimension
1966: . Nf   - The number of fields
1967: . x    - The coordinates at a point on the interface
1968: . n    - The normal vector to the interface
1969: . uL   - The state vector to the left of the interface
1970: . uR   - The state vector to the right of the interface
1971: . flux - output array of flux through the interface
1972: . numConstants - number of constant parameters
1973: . constants - constant parameters
1974: - ctx  - optional user context

1976:   Level: intermediate

1978: .seealso: PetscDSSetRiemannSolver()
1979: @*/
1980: PetscErrorCode PetscDSGetRiemannSolver(PetscDS ds, PetscInt f,
1981:                                        void (**r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
1982: {
1983:   PetscRiemannFunc *tmp;
1984:   PetscInt          n;

1989:   PetscWeakFormGetRiemannSolver(ds->wf, NULL, 0, f, 0, &n, &tmp);
1990:   *r   = tmp ? tmp[0] : NULL;
1991:   return 0;
1992: }

1994: /*@C
1995:   PetscDSSetRiemannSolver - Sets the Riemann solver for the given field

1997:   Not collective

1999:   Input Parameters:
2000: + ds - The PetscDS object
2001: . f  - The field number
2002: - r  - Riemann solver

2004:   Calling sequence for r:

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

2008: + dim  - The spatial dimension
2009: . Nf   - The number of fields
2010: . x    - The coordinates at a point on the interface
2011: . n    - The normal vector to the interface
2012: . uL   - The state vector to the left of the interface
2013: . uR   - The state vector to the right of the interface
2014: . flux - output array of flux through the interface
2015: . numConstants - number of constant parameters
2016: . constants - constant parameters
2017: - ctx  - optional user context

2019:   Level: intermediate

2021: .seealso: PetscDSGetRiemannSolver()
2022: @*/
2023: PetscErrorCode PetscDSSetRiemannSolver(PetscDS ds, PetscInt f,
2024:                                        void (*r)(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscInt numConstants, const PetscScalar constants[], PetscScalar flux[], void *ctx))
2025: {
2029:   PetscWeakFormSetIndexRiemannSolver(ds->wf, NULL, 0, f, 0, 0, r);
2030:   return 0;
2031: }

2033: /*@C
2034:   PetscDSGetUpdate - Get the pointwise update function for a given field

2036:   Not collective

2038:   Input Parameters:
2039: + ds - The PetscDS
2040: - f  - The field number

2042:   Output Parameter:
2043: . update - update function

2045:   Note: The calling sequence for the callback update is given by:

2047: $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2048: $        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2049: $        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2050: $        PetscReal t, const PetscReal x[], PetscScalar uNew[])

2052: + dim - the spatial dimension
2053: . Nf - the number of fields
2054: . uOff - the offset into u[] and u_t[] for each field
2055: . uOff_x - the offset into u_x[] for each field
2056: . u - each field evaluated at the current point
2057: . u_t - the time derivative of each field evaluated at the current point
2058: . u_x - the gradient of each field evaluated at the current point
2059: . aOff - the offset into a[] and a_t[] for each auxiliary field
2060: . aOff_x - the offset into a_x[] for each auxiliary field
2061: . a - each auxiliary field evaluated at the current point
2062: . a_t - the time derivative of each auxiliary field evaluated at the current point
2063: . a_x - the gradient of auxiliary each field evaluated at the current point
2064: . t - current time
2065: . x - coordinates of the current point
2066: - uNew - new value for field at the current point

2068:   Level: intermediate

2070: .seealso: PetscDSSetUpdate(), PetscDSSetResidual()
2071: @*/
2072: PetscErrorCode PetscDSGetUpdate(PetscDS ds, PetscInt f,
2073:                                   void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2074:                                                   const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2075:                                                   const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2076:                                                   PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2077: {
2081:   return 0;
2082: }

2084: /*@C
2085:   PetscDSSetUpdate - Set the pointwise update function for a given field

2087:   Not collective

2089:   Input Parameters:
2090: + ds     - The PetscDS
2091: . f      - The field number
2092: - update - update function

2094:   Note: The calling sequence for the callback update is given by:

2096: $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2097: $        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2098: $        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2099: $        PetscReal t, const PetscReal x[], PetscScalar uNew[])

2101: + dim - the spatial dimension
2102: . Nf - the number of fields
2103: . uOff - the offset into u[] and u_t[] for each field
2104: . uOff_x - the offset into u_x[] for each field
2105: . u - each field evaluated at the current point
2106: . u_t - the time derivative of each field evaluated at the current point
2107: . u_x - the gradient of each field evaluated at the current point
2108: . aOff - the offset into a[] and a_t[] for each auxiliary field
2109: . aOff_x - the offset into a_x[] for each auxiliary field
2110: . a - each auxiliary field evaluated at the current point
2111: . a_t - the time derivative of each auxiliary field evaluated at the current point
2112: . a_x - the gradient of auxiliary each field evaluated at the current point
2113: . t - current time
2114: . x - coordinates of the current point
2115: - uNew - new field values at the current point

2117:   Level: intermediate

2119: .seealso: PetscDSGetResidual()
2120: @*/
2121: PetscErrorCode PetscDSSetUpdate(PetscDS ds, PetscInt f,
2122:                                 void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2123:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2124:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2125:                                                PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
2126: {
2130:   PetscDSEnlarge_Static(ds, f+1);
2131:   ds->update[f] = update;
2132:   return 0;
2133: }

2135: PetscErrorCode PetscDSGetContext(PetscDS ds, PetscInt f, void *ctx)
2136: {
2140:   *(void**)ctx = ds->ctx[f];
2141:   return 0;
2142: }

2144: PetscErrorCode PetscDSSetContext(PetscDS ds, PetscInt f, void *ctx)
2145: {
2148:   PetscDSEnlarge_Static(ds, f+1);
2149:   ds->ctx[f] = ctx;
2150:   return 0;
2151: }

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

2156:   Not collective

2158:   Input Parameters:
2159: + ds - The PetscDS
2160: - f  - The test field number

2162:   Output Parameters:
2163: + f0 - boundary integrand for the test function term
2164: - f1 - boundary integrand for the test function gradient term

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

2168:   \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n

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

2172: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2173: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2174: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2175: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])

2177: + dim - the spatial dimension
2178: . Nf - the number of fields
2179: . uOff - the offset into u[] and u_t[] for each field
2180: . uOff_x - the offset into u_x[] for each field
2181: . u - each field evaluated at the current point
2182: . u_t - the time derivative of each field evaluated at the current point
2183: . u_x - the gradient of each field evaluated at the current point
2184: . aOff - the offset into a[] and a_t[] for each auxiliary field
2185: . aOff_x - the offset into a_x[] for each auxiliary field
2186: . a - each auxiliary field evaluated at the current point
2187: . a_t - the time derivative of each auxiliary field evaluated at the current point
2188: . a_x - the gradient of auxiliary each field evaluated at the current point
2189: . t - current time
2190: . x - coordinates of the current point
2191: . n - unit normal at the current point
2192: . numConstants - number of constant parameters
2193: . constants - constant parameters
2194: - f0 - output values at the current point

2196:   Level: intermediate

2198: .seealso: PetscDSSetBdResidual()
2199: @*/
2200: PetscErrorCode PetscDSGetBdResidual(PetscDS ds, PetscInt f,
2201:                                     void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2202:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2203:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2204:                                                 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
2205:                                     void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2206:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2207:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2208:                                                 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2209: {
2210:   PetscBdPointFunc *tmp0, *tmp1;
2211:   PetscInt          n0, n1;

2215:   PetscWeakFormGetBdResidual(ds->wf, NULL, 0, f, 0, &n0, &tmp0, &n1, &tmp1);
2216:   *f0  = tmp0 ? tmp0[0] : NULL;
2217:   *f1  = tmp1 ? tmp1[0] : NULL;
2218:   return 0;
2219: }

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

2224:   Not collective

2226:   Input Parameters:
2227: + ds - The PetscDS
2228: . f  - The test field number
2229: . f0 - boundary integrand for the test function term
2230: - f1 - boundary integrand for the test function gradient term

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

2234:   \int_\Gamma \phi {\vec f}_0(u, u_t, \nabla u, x, t) \cdot \hat n + \nabla\phi \cdot {\overleftrightarrow f}_1(u, u_t, \nabla u, x, t) \cdot \hat n

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

2238: $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2239: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2240: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2241: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])

2243: + dim - the spatial dimension
2244: . Nf - the number of fields
2245: . uOff - the offset into u[] and u_t[] for each field
2246: . uOff_x - the offset into u_x[] for each field
2247: . u - each field evaluated at the current point
2248: . u_t - the time derivative of each field evaluated at the current point
2249: . u_x - the gradient of each field evaluated at the current point
2250: . aOff - the offset into a[] and a_t[] for each auxiliary field
2251: . aOff_x - the offset into a_x[] for each auxiliary field
2252: . a - each auxiliary field evaluated at the current point
2253: . a_t - the time derivative of each auxiliary field evaluated at the current point
2254: . a_x - the gradient of auxiliary each field evaluated at the current point
2255: . t - current time
2256: . x - coordinates of the current point
2257: . n - unit normal at the current point
2258: . numConstants - number of constant parameters
2259: . constants - constant parameters
2260: - f0 - output values at the current point

2262:   Level: intermediate

2264: .seealso: PetscDSGetBdResidual()
2265: @*/
2266: PetscErrorCode PetscDSSetBdResidual(PetscDS ds, PetscInt f,
2267:                                     void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2268:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2269:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2270:                                                PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
2271:                                     void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2272:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2273:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2274:                                                PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2275: {
2278:   PetscWeakFormSetIndexBdResidual(ds->wf, NULL, 0, f, 0, 0, f0, 0, f1);
2279:   return 0;
2280: }

2282: /*@
2283:   PetscDSHasBdJacobian - Signals that boundary Jacobian functions have been set

2285:   Not collective

2287:   Input Parameter:
2288: . ds - The PetscDS

2290:   Output Parameter:
2291: . hasBdJac - flag that pointwise function for the boundary Jacobian has been set

2293:   Level: intermediate

2295: .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian()
2296: @*/
2297: PetscErrorCode PetscDSHasBdJacobian(PetscDS ds, PetscBool *hasBdJac)
2298: {
2301:   PetscWeakFormHasBdJacobian(ds->wf, hasBdJac);
2302:   return 0;
2303: }

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

2308:   Not collective

2310:   Input Parameters:
2311: + ds - The PetscDS
2312: . f  - The test field number
2313: - g  - The field number

2315:   Output Parameters:
2316: + g0 - integrand for the test and basis function term
2317: . g1 - integrand for the test function and basis function gradient term
2318: . g2 - integrand for the test function gradient and basis function term
2319: - g3 - integrand for the test function gradient and basis function gradient term

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

2323:   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi

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

2327: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2328: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2329: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2330: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])

2332: + dim - the spatial dimension
2333: . Nf - the number of fields
2334: . uOff - the offset into u[] and u_t[] for each field
2335: . uOff_x - the offset into u_x[] for each field
2336: . u - each field evaluated at the current point
2337: . u_t - the time derivative of each field evaluated at the current point
2338: . u_x - the gradient of each field evaluated at the current point
2339: . aOff - the offset into a[] and a_t[] for each auxiliary field
2340: . aOff_x - the offset into a_x[] for each auxiliary field
2341: . a - each auxiliary field evaluated at the current point
2342: . a_t - the time derivative of each auxiliary field evaluated at the current point
2343: . a_x - the gradient of auxiliary each field evaluated at the current point
2344: . t - current time
2345: . u_tShift - the multiplier a for dF/dU_t
2346: . x - coordinates of the current point
2347: . n - normal at the current point
2348: . numConstants - number of constant parameters
2349: . constants - constant parameters
2350: - g0 - output values at the current point

2352:   Level: intermediate

2354: .seealso: PetscDSSetBdJacobian()
2355: @*/
2356: PetscErrorCode PetscDSGetBdJacobian(PetscDS ds, PetscInt f, PetscInt g,
2357:                                     void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2358:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2359:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2360:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2361:                                     void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2362:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2363:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2364:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2365:                                     void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2366:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2367:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2368:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2369:                                     void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2370:                                                 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2371:                                                 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2372:                                                 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2373: {
2374:   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
2375:   PetscInt         n0, n1, n2, n3;

2380:   PetscWeakFormGetBdJacobian(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
2381:   *g0  = tmp0 ? tmp0[0] : NULL;
2382:   *g1  = tmp1 ? tmp1[0] : NULL;
2383:   *g2  = tmp2 ? tmp2[0] : NULL;
2384:   *g3  = tmp3 ? tmp3[0] : NULL;
2385:   return 0;
2386: }

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

2391:   Not collective

2393:   Input Parameters:
2394: + ds - The PetscDS
2395: . f  - The test field number
2396: . g  - The field number
2397: . g0 - integrand for the test and basis function term
2398: . g1 - integrand for the test function and basis function gradient term
2399: . g2 - integrand for the test function gradient and basis function term
2400: - g3 - integrand for the test function gradient and basis function gradient term

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

2404:   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi

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

2408: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2409: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2410: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2411: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])

2413: + dim - the spatial dimension
2414: . Nf - the number of fields
2415: . uOff - the offset into u[] and u_t[] for each field
2416: . uOff_x - the offset into u_x[] for each field
2417: . u - each field evaluated at the current point
2418: . u_t - the time derivative of each field evaluated at the current point
2419: . u_x - the gradient of each field evaluated at the current point
2420: . aOff - the offset into a[] and a_t[] for each auxiliary field
2421: . aOff_x - the offset into a_x[] for each auxiliary field
2422: . a - each auxiliary field evaluated at the current point
2423: . a_t - the time derivative of each auxiliary field evaluated at the current point
2424: . a_x - the gradient of auxiliary each field evaluated at the current point
2425: . t - current time
2426: . u_tShift - the multiplier a for dF/dU_t
2427: . x - coordinates of the current point
2428: . n - normal at the current point
2429: . numConstants - number of constant parameters
2430: . constants - constant parameters
2431: - g0 - output values at the current point

2433:   Level: intermediate

2435: .seealso: PetscDSGetBdJacobian()
2436: @*/
2437: PetscErrorCode PetscDSSetBdJacobian(PetscDS ds, PetscInt f, PetscInt g,
2438:                                     void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2439:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2440:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2441:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2442:                                     void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2443:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2444:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2445:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2446:                                     void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2447:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2448:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2449:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2450:                                     void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2451:                                                const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2452:                                                const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2453:                                                PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2454: {
2462:   PetscWeakFormSetIndexBdJacobian(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
2463:   return 0;
2464: }

2466: /*@
2467:   PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set

2469:   Not collective

2471:   Input Parameter:
2472: . ds - The PetscDS

2474:   Output Parameter:
2475: . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set

2477:   Level: intermediate

2479: .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian()
2480: @*/
2481: PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS ds, PetscBool *hasBdJacPre)
2482: {
2485:   PetscWeakFormHasBdJacobianPreconditioner(ds->wf, hasBdJacPre);
2486:   return 0;
2487: }

2489: /*@C
2490:   PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field

2492:   Not collective

2494:   Input Parameters:
2495: + ds - The PetscDS
2496: . f  - The test field number
2497: - g  - The field number

2499:   Output Parameters:
2500: + g0 - integrand for the test and basis function term
2501: . g1 - integrand for the test function and basis function gradient term
2502: . g2 - integrand for the test function gradient and basis function term
2503: - g3 - integrand for the test function gradient and basis function gradient term

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

2507:   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi

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

2511: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2512: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2513: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2514: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])

2516: + dim - the spatial dimension
2517: . Nf - the number of fields
2518: . NfAux - the number of auxiliary fields
2519: . uOff - the offset into u[] and u_t[] for each field
2520: . uOff_x - the offset into u_x[] for each field
2521: . u - each field evaluated at the current point
2522: . u_t - the time derivative of each field evaluated at the current point
2523: . u_x - the gradient of each field evaluated at the current point
2524: . aOff - the offset into a[] and a_t[] for each auxiliary field
2525: . aOff_x - the offset into a_x[] for each auxiliary field
2526: . a - each auxiliary field evaluated at the current point
2527: . a_t - the time derivative of each auxiliary field evaluated at the current point
2528: . a_x - the gradient of auxiliary each field evaluated at the current point
2529: . t - current time
2530: . u_tShift - the multiplier a for dF/dU_t
2531: . x - coordinates of the current point
2532: . n - normal at the current point
2533: . numConstants - number of constant parameters
2534: . constants - constant parameters
2535: - g0 - output values at the current point

2537:   This is not yet available in Fortran.

2539:   Level: intermediate

2541: .seealso: PetscDSSetBdJacobianPreconditioner()
2542: @*/
2543: PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
2544:                                                   void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2545:                                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2546:                                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2547:                                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2548:                                                   void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2549:                                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2550:                                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2551:                                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2552:                                                   void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2553:                                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2554:                                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2555:                                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2556:                                                   void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2557:                                                               const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2558:                                                               const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2559:                                                               PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2560: {
2561:   PetscBdPointJac *tmp0, *tmp1, *tmp2, *tmp3;
2562:   PetscInt         n0, n1, n2, n3;

2567:   PetscWeakFormGetBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, &n0, &tmp0, &n1, &tmp1, &n2, &tmp2, &n3, &tmp3);
2568:   *g0  = tmp0 ? tmp0[0] : NULL;
2569:   *g1  = tmp1 ? tmp1[0] : NULL;
2570:   *g2  = tmp2 ? tmp2[0] : NULL;
2571:   *g3  = tmp3 ? tmp3[0] : NULL;
2572:   return 0;
2573: }

2575: /*@C
2576:   PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field

2578:   Not collective

2580:   Input Parameters:
2581: + ds - The PetscDS
2582: . f  - The test field number
2583: . g  - The field number
2584: . g0 - integrand for the test and basis function term
2585: . g1 - integrand for the test function and basis function gradient term
2586: . g2 - integrand for the test function gradient and basis function term
2587: - g3 - integrand for the test function gradient and basis function gradient term

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

2591:   \int_\Gamma \phi {\vec g}_0(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \phi {\vec g}_1(u, u_t, \nabla u, x, t) \cdot \hat n \nabla \psi + \nabla\phi \cdot {\vec g}_2(u, u_t, \nabla u, x, t) \cdot \hat n \psi + \nabla\phi \cdot {\overleftrightarrow g}_3(u, u_t, \nabla u, x, t) \cdot \hat n \cdot \nabla \psi

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

2595: $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2596: $    const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2597: $    const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2598: $    PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])

2600: + dim - the spatial dimension
2601: . Nf - the number of fields
2602: . NfAux - the number of auxiliary fields
2603: . uOff - the offset into u[] and u_t[] for each field
2604: . uOff_x - the offset into u_x[] for each field
2605: . u - each field evaluated at the current point
2606: . u_t - the time derivative of each field evaluated at the current point
2607: . u_x - the gradient of each field evaluated at the current point
2608: . aOff - the offset into a[] and a_t[] for each auxiliary field
2609: . aOff_x - the offset into a_x[] for each auxiliary field
2610: . a - each auxiliary field evaluated at the current point
2611: . a_t - the time derivative of each auxiliary field evaluated at the current point
2612: . a_x - the gradient of auxiliary each field evaluated at the current point
2613: . t - current time
2614: . u_tShift - the multiplier a for dF/dU_t
2615: . x - coordinates of the current point
2616: . n - normal at the current point
2617: . numConstants - number of constant parameters
2618: . constants - constant parameters
2619: - g0 - output values at the current point

2621:   This is not yet available in Fortran.

2623:   Level: intermediate

2625: .seealso: PetscDSGetBdJacobianPreconditioner()
2626: @*/
2627: PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS ds, PetscInt f, PetscInt g,
2628:                                                   void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2629:                                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2630:                                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2631:                                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2632:                                                   void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2633:                                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2634:                                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2635:                                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2636:                                                   void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2637:                                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2638:                                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2639:                                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2640:                                                   void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2641:                                                              const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2642:                                                              const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2643:                                                              PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2644: {
2652:   PetscWeakFormSetIndexBdJacobianPreconditioner(ds->wf, NULL, 0, f, g, 0, 0, g0, 0, g1, 0, g2, 0, g3);
2653:   return 0;
2654: }

2656: /*@C
2657:   PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field

2659:   Not collective

2661:   Input Parameters:
2662: + prob - The PetscDS
2663: - f    - The test field number

2665:   Output Parameters:
2666: + exactSol - exact solution for the test field
2667: - exactCtx - exact solution context

2669:   Note: The calling sequence for the solution functions is given by:

2671: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)

2673: + dim - the spatial dimension
2674: . t - current time
2675: . x - coordinates of the current point
2676: . Nc - the number of field components
2677: . u - the solution field evaluated at the current point
2678: - ctx - a user context

2680:   Level: intermediate

2682: .seealso: PetscDSSetExactSolution(), PetscDSGetExactSolutionTimeDerivative()
2683: @*/
2684: PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2685: {
2690:   return 0;
2691: }

2693: /*@C
2694:   PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field

2696:   Not collective

2698:   Input Parameters:
2699: + prob - The PetscDS
2700: . f    - The test field number
2701: . sol  - solution function for the test fields
2702: - ctx  - solution context or NULL

2704:   Note: The calling sequence for solution functions is given by:

2706: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)

2708: + dim - the spatial dimension
2709: . t - current time
2710: . x - coordinates of the current point
2711: . Nc - the number of field components
2712: . u - the solution field evaluated at the current point
2713: - ctx - a user context

2715:   Level: intermediate

2717: .seealso: PetscDSGetExactSolution()
2718: @*/
2719: PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2720: {
2723:   PetscDSEnlarge_Static(prob, f+1);
2726:   return 0;
2727: }

2729: /*@C
2730:   PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field

2732:   Not collective

2734:   Input Parameters:
2735: + prob - The PetscDS
2736: - f    - The test field number

2738:   Output Parameters:
2739: + exactSol - time derivative of the exact solution for the test field
2740: - exactCtx - time derivative of the exact solution context

2742:   Note: The calling sequence for the solution functions is given by:

2744: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)

2746: + dim - the spatial dimension
2747: . t - current time
2748: . x - coordinates of the current point
2749: . Nc - the number of field components
2750: . u - the solution field evaluated at the current point
2751: - ctx - a user context

2753:   Level: intermediate

2755: .seealso: PetscDSSetExactSolutionTimeDerivative(), PetscDSGetExactSolution()
2756: @*/
2757: PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2758: {
2763:   return 0;
2764: }

2766: /*@C
2767:   PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field

2769:   Not collective

2771:   Input Parameters:
2772: + prob - The PetscDS
2773: . f    - The test field number
2774: . sol  - time derivative of the solution function for the test fields
2775: - ctx  - time derivative of the solution context or NULL

2777:   Note: The calling sequence for solution functions is given by:

2779: $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)

2781: + dim - the spatial dimension
2782: . t - current time
2783: . x - coordinates of the current point
2784: . Nc - the number of field components
2785: . u - the solution field evaluated at the current point
2786: - ctx - a user context

2788:   Level: intermediate

2790: .seealso: PetscDSGetExactSolutionTimeDerivative(), PetscDSSetExactSolution()
2791: @*/
2792: PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2793: {
2796:   PetscDSEnlarge_Static(prob, f+1);
2799:   return 0;
2800: }

2802: /*@C
2803:   PetscDSGetConstants - Returns the array of constants passed to point functions

2805:   Not collective

2807:   Input Parameter:
2808: . prob - The PetscDS object

2810:   Output Parameters:
2811: + numConstants - The number of constants
2812: - constants    - The array of constants, NULL if there are none

2814:   Level: intermediate

2816: .seealso: PetscDSSetConstants(), PetscDSCreate()
2817: @*/
2818: PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2819: {
2823:   return 0;
2824: }

2826: /*@C
2827:   PetscDSSetConstants - Set the array of constants passed to point functions

2829:   Not collective

2831:   Input Parameters:
2832: + prob         - The PetscDS object
2833: . numConstants - The number of constants
2834: - constants    - The array of constants, NULL if there are none

2836:   Level: intermediate

2838: .seealso: PetscDSGetConstants(), PetscDSCreate()
2839: @*/
2840: PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2841: {
2843:   if (numConstants != prob->numConstants) {
2844:     PetscFree(prob->constants);
2845:     prob->numConstants = numConstants;
2846:     if (prob->numConstants) {
2847:       PetscMalloc1(prob->numConstants, &prob->constants);
2848:     } else {
2849:       prob->constants = NULL;
2850:     }
2851:   }
2852:   if (prob->numConstants) {
2854:     PetscArraycpy(prob->constants, constants, prob->numConstants);
2855:   }
2856:   return 0;
2857: }

2859: /*@
2860:   PetscDSGetFieldIndex - Returns the index of the given field

2862:   Not collective

2864:   Input Parameters:
2865: + prob - The PetscDS object
2866: - disc - The discretization object

2868:   Output Parameter:
2869: . f - The field number

2871:   Level: beginner

2873: .seealso: PetscGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
2874: @*/
2875: PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2876: {
2877:   PetscInt g;

2881:   *f = -1;
2882:   for (g = 0; g < prob->Nf; ++g) {if (disc == prob->disc[g]) break;}
2884:   *f = g;
2885:   return 0;
2886: }

2888: /*@
2889:   PetscDSGetFieldSize - Returns the size of the given field in the full space basis

2891:   Not collective

2893:   Input Parameters:
2894: + prob - The PetscDS object
2895: - f - The field number

2897:   Output Parameter:
2898: . size - The size

2900:   Level: beginner

2902: .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
2903: @*/
2904: PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2905: {
2909:   PetscDSSetUp(prob);
2910:   *size = prob->Nb[f];
2911:   return 0;
2912: }

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

2917:   Not collective

2919:   Input Parameters:
2920: + prob - The PetscDS object
2921: - f - The field number

2923:   Output Parameter:
2924: . off - The offset

2926:   Level: beginner

2928: .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate()
2929: @*/
2930: PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2931: {
2932:   PetscInt       size, g;

2937:   *off = 0;
2938:   for (g = 0; g < f; ++g) {
2939:     PetscDSGetFieldSize(prob, g, &size);
2940:     *off += size;
2941:   }
2942:   return 0;
2943: }

2945: /*@
2946:   PetscDSGetFieldOffsetCohesive - Returns the offset of the given field in the full space basis on a cohesive cell

2948:   Not collective

2950:   Input Parameters:
2951: + prob - The PetscDS object
2952: - f - The field number

2954:   Output Parameter:
2955: . off - The offset

2957:   Level: beginner

2959: .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate()
2960: @*/
2961: PetscErrorCode PetscDSGetFieldOffsetCohesive(PetscDS ds, PetscInt f, PetscInt *off)
2962: {
2963:   PetscInt       size, g;

2968:   *off = 0;
2969:   for (g = 0; g < f; ++g) {
2970:     PetscBool cohesive;

2972:     PetscDSGetCohesive(ds, g, &cohesive);
2973:     PetscDSGetFieldSize(ds, g, &size);
2974:     *off += cohesive ? size : size*2;
2975:   }
2976:   return 0;
2977: }

2979: /*@
2980:   PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point

2982:   Not collective

2984:   Input Parameter:
2985: . prob - The PetscDS object

2987:   Output Parameter:
2988: . dimensions - The number of dimensions

2990:   Level: beginner

2992: .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
2993: @*/
2994: PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2995: {
2997:   PetscDSSetUp(prob);
2999:   *dimensions = prob->Nb;
3000:   return 0;
3001: }

3003: /*@
3004:   PetscDSGetComponents - Returns the number of components for each field on an evaluation point

3006:   Not collective

3008:   Input Parameter:
3009: . prob - The PetscDS object

3011:   Output Parameter:
3012: . components - The number of components

3014:   Level: beginner

3016: .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
3017: @*/
3018: PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
3019: {
3021:   PetscDSSetUp(prob);
3023:   *components = prob->Nc;
3024:   return 0;
3025: }

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

3030:   Not collective

3032:   Input Parameters:
3033: + prob - The PetscDS object
3034: - f - The field number

3036:   Output Parameter:
3037: . off - The offset

3039:   Level: beginner

3041: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3042: @*/
3043: PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
3044: {
3048:   PetscDSSetUp(prob);
3049:   *off = prob->off[f];
3050:   return 0;
3051: }

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

3056:   Not collective

3058:   Input Parameter:
3059: . prob - The PetscDS object

3061:   Output Parameter:
3062: . offsets - The offsets

3064:   Level: beginner

3066: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3067: @*/
3068: PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
3069: {
3072:   PetscDSSetUp(prob);
3073:   *offsets = prob->off;
3074:   return 0;
3075: }

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

3080:   Not collective

3082:   Input Parameter:
3083: . prob - The PetscDS object

3085:   Output Parameter:
3086: . offsets - The offsets

3088:   Level: beginner

3090: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3091: @*/
3092: PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
3093: {
3096:   PetscDSSetUp(prob);
3097:   *offsets = prob->offDer;
3098:   return 0;
3099: }

3101: /*@
3102:   PetscDSGetComponentOffsetsCohesive - Returns the offset of each field on an evaluation point

3104:   Not collective

3106:   Input Parameters:
3107: + ds - The PetscDS object
3108: - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive

3110:   Output Parameter:
3111: . offsets - The offsets

3113:   Level: beginner

3115: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3116: @*/
3117: PetscErrorCode PetscDSGetComponentOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3118: {
3123:   PetscDSSetUp(ds);
3124:   *offsets = ds->offCohesive[s];
3125:   return 0;
3126: }

3128: /*@
3129:   PetscDSGetComponentDerivativeOffsetsCohesive - Returns the offset of each field derivative on an evaluation point

3131:   Not collective

3133:   Input Parameters:
3134: + ds - The PetscDS object
3135: - s  - The cohesive side, 0 for negative, 1 for positive, 2 for cohesive

3137:   Output Parameter:
3138: . offsets - The offsets

3140:   Level: beginner

3142: .seealso: PetscDSGetNumFields(), PetscDSCreate()
3143: @*/
3144: PetscErrorCode PetscDSGetComponentDerivativeOffsetsCohesive(PetscDS ds, PetscInt s, PetscInt *offsets[])
3145: {
3150:   PetscDSSetUp(ds);
3151:   *offsets = ds->offDerCohesive[s];
3152:   return 0;
3153: }

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

3158:   Not collective

3160:   Input Parameter:
3161: . prob - The PetscDS object

3163:   Output Parameter:
3164: . T - The basis function and derivatives tabulation at quadrature points for each field

3166:   Level: intermediate

3168: .seealso: PetscDSCreate()
3169: @*/
3170: PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
3171: {
3174:   PetscDSSetUp(prob);
3175:   *T = prob->T;
3176:   return 0;
3177: }

3179: /*@C
3180:   PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces

3182:   Not collective

3184:   Input Parameter:
3185: . prob - The PetscDS object

3187:   Output Parameter:
3188: . Tf - The basis function and derivative tabulation on each local face at quadrature points for each and field

3190:   Level: intermediate

3192: .seealso: PetscDSGetTabulation(), PetscDSCreate()
3193: @*/
3194: PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
3195: {
3198:   PetscDSSetUp(prob);
3199:   *Tf = prob->Tf;
3200:   return 0;
3201: }

3203: PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3204: {
3206:   PetscDSSetUp(prob);
3210:   return 0;
3211: }

3213: PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3214: {
3216:   PetscDSSetUp(prob);
3223:   return 0;
3224: }

3226: PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3227: {
3229:   PetscDSSetUp(prob);
3235:   return 0;
3236: }

3238: /*@C
3239:   PetscDSAddBoundary - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions. In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals should be performed, using the kernels from PetscDSSetBdResidual().

3241:   Collective on ds

3243:   Input Parameters:
3244: + ds       - The PetscDS object
3245: . type     - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3246: . name     - The BC name
3247: . label    - The label defining constrained points
3248: . Nv       - The number of DMLabel values for constrained points
3249: . values   - An array of label values for constrained points
3250: . field    - The field to constrain
3251: . Nc       - The number of constrained field components (0 will constrain all fields)
3252: . comps    - An array of constrained component numbers
3253: . bcFunc   - A pointwise function giving boundary values
3254: . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3255: - ctx      - An optional user context for bcFunc

3257:   Output Parameters:
3258: - bd       - The boundary number

3260:   Options Database Keys:
3261: + -bc_<boundary name> <num> - Overrides the boundary ids
3262: - -bc_<boundary name>_comp <num> - Overrides the boundary components

3264:   Note:
3265:   Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is:

3267: $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])

3269:   If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is:

3271: $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3272: $        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3273: $        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3274: $        PetscReal time, const PetscReal x[], PetscScalar bcval[])

3276: + dim - the spatial dimension
3277: . Nf - the number of fields
3278: . uOff - the offset into u[] and u_t[] for each field
3279: . uOff_x - the offset into u_x[] for each field
3280: . u - each field evaluated at the current point
3281: . u_t - the time derivative of each field evaluated at the current point
3282: . u_x - the gradient of each field evaluated at the current point
3283: . aOff - the offset into a[] and a_t[] for each auxiliary field
3284: . aOff_x - the offset into a_x[] for each auxiliary field
3285: . a - each auxiliary field evaluated at the current point
3286: . a_t - the time derivative of each auxiliary field evaluated at the current point
3287: . a_x - the gradient of auxiliary each field evaluated at the current point
3288: . t - current time
3289: . x - coordinates of the current point
3290: . numConstants - number of constant parameters
3291: . constants - constant parameters
3292: - bcval - output values at the current point

3294:   Level: developer

3296: .seealso: PetscDSAddBoundaryByName(), PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual()
3297: @*/
3298: PetscErrorCode PetscDSAddBoundary(PetscDS ds, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd)
3299: {
3300:   DSBoundary     head = ds->boundary, b;
3301:   PetscInt       n    = 0;
3302:   const char    *lname;

3311:   if (Nc > 0) {
3312:     PetscInt *fcomps;
3313:     PetscInt  c;

3315:     PetscDSGetComponents(ds, &fcomps);
3317:     for (c = 0; c < Nc; ++c) {
3319:     }
3320:   }
3321:   PetscNew(&b);
3322:   PetscStrallocpy(name, (char **) &b->name);
3323:   PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf);
3324:   PetscWeakFormSetNumFields(b->wf, ds->Nf);
3325:   PetscMalloc1(Nv, &b->values);
3326:   if (Nv) PetscArraycpy(b->values, values, Nv);
3327:   PetscMalloc1(Nc, &b->comps);
3328:   if (Nc) PetscArraycpy(b->comps, comps, Nc);
3329:   PetscObjectGetName((PetscObject) label, &lname);
3330:   PetscStrallocpy(lname, (char **) &b->lname);
3331:   b->type   = type;
3332:   b->label  = label;
3333:   b->Nv     = Nv;
3334:   b->field  = field;
3335:   b->Nc     = Nc;
3336:   b->func   = bcFunc;
3337:   b->func_t = bcFunc_t;
3338:   b->ctx    = ctx;
3339:   b->next   = NULL;
3340:   /* Append to linked list so that we can preserve the order */
3341:   if (!head) ds->boundary = b;
3342:   while (head) {
3343:     if (!head->next) {
3344:       head->next = b;
3345:       head       = b;
3346:     }
3347:     head = head->next;
3348:     ++n;
3349:   }
3351:   return 0;
3352: }

3354: /*@C
3355:   PetscDSAddBoundaryByName - Add a boundary condition to the model. The pointwise functions are used to provide boundary values for essential boundary conditions. In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals should be performed, using the kernels from PetscDSSetBdResidual().

3357:   Collective on ds

3359:   Input Parameters:
3360: + ds       - The PetscDS object
3361: . type     - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3362: . name     - The BC name
3363: . lname    - The naem of the label defining constrained points
3364: . Nv       - The number of DMLabel values for constrained points
3365: . values   - An array of label values for constrained points
3366: . field    - The field to constrain
3367: . Nc       - The number of constrained field components (0 will constrain all fields)
3368: . comps    - An array of constrained component numbers
3369: . bcFunc   - A pointwise function giving boundary values
3370: . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3371: - ctx      - An optional user context for bcFunc

3373:   Output Parameters:
3374: - bd       - The boundary number

3376:   Options Database Keys:
3377: + -bc_<boundary name> <num> - Overrides the boundary ids
3378: - -bc_<boundary name>_comp <num> - Overrides the boundary components

3380:   Note:
3381:   This function should only be used with DMForest currently, since labels cannot be defined before the underlygin Plex is built.

3383:   Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is:

3385: $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])

3387:   If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is:

3389: $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3390: $        const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3391: $        const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3392: $        PetscReal time, const PetscReal x[], PetscScalar bcval[])

3394: + dim - the spatial dimension
3395: . Nf - the number of fields
3396: . uOff - the offset into u[] and u_t[] for each field
3397: . uOff_x - the offset into u_x[] for each field
3398: . u - each field evaluated at the current point
3399: . u_t - the time derivative of each field evaluated at the current point
3400: . u_x - the gradient of each field evaluated at the current point
3401: . aOff - the offset into a[] and a_t[] for each auxiliary field
3402: . aOff_x - the offset into a_x[] for each auxiliary field
3403: . a - each auxiliary field evaluated at the current point
3404: . a_t - the time derivative of each auxiliary field evaluated at the current point
3405: . a_x - the gradient of auxiliary each field evaluated at the current point
3406: . t - current time
3407: . x - coordinates of the current point
3408: . numConstants - number of constant parameters
3409: . constants - constant parameters
3410: - bcval - output values at the current point

3412:   Level: developer

3414: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual()
3415: @*/
3416: PetscErrorCode PetscDSAddBoundaryByName(PetscDS ds, DMBoundaryConditionType type, const char name[], const char lname[], PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx, PetscInt *bd)
3417: {
3418:   DSBoundary     head = ds->boundary, b;
3419:   PetscInt       n    = 0;

3428:   PetscNew(&b);
3429:   PetscStrallocpy(name, (char **) &b->name);
3430:   PetscWeakFormCreate(PETSC_COMM_SELF, &b->wf);
3431:   PetscWeakFormSetNumFields(b->wf, ds->Nf);
3432:   PetscMalloc1(Nv, &b->values);
3433:   if (Nv) PetscArraycpy(b->values, values, Nv);
3434:   PetscMalloc1(Nc, &b->comps);
3435:   if (Nc) PetscArraycpy(b->comps, comps, Nc);
3436:   PetscStrallocpy(lname, (char **) &b->lname);
3437:   b->type   = type;
3438:   b->label  = NULL;
3439:   b->Nv     = Nv;
3440:   b->field  = field;
3441:   b->Nc     = Nc;
3442:   b->func   = bcFunc;
3443:   b->func_t = bcFunc_t;
3444:   b->ctx    = ctx;
3445:   b->next   = NULL;
3446:   /* Append to linked list so that we can preserve the order */
3447:   if (!head) ds->boundary = b;
3448:   while (head) {
3449:     if (!head->next) {
3450:       head->next = b;
3451:       head       = b;
3452:     }
3453:     head = head->next;
3454:     ++n;
3455:   }
3457:   return 0;
3458: }

3460: /*@C
3461:   PetscDSUpdateBoundary - Change a boundary condition for the model. The pointwise functions are used to provide boundary values for essential boundary conditions. In FEM, they are acting upon by dual basis functionals to generate FEM coefficients which are fixed. Natural boundary conditions signal to PETSc that boundary integrals should be performed, using the kernels from PetscDSSetBdResidual().

3463:   Input Parameters:
3464: + ds       - The PetscDS object
3465: . bd       - The boundary condition number
3466: . type     - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3467: . name     - The BC name
3468: . label    - The label defining constrained points
3469: . Nv       - The number of DMLabel ids for constrained points
3470: . values   - An array of ids for constrained points
3471: . field    - The field to constrain
3472: . Nc       - The number of constrained field components
3473: . comps    - An array of constrained component numbers
3474: . bcFunc   - A pointwise function giving boundary values
3475: . bcFunc_t - A pointwise function giving the time derivative of the boundary values, or NULL
3476: - ctx      - An optional user context for bcFunc

3478:   Note:
3479:   The boundary condition number is the order in which it was registered. The user can get the number of boundary conditions from PetscDSGetNumBoundary(). See PetscDSAddBoundary() for a description of the calling sequences for the callbacks.

3481:   Level: developer

3483: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSGetNumBoundary()
3484: @*/
3485: PetscErrorCode PetscDSUpdateBoundary(PetscDS ds, PetscInt bd, DMBoundaryConditionType type, const char name[], DMLabel label, PetscInt Nv, const PetscInt values[], PetscInt field, PetscInt Nc, const PetscInt comps[], void (*bcFunc)(void), void (*bcFunc_t)(void), void *ctx)
3486: {
3487:   DSBoundary     b = ds->boundary;
3488:   PetscInt       n = 0;

3491:   while (b) {
3492:     if (n == bd) break;
3493:     b = b->next;
3494:     ++n;
3495:   }
3497:   if (name) {
3498:     PetscFree(b->name);
3499:     PetscStrallocpy(name, (char **) &b->name);
3500:   }
3501:   b->type = type;
3502:   if (label) {
3503:     const char *name;

3505:     b->label = label;
3506:     PetscFree(b->lname);
3507:     PetscObjectGetName((PetscObject) label, &name);
3508:     PetscStrallocpy(name, (char **) &b->lname);
3509:   }
3510:   if (Nv >= 0) {
3511:     b->Nv = Nv;
3512:     PetscFree(b->values);
3513:     PetscMalloc1(Nv, &b->values);
3514:     if (Nv) PetscArraycpy(b->values, values, Nv);
3515:   }
3516:   if (field >= 0) b->field = field;
3517:   if (Nc >= 0) {
3518:     b->Nc = Nc;
3519:     PetscFree(b->comps);
3520:     PetscMalloc1(Nc, &b->comps);
3521:     if (Nc) PetscArraycpy(b->comps, comps, Nc);
3522:   }
3523:   if (bcFunc)   b->func   = bcFunc;
3524:   if (bcFunc_t) b->func_t = bcFunc_t;
3525:   if (ctx)      b->ctx    = ctx;
3526:   return 0;
3527: }

3529: /*@
3530:   PetscDSGetNumBoundary - Get the number of registered BC

3532:   Input Parameters:
3533: . ds - The PetscDS object

3535:   Output Parameters:
3536: . numBd - The number of BC

3538:   Level: intermediate

3540: .seealso: PetscDSAddBoundary(), PetscDSGetBoundary()
3541: @*/
3542: PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3543: {
3544:   DSBoundary b = ds->boundary;

3548:   *numBd = 0;
3549:   while (b) {++(*numBd); b = b->next;}
3550:   return 0;
3551: }

3553: /*@C
3554:   PetscDSGetBoundary - Gets a boundary condition to the model

3556:   Input Parameters:
3557: + ds          - The PetscDS object
3558: - bd          - The BC number

3560:   Output Parameters:
3561: + wf       - The PetscWeakForm holding the pointwise functions
3562: . type     - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3563: . name     - The BC name
3564: . label    - The label defining constrained points
3565: . Nv       - The number of DMLabel ids for constrained points
3566: . values   - An array of ids for constrained points
3567: . field    - The field to constrain
3568: . Nc       - The number of constrained field components
3569: . comps    - An array of constrained component numbers
3570: . bcFunc   - A pointwise function giving boundary values
3571: . bcFunc_t - A pointwise function giving the time derivative of the boundary values
3572: - ctx      - An optional user context for bcFunc

3574:   Options Database Keys:
3575: + -bc_<boundary name> <num> - Overrides the boundary ids
3576: - -bc_<boundary name>_comp <num> - Overrides the boundary components

3578:   Level: developer

3580: .seealso: PetscDSAddBoundary()
3581: @*/
3582: PetscErrorCode PetscDSGetBoundary(PetscDS ds, PetscInt bd, PetscWeakForm *wf, DMBoundaryConditionType *type, const char *name[], DMLabel *label, PetscInt *Nv, const PetscInt *values[], PetscInt *field, PetscInt *Nc, const PetscInt *comps[], void (**func)(void), void (**func_t)(void), void **ctx)
3583: {
3584:   DSBoundary b = ds->boundary;
3585:   PetscInt   n = 0;

3588:   while (b) {
3589:     if (n == bd) break;
3590:     b = b->next;
3591:     ++n;
3592:   }
3594:   if (wf) {
3596:     *wf = b->wf;
3597:   }
3598:   if (type) {
3600:     *type = b->type;
3601:   }
3602:   if (name) {
3604:     *name = b->name;
3605:   }
3606:   if (label) {
3608:     *label = b->label;
3609:   }
3610:   if (Nv) {
3612:     *Nv = b->Nv;
3613:   }
3614:   if (values) {
3616:     *values = b->values;
3617:   }
3618:   if (field) {
3620:     *field = b->field;
3621:   }
3622:   if (Nc) {
3624:     *Nc = b->Nc;
3625:   }
3626:   if (comps) {
3628:     *comps = b->comps;
3629:   }
3630:   if (func) {
3632:     *func = b->func;
3633:   }
3634:   if (func_t) {
3636:     *func_t = b->func_t;
3637:   }
3638:   if (ctx) {
3640:     *ctx = b->ctx;
3641:   }
3642:   return 0;
3643: }

3645: static PetscErrorCode DSBoundaryDuplicate_Internal(DSBoundary b, DSBoundary *bNew)
3646: {
3647:   PetscNew(bNew);
3648:   PetscWeakFormCreate(PETSC_COMM_SELF, &(*bNew)->wf);
3649:   PetscWeakFormCopy(b->wf, (*bNew)->wf);
3650:   PetscStrallocpy(b->name,(char **) &((*bNew)->name));
3651:   PetscStrallocpy(b->lname,(char **) &((*bNew)->lname));
3652:   (*bNew)->type   = b->type;
3653:   (*bNew)->label  = b->label;
3654:   (*bNew)->Nv     = b->Nv;
3655:   PetscMalloc1(b->Nv, &(*bNew)->values);
3656:   PetscArraycpy((*bNew)->values, b->values, b->Nv);
3657:   (*bNew)->field  = b->field;
3658:   (*bNew)->Nc     = b->Nc;
3659:   PetscMalloc1(b->Nc, &(*bNew)->comps);
3660:   PetscArraycpy((*bNew)->comps, b->comps, b->Nc);
3661:   (*bNew)->func   = b->func;
3662:   (*bNew)->func_t = b->func_t;
3663:   (*bNew)->ctx    = b->ctx;
3664:   return 0;
3665: }

3667: /*@
3668:   PetscDSCopyBoundary - Copy all boundary condition objects to the new problem

3670:   Not collective

3672:   Input Parameters:
3673: + ds        - The source PetscDS object
3674: . numFields - The number of selected fields, or PETSC_DEFAULT for all fields
3675: - fields    - The selected fields, or NULL for all fields

3677:   Output Parameter:
3678: . newds     - The target PetscDS, now with a copy of the boundary conditions

3680:   Level: intermediate

3682: .seealso: PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3683: @*/
3684: PetscErrorCode PetscDSCopyBoundary(PetscDS ds, PetscInt numFields, const PetscInt fields[], PetscDS newds)
3685: {
3686:   DSBoundary     b, *lastnext;

3690:   if (ds == newds) return 0;
3691:   PetscDSDestroyBoundary(newds);
3692:   lastnext = &(newds->boundary);
3693:   for (b = ds->boundary; b; b = b->next) {
3694:     DSBoundary bNew;
3695:     PetscInt   fieldNew = -1;

3697:     if (numFields > 0 && fields) {
3698:       PetscInt f;

3700:       for (f = 0; f < numFields; ++f) if (b->field == fields[f]) break;
3701:       if (f == numFields) continue;
3702:       fieldNew = f;
3703:     }
3704:     DSBoundaryDuplicate_Internal(b, &bNew);
3705:     bNew->field = fieldNew < 0 ? b->field : fieldNew;
3706:     *lastnext = bNew;
3707:     lastnext  = &(bNew->next);
3708:   }
3709:   return 0;
3710: }

3712: /*@
3713:   PetscDSDestroyBoundary - Remove all DMBoundary objects from the PetscDS

3715:   Not collective

3717:   Input Parameter:
3718: . ds - The PetscDS object

3720:   Level: intermediate

3722: .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations()
3723: @*/
3724: PetscErrorCode PetscDSDestroyBoundary(PetscDS ds)
3725: {
3726:   DSBoundary     next = ds->boundary;

3728:   while (next) {
3729:     DSBoundary b = next;

3731:     next = b->next;
3732:     PetscWeakFormDestroy(&b->wf);
3733:     PetscFree(b->name);
3734:     PetscFree(b->lname);
3735:     PetscFree(b->values);
3736:     PetscFree(b->comps);
3737:     PetscFree(b);
3738:   }
3739:   return 0;
3740: }

3742: /*@
3743:   PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout

3745:   Not collective

3747:   Input Parameters:
3748: + prob - The PetscDS object
3749: . numFields - Number of new fields
3750: - fields - Old field number for each new field

3752:   Output Parameter:
3753: . newprob - The PetscDS copy

3755:   Level: intermediate

3757: .seealso: PetscDSSelectEquations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3758: @*/
3759: PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3760: {
3761:   PetscInt       Nf, Nfn, fn;

3766:   PetscDSGetNumFields(prob, &Nf);
3767:   PetscDSGetNumFields(newprob, &Nfn);
3768:   numFields = numFields < 0 ? Nf : numFields;
3769:   for (fn = 0; fn < numFields; ++fn) {
3770:     const PetscInt f = fields ? fields[fn] : fn;
3771:     PetscObject    disc;

3773:     if (f >= Nf) continue;
3774:     PetscDSGetDiscretization(prob, f, &disc);
3775:     PetscDSSetDiscretization(newprob, fn, disc);
3776:   }
3777:   return 0;
3778: }

3780: /*@
3781:   PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout

3783:   Not collective

3785:   Input Parameters:
3786: + prob - The PetscDS object
3787: . numFields - Number of new fields
3788: - fields - Old field number for each new field

3790:   Output Parameter:
3791: . newprob - The PetscDS copy

3793:   Level: intermediate

3795: .seealso: PetscDSSelectDiscretizations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3796: @*/
3797: PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3798: {
3799:   PetscInt       Nf, Nfn, fn, gn;

3804:   PetscDSGetNumFields(prob, &Nf);
3805:   PetscDSGetNumFields(newprob, &Nfn);
3807:   for (fn = 0; fn < numFields; ++fn) {
3808:     const PetscInt   f = fields ? fields[fn] : fn;
3809:     PetscPointFunc   obj;
3810:     PetscPointFunc   f0, f1;
3811:     PetscBdPointFunc f0Bd, f1Bd;
3812:     PetscRiemannFunc r;

3814:     if (f >= Nf) continue;
3815:     PetscDSGetObjective(prob, f, &obj);
3816:     PetscDSGetResidual(prob, f, &f0, &f1);
3817:     PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd);
3818:     PetscDSGetRiemannSolver(prob, f, &r);
3819:     PetscDSSetObjective(newprob, fn, obj);
3820:     PetscDSSetResidual(newprob, fn, f0, f1);
3821:     PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd);
3822:     PetscDSSetRiemannSolver(newprob, fn, r);
3823:     for (gn = 0; gn < numFields; ++gn) {
3824:       const PetscInt  g = fields ? fields[gn] : gn;
3825:       PetscPointJac   g0, g1, g2, g3;
3826:       PetscPointJac   g0p, g1p, g2p, g3p;
3827:       PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;

3829:       if (g >= Nf) continue;
3830:       PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3);
3831:       PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p);
3832:       PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd);
3833:       PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3);
3834:       PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p);
3835:       PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd);
3836:     }
3837:   }
3838:   return 0;
3839: }

3841: /*@
3842:   PetscDSCopyEquations - Copy all pointwise function pointers to the new problem

3844:   Not collective

3846:   Input Parameter:
3847: . prob - The PetscDS object

3849:   Output Parameter:
3850: . newprob - The PetscDS copy

3852:   Level: intermediate

3854: .seealso: PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3855: @*/
3856: PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3857: {
3858:   PetscWeakForm  wf, newwf;
3859:   PetscInt       Nf, Ng;

3863:   PetscDSGetNumFields(prob, &Nf);
3864:   PetscDSGetNumFields(newprob, &Ng);
3866:   PetscDSGetWeakForm(prob, &wf);
3867:   PetscDSGetWeakForm(newprob, &newwf);
3868:   PetscWeakFormCopy(wf, newwf);
3869:   return 0;
3870: }

3872: /*@
3873:   PetscDSCopyConstants - Copy all constants to the new problem

3875:   Not collective

3877:   Input Parameter:
3878: . prob - The PetscDS object

3880:   Output Parameter:
3881: . newprob - The PetscDS copy

3883:   Level: intermediate

3885: .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3886: @*/
3887: PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3888: {
3889:   PetscInt           Nc;
3890:   const PetscScalar *constants;

3894:   PetscDSGetConstants(prob, &Nc, &constants);
3895:   PetscDSSetConstants(newprob, Nc, (PetscScalar *) constants);
3896:   return 0;
3897: }

3899: /*@
3900:   PetscDSCopyExactSolutions - Copy all exact solutions to the new problem

3902:   Not collective

3904:   Input Parameter:
3905: . ds - The PetscDS object

3907:   Output Parameter:
3908: . newds - The PetscDS copy

3910:   Level: intermediate

3912: .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3913: @*/
3914: PetscErrorCode PetscDSCopyExactSolutions(PetscDS ds, PetscDS newds)
3915: {
3916:   PetscSimplePointFunc sol;
3917:   void                *ctx;
3918:   PetscInt             Nf, f;

3922:   PetscDSGetNumFields(ds, &Nf);
3923:   for (f = 0; f < Nf; ++f) {
3924:     PetscDSGetExactSolution(ds,    f, &sol, &ctx);
3925:     PetscDSSetExactSolution(newds, f,  sol,  ctx);
3926:     PetscDSGetExactSolutionTimeDerivative(ds,    f, &sol, &ctx);
3927:     PetscDSSetExactSolutionTimeDerivative(newds, f,  sol,  ctx);
3928:   }
3929:   return 0;
3930: }

3932: PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
3933: {
3934:   PetscInt       dim, Nf, f;

3938:   if (height == 0) {*subprob = prob; return 0;}
3939:   PetscDSGetNumFields(prob, &Nf);
3940:   PetscDSGetSpatialDimension(prob, &dim);
3942:   if (!prob->subprobs) PetscCalloc1(dim, &prob->subprobs);
3943:   if (!prob->subprobs[height-1]) {
3944:     PetscInt cdim;

3946:     PetscDSCreate(PetscObjectComm((PetscObject) prob), &prob->subprobs[height-1]);
3947:     PetscDSGetCoordinateDimension(prob, &cdim);
3948:     PetscDSSetCoordinateDimension(prob->subprobs[height-1], cdim);
3949:     for (f = 0; f < Nf; ++f) {
3950:       PetscFE      subfe;
3951:       PetscObject  obj;
3952:       PetscClassId id;

3954:       PetscDSGetDiscretization(prob, f, &obj);
3955:       PetscObjectGetClassId(obj, &id);
3956:       if (id == PETSCFE_CLASSID) PetscFEGetHeightSubspace((PetscFE) obj, height, &subfe);
3957:       else SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %d", f);
3958:       PetscDSSetDiscretization(prob->subprobs[height-1], f, (PetscObject) subfe);
3959:     }
3960:   }
3961:   *subprob = prob->subprobs[height-1];
3962:   return 0;
3963: }

3965: PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
3966: {
3967:   PetscObject    obj;
3968:   PetscClassId   id;
3969:   PetscInt       Nf;

3973:   *disctype = PETSC_DISC_NONE;
3974:   PetscDSGetNumFields(ds, &Nf);
3976:   PetscDSGetDiscretization(ds, f, &obj);
3977:   if (obj) {
3978:     PetscObjectGetClassId(obj, &id);
3979:     if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
3980:     else                       *disctype = PETSC_DISC_FV;
3981:   }
3982:   return 0;
3983: }

3985: static PetscErrorCode PetscDSDestroy_Basic(PetscDS ds)
3986: {
3987:   PetscFree(ds->data);
3988:   return 0;
3989: }

3991: static PetscErrorCode PetscDSInitialize_Basic(PetscDS ds)
3992: {
3993:   ds->ops->setfromoptions = NULL;
3994:   ds->ops->setup          = NULL;
3995:   ds->ops->view           = NULL;
3996:   ds->ops->destroy        = PetscDSDestroy_Basic;
3997:   return 0;
3998: }

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

4003:   Level: intermediate

4005: .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType()
4006: M*/

4008: PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS ds)
4009: {
4010:   PetscDS_Basic *b;

4013:   PetscNewLog(ds, &b);
4014:   ds->data = b;

4016:   PetscDSInitialize_Basic(ds);
4017:   return 0;
4018: }