1 #include <petsc/private/petscdsimpl.h> /*I "petscds.h" I*/
2
3 PetscClassId PETSCDS_CLASSID = 0;
4
5 PetscFunctionList PetscDSList = NULL;
6 PetscBool PetscDSRegisterAllCalled = PETSC_FALSE;
7
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.
11
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.
14
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 */
20
21 /*@C
22 PetscDSRegister - Adds a new PetscDS implementation
23
24 Not Collective
25
26 Input Parameters:
27 + name - The name of a new user-defined creation routine
28 - create_func - The creation routine itself
29
30 Notes:
31 PetscDSRegister() may be called multiple times to add several user-defined PetscDSs
32
33 Sample usage:
34 .vb
35 PetscDSRegister("my_ds", MyPetscDSCreate);
36 .ve
37
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
47
48 Level: advanced
49
50 Not available from Fortran
51
52 .seealso: PetscDSRegisterAll(), PetscDSRegisterDestroy()
53
54 @*/
PetscDSRegister(const char sname[],PetscErrorCode (* function)(PetscDS))55 PetscErrorCode PetscDSRegister(const char sname[], PetscErrorCode (*function)(PetscDS))
56 {
57 PetscErrorCode ierr;
58
59 PetscFunctionBegin;
60 ierr = PetscFunctionListAdd(&PetscDSList, sname, function);CHKERRQ(ierr);
61 PetscFunctionReturn(0);
62 }
63
64 /*@C
65 PetscDSSetType - Builds a particular PetscDS
66
67 Collective on prob
68
69 Input Parameters:
70 + prob - The PetscDS object
71 - name - The kind of system
72
73 Options Database Key:
74 . -petscds_type <type> - Sets the PetscDS type; use -help for a list of available types
75
76 Level: intermediate
77
78 Not available from Fortran
79
80 .seealso: PetscDSGetType(), PetscDSCreate()
81 @*/
PetscDSSetType(PetscDS prob,PetscDSType name)82 PetscErrorCode PetscDSSetType(PetscDS prob, PetscDSType name)
83 {
84 PetscErrorCode (*r)(PetscDS);
85 PetscBool match;
86 PetscErrorCode ierr;
87
88 PetscFunctionBegin;
89 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
90 ierr = PetscObjectTypeCompare((PetscObject) prob, name, &match);CHKERRQ(ierr);
91 if (match) PetscFunctionReturn(0);
92
93 ierr = PetscDSRegisterAll();CHKERRQ(ierr);
94 ierr = PetscFunctionListFind(PetscDSList, name, &r);CHKERRQ(ierr);
95 if (!r) SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscDS type: %s", name);
96
97 if (prob->ops->destroy) {
98 ierr = (*prob->ops->destroy)(prob);CHKERRQ(ierr);
99 prob->ops->destroy = NULL;
100 }
101 ierr = (*r)(prob);CHKERRQ(ierr);
102 ierr = PetscObjectChangeTypeName((PetscObject) prob, name);CHKERRQ(ierr);
103 PetscFunctionReturn(0);
104 }
105
106 /*@C
107 PetscDSGetType - Gets the PetscDS type name (as a string) from the object.
108
109 Not Collective
110
111 Input Parameter:
112 . prob - The PetscDS
113
114 Output Parameter:
115 . name - The PetscDS type name
116
117 Level: intermediate
118
119 Not available from Fortran
120
121 .seealso: PetscDSSetType(), PetscDSCreate()
122 @*/
PetscDSGetType(PetscDS prob,PetscDSType * name)123 PetscErrorCode PetscDSGetType(PetscDS prob, PetscDSType *name)
124 {
125 PetscErrorCode ierr;
126
127 PetscFunctionBegin;
128 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
129 PetscValidPointer(name, 2);
130 ierr = PetscDSRegisterAll();CHKERRQ(ierr);
131 *name = ((PetscObject) prob)->type_name;
132 PetscFunctionReturn(0);
133 }
134
PetscDSView_Ascii(PetscDS prob,PetscViewer viewer)135 static PetscErrorCode PetscDSView_Ascii(PetscDS prob, PetscViewer viewer)
136 {
137 PetscViewerFormat format;
138 const PetscScalar *constants;
139 PetscInt numConstants, f;
140 PetscErrorCode ierr;
141
142 PetscFunctionBegin;
143 ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
144 ierr = PetscViewerASCIIPrintf(viewer, "Discrete System with %d fields\n", prob->Nf);CHKERRQ(ierr);
145 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
146 ierr = PetscViewerASCIIPrintf(viewer, " cell total dim %D total comp %D\n", prob->totDim, prob->totComp);CHKERRQ(ierr);
147 if (prob->isHybrid) {ierr = PetscViewerASCIIPrintf(viewer, " hybrid cell\n");CHKERRQ(ierr);}
148 for (f = 0; f < prob->Nf; ++f) {
149 DSBoundary b;
150 PetscObject obj;
151 PetscClassId id;
152 PetscQuadrature q;
153 const char *name;
154 PetscInt Nc, Nq, Nqc;
155
156 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr);
157 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr);
158 ierr = PetscObjectGetName(obj, &name);CHKERRQ(ierr);
159 ierr = PetscViewerASCIIPrintf(viewer, "Field %s", name ? name : "<unknown>");CHKERRQ(ierr);
160 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr);
161 if (id == PETSCFE_CLASSID) {
162 ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr);
163 ierr = PetscFEGetQuadrature((PetscFE) obj, &q);CHKERRQ(ierr);
164 ierr = PetscViewerASCIIPrintf(viewer, " FEM");CHKERRQ(ierr);
165 } else if (id == PETSCFV_CLASSID) {
166 ierr = PetscFVGetNumComponents((PetscFV) obj, &Nc);CHKERRQ(ierr);
167 ierr = PetscFVGetQuadrature((PetscFV) obj, &q);CHKERRQ(ierr);
168 ierr = PetscViewerASCIIPrintf(viewer, " FVM");CHKERRQ(ierr);
169 }
170 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %D", f);
171 if (Nc > 1) {ierr = PetscViewerASCIIPrintf(viewer, "%D components", Nc);CHKERRQ(ierr);}
172 else {ierr = PetscViewerASCIIPrintf(viewer, "%D component ", Nc);CHKERRQ(ierr);}
173 if (prob->implicit[f]) {ierr = PetscViewerASCIIPrintf(viewer, " (implicit)");CHKERRQ(ierr);}
174 else {ierr = PetscViewerASCIIPrintf(viewer, " (explicit)");CHKERRQ(ierr);}
175 if (q) {
176 ierr = PetscQuadratureGetData(q, NULL, &Nqc, &Nq, NULL, NULL);CHKERRQ(ierr);
177 ierr = PetscViewerASCIIPrintf(viewer, " (Nq %D Nqc %D)", Nq, Nqc);CHKERRQ(ierr);
178 }
179 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr);
180 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr);
181 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
182 if (id == PETSCFE_CLASSID) {ierr = PetscFEView((PetscFE) obj, viewer);CHKERRQ(ierr);}
183 else if (id == PETSCFV_CLASSID) {ierr = PetscFVView((PetscFV) obj, viewer);CHKERRQ(ierr);}
184 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
185
186 for (b = prob->boundary; b; b = b->next) {
187 PetscInt c, i;
188
189 if (b->field != f) continue;
190 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
191 ierr = PetscViewerASCIIPrintf(viewer, "Boundary %s (%s) %s\n", b->name, b->labelname, DMBoundaryConditionTypes[b->type]);CHKERRQ(ierr);
192 if (!b->numcomps) {
193 ierr = PetscViewerASCIIPrintf(viewer, " all components\n");CHKERRQ(ierr);
194 } else {
195 ierr = PetscViewerASCIIPrintf(viewer, " components: ");CHKERRQ(ierr);
196 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr);
197 for (c = 0; c < b->numcomps; ++c) {
198 if (c > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
199 ierr = PetscViewerASCIIPrintf(viewer, "%D", b->comps[c]);CHKERRQ(ierr);
200 }
201 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr);
202 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr);
203 }
204 ierr = PetscViewerASCIIPrintf(viewer, " ids: ");CHKERRQ(ierr);
205 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr);
206 for (i = 0; i < b->numids; ++i) {
207 if (i > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);}
208 ierr = PetscViewerASCIIPrintf(viewer, "%D", b->ids[i]);CHKERRQ(ierr);
209 }
210 ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr);
211 ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr);
212 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
213 }
214 }
215 ierr = PetscDSGetConstants(prob, &numConstants, &constants);CHKERRQ(ierr);
216 if (numConstants) {
217 ierr = PetscViewerASCIIPrintf(viewer, "%D constants\n", numConstants);CHKERRQ(ierr);
218 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
219 for (f = 0; f < numConstants; ++f) {ierr = PetscViewerASCIIPrintf(viewer, "%g\n", (double) PetscRealPart(constants[f]));CHKERRQ(ierr);}
220 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
221 }
222 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
223 PetscFunctionReturn(0);
224 }
225
226 /*@C
227 PetscDSViewFromOptions - View from Options
228
229 Collective on PetscDS
230
231 Input Parameters:
232 + A - the PetscDS object
233 . obj - Optional object
234 - name - command line option
235
236 Level: intermediate
237 .seealso: PetscDS, PetscDSView, PetscObjectViewFromOptions(), PetscDSCreate()
238 @*/
PetscDSViewFromOptions(PetscDS A,PetscObject obj,const char name[])239 PetscErrorCode PetscDSViewFromOptions(PetscDS A,PetscObject obj,const char name[])
240 {
241 PetscErrorCode ierr;
242
243 PetscFunctionBegin;
244 PetscValidHeaderSpecific(A,PETSCDS_CLASSID,1);
245 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
246 PetscFunctionReturn(0);
247 }
248
249 /*@C
250 PetscDSView - Views a PetscDS
251
252 Collective on prob
253
254 Input Parameter:
255 + prob - the PetscDS object to view
256 - v - the viewer
257
258 Level: developer
259
260 .seealso PetscDSDestroy()
261 @*/
PetscDSView(PetscDS prob,PetscViewer v)262 PetscErrorCode PetscDSView(PetscDS prob, PetscViewer v)
263 {
264 PetscBool iascii;
265 PetscErrorCode ierr;
266
267 PetscFunctionBegin;
268 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
269 if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) prob), &v);CHKERRQ(ierr);}
270 else {PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 2);}
271 ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
272 if (iascii) {ierr = PetscDSView_Ascii(prob, v);CHKERRQ(ierr);}
273 if (prob->ops->view) {ierr = (*prob->ops->view)(prob, v);CHKERRQ(ierr);}
274 PetscFunctionReturn(0);
275 }
276
277 /*@
278 PetscDSSetFromOptions - sets parameters in a PetscDS from the options database
279
280 Collective on prob
281
282 Input Parameter:
283 . prob - the PetscDS object to set options for
284
285 Options Database:
286 + -petscds_type <type> : Set the DS type
287 . -petscds_view <view opt> : View the DS
288 . -petscds_jac_pre : Turn formation of a separate Jacobian preconditioner on and off
289 . -bc_<name> <ids> : Specify a list of label ids for a boundary condition
290 - -bc_<name>_comp <comps> : Specify a list of field components to constrain for a boundary condition
291
292 Level: developer
293
294 .seealso PetscDSView()
295 @*/
PetscDSSetFromOptions(PetscDS prob)296 PetscErrorCode PetscDSSetFromOptions(PetscDS prob)
297 {
298 DSBoundary b;
299 const char *defaultType;
300 char name[256];
301 PetscBool flg;
302 PetscErrorCode ierr;
303
304 PetscFunctionBegin;
305 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
306 if (!((PetscObject) prob)->type_name) {
307 defaultType = PETSCDSBASIC;
308 } else {
309 defaultType = ((PetscObject) prob)->type_name;
310 }
311 ierr = PetscDSRegisterAll();CHKERRQ(ierr);
312
313 ierr = PetscObjectOptionsBegin((PetscObject) prob);CHKERRQ(ierr);
314 for (b = prob->boundary; b; b = b->next) {
315 char optname[1024];
316 PetscInt ids[1024], len = 1024;
317 PetscBool flg;
318
319 ierr = PetscSNPrintf(optname, sizeof(optname), "-bc_%s", b->name);CHKERRQ(ierr);
320 ierr = PetscMemzero(ids, sizeof(ids));CHKERRQ(ierr);
321 ierr = PetscOptionsIntArray(optname, "List of boundary IDs", "", ids, &len, &flg);CHKERRQ(ierr);
322 if (flg) {
323 b->numids = len;
324 ierr = PetscFree(b->ids);CHKERRQ(ierr);
325 ierr = PetscMalloc1(len, &b->ids);CHKERRQ(ierr);
326 ierr = PetscArraycpy(b->ids, ids, len);CHKERRQ(ierr);
327 }
328 len = 1024;
329 ierr = PetscSNPrintf(optname, sizeof(optname), "-bc_%s_comp", b->name);CHKERRQ(ierr);
330 ierr = PetscMemzero(ids, sizeof(ids));CHKERRQ(ierr);
331 ierr = PetscOptionsIntArray(optname, "List of boundary field components", "", ids, &len, &flg);CHKERRQ(ierr);
332 if (flg) {
333 b->numcomps = len;
334 ierr = PetscFree(b->comps);CHKERRQ(ierr);
335 ierr = PetscMalloc1(len, &b->comps);CHKERRQ(ierr);
336 ierr = PetscArraycpy(b->comps, ids, len);CHKERRQ(ierr);
337 }
338 }
339 ierr = PetscOptionsFList("-petscds_type", "Discrete System", "PetscDSSetType", PetscDSList, defaultType, name, 256, &flg);CHKERRQ(ierr);
340 if (flg) {
341 ierr = PetscDSSetType(prob, name);CHKERRQ(ierr);
342 } else if (!((PetscObject) prob)->type_name) {
343 ierr = PetscDSSetType(prob, defaultType);CHKERRQ(ierr);
344 }
345 ierr = PetscOptionsBool("-petscds_jac_pre", "Discrete System", "PetscDSUseJacobianPreconditioner", prob->useJacPre, &prob->useJacPre, &flg);CHKERRQ(ierr);
346 if (prob->ops->setfromoptions) {ierr = (*prob->ops->setfromoptions)(prob);CHKERRQ(ierr);}
347 /* process any options handlers added with PetscObjectAddOptionsHandler() */
348 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) prob);CHKERRQ(ierr);
349 ierr = PetscOptionsEnd();CHKERRQ(ierr);
350 if (prob->Nf) {ierr = PetscDSViewFromOptions(prob, NULL, "-petscds_view");CHKERRQ(ierr);}
351 PetscFunctionReturn(0);
352 }
353
354 /*@C
355 PetscDSSetUp - Construct data structures for the PetscDS
356
357 Collective on prob
358
359 Input Parameter:
360 . prob - the PetscDS object to setup
361
362 Level: developer
363
364 .seealso PetscDSView(), PetscDSDestroy()
365 @*/
PetscDSSetUp(PetscDS prob)366 PetscErrorCode PetscDSSetUp(PetscDS prob)
367 {
368 const PetscInt Nf = prob->Nf;
369 PetscInt dim, dimEmbed, NbMax = 0, NcMax = 0, NqMax = 0, NsMax = 1, f;
370 PetscErrorCode ierr;
371
372 PetscFunctionBegin;
373 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
374 if (prob->setup) PetscFunctionReturn(0);
375 /* Calculate sizes */
376 ierr = PetscDSGetSpatialDimension(prob, &dim);CHKERRQ(ierr);
377 ierr = PetscDSGetCoordinateDimension(prob, &dimEmbed);CHKERRQ(ierr);
378 prob->totDim = prob->totComp = 0;
379 ierr = PetscMalloc2(Nf,&prob->Nc,Nf,&prob->Nb);CHKERRQ(ierr);
380 ierr = PetscCalloc2(Nf+1,&prob->off,Nf+1,&prob->offDer);CHKERRQ(ierr);
381 ierr = PetscMalloc2(Nf,&prob->T,Nf,&prob->Tf);CHKERRQ(ierr);
382 for (f = 0; f < Nf; ++f) {
383 PetscObject obj;
384 PetscClassId id;
385 PetscQuadrature q = NULL;
386 PetscInt Nq = 0, Nb, Nc;
387
388 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr);
389 if (!obj) {
390 /* Empty mesh */
391 Nb = Nc = 0;
392 prob->T[f] = prob->Tf[f] = NULL;
393 } else {
394 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr);
395 if (id == PETSCFE_CLASSID) {
396 PetscFE fe = (PetscFE) obj;
397
398 ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr);
399 ierr = PetscFEGetDimension(fe, &Nb);CHKERRQ(ierr);
400 ierr = PetscFEGetNumComponents(fe, &Nc);CHKERRQ(ierr);
401 ierr = PetscFEGetCellTabulation(fe, &prob->T[f]);CHKERRQ(ierr);
402 ierr = PetscFEGetFaceTabulation(fe, &prob->Tf[f]);CHKERRQ(ierr);
403 } else if (id == PETSCFV_CLASSID) {
404 PetscFV fv = (PetscFV) obj;
405
406 ierr = PetscFVGetQuadrature(fv, &q);CHKERRQ(ierr);
407 ierr = PetscFVGetNumComponents(fv, &Nc);CHKERRQ(ierr);
408 Nb = Nc;
409 ierr = PetscFVGetCellTabulation(fv, &prob->T[f]);CHKERRQ(ierr);
410 /* TODO: should PetscFV also have face tabulation? Otherwise there will be a null pointer in prob->basisFace */
411 } else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", f);
412 }
413 prob->Nc[f] = Nc;
414 prob->Nb[f] = Nb;
415 prob->off[f+1] = Nc + prob->off[f];
416 prob->offDer[f+1] = Nc*dim + prob->offDer[f];
417 if (q) {ierr = PetscQuadratureGetData(q, NULL, NULL, &Nq, NULL, NULL);CHKERRQ(ierr);}
418 NqMax = PetscMax(NqMax, Nq);
419 NbMax = PetscMax(NbMax, Nb);
420 NcMax = PetscMax(NcMax, Nc);
421 prob->totDim += Nb;
422 prob->totComp += Nc;
423 /* There are two faces for all fields but the cohesive field on a hybrid cell */
424 if (prob->isHybrid && (f < Nf-1)) prob->totDim += Nb;
425 }
426 /* Allocate works space */
427 if (prob->isHybrid) NsMax = 2;
428 ierr = PetscMalloc3(NsMax*prob->totComp,&prob->u,NsMax*prob->totComp,&prob->u_t,NsMax*prob->totComp*dimEmbed,&prob->u_x);CHKERRQ(ierr);
429 ierr = PetscMalloc5(dimEmbed,&prob->x,NbMax*NcMax,&prob->basisReal,NbMax*NcMax*dimEmbed,&prob->basisDerReal,NbMax*NcMax,&prob->testReal,NbMax*NcMax*dimEmbed,&prob->testDerReal);CHKERRQ(ierr);
430 ierr = PetscMalloc6(NsMax*NqMax*NcMax,&prob->f0,NsMax*NqMax*NcMax*dimEmbed,&prob->f1,
431 NsMax*NsMax*NqMax*NcMax*NcMax,&prob->g0,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g1,
432 NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed,&prob->g2,NsMax*NsMax*NqMax*NcMax*NcMax*dimEmbed*dimEmbed,&prob->g3);CHKERRQ(ierr);
433 if (prob->ops->setup) {ierr = (*prob->ops->setup)(prob);CHKERRQ(ierr);}
434 prob->setup = PETSC_TRUE;
435 PetscFunctionReturn(0);
436 }
437
PetscDSDestroyStructs_Static(PetscDS prob)438 static PetscErrorCode PetscDSDestroyStructs_Static(PetscDS prob)
439 {
440 PetscErrorCode ierr;
441
442 PetscFunctionBegin;
443 ierr = PetscFree2(prob->Nc,prob->Nb);CHKERRQ(ierr);
444 ierr = PetscFree2(prob->off,prob->offDer);CHKERRQ(ierr);
445 ierr = PetscFree2(prob->T,prob->Tf);CHKERRQ(ierr);
446 ierr = PetscFree3(prob->u,prob->u_t,prob->u_x);CHKERRQ(ierr);
447 ierr = PetscFree5(prob->x,prob->basisReal, prob->basisDerReal,prob->testReal,prob->testDerReal);CHKERRQ(ierr);
448 ierr = PetscFree6(prob->f0,prob->f1,prob->g0,prob->g1,prob->g2,prob->g3);CHKERRQ(ierr);
449 PetscFunctionReturn(0);
450 }
451
PetscDSEnlarge_Static(PetscDS prob,PetscInt NfNew)452 static PetscErrorCode PetscDSEnlarge_Static(PetscDS prob, PetscInt NfNew)
453 {
454 PetscObject *tmpd;
455 PetscBool *tmpi;
456 PetscPointFunc *tmpobj, *tmpf, *tmpup;
457 PetscPointJac *tmpg, *tmpgp, *tmpgt;
458 PetscBdPointFunc *tmpfbd;
459 PetscBdPointJac *tmpgbd, *tmpgpbd;
460 PetscRiemannFunc *tmpr;
461 PetscSimplePointFunc *tmpexactSol, *tmpexactSol_t;
462 void **tmpexactCtx, **tmpexactCtx_t;
463 void **tmpctx;
464 PetscInt Nf = prob->Nf, f;
465 PetscErrorCode ierr;
466
467 PetscFunctionBegin;
468 if (Nf >= NfNew) PetscFunctionReturn(0);
469 prob->setup = PETSC_FALSE;
470 ierr = PetscDSDestroyStructs_Static(prob);CHKERRQ(ierr);
471 ierr = PetscMalloc2(NfNew, &tmpd, NfNew, &tmpi);CHKERRQ(ierr);
472 for (f = 0; f < Nf; ++f) {tmpd[f] = prob->disc[f]; tmpi[f] = prob->implicit[f];}
473 for (f = Nf; f < NfNew; ++f) {tmpd[f] = NULL; tmpi[f] = PETSC_TRUE;}
474 ierr = PetscFree2(prob->disc, prob->implicit);CHKERRQ(ierr);
475 prob->Nf = NfNew;
476 prob->disc = tmpd;
477 prob->implicit = tmpi;
478 ierr = PetscCalloc7(NfNew, &tmpobj, NfNew*2, &tmpf, NfNew*NfNew*4, &tmpg, NfNew*NfNew*4, &tmpgp, NfNew*NfNew*4, &tmpgt, NfNew, &tmpr, NfNew, &tmpctx);CHKERRQ(ierr);
479 ierr = PetscCalloc1(NfNew, &tmpup);CHKERRQ(ierr);
480 for (f = 0; f < Nf; ++f) tmpobj[f] = prob->obj[f];
481 for (f = 0; f < Nf*2; ++f) tmpf[f] = prob->f[f];
482 for (f = 0; f < Nf*Nf*4; ++f) tmpg[f] = prob->g[f];
483 for (f = 0; f < Nf*Nf*4; ++f) tmpgp[f] = prob->gp[f];
484 for (f = 0; f < Nf; ++f) tmpr[f] = prob->r[f];
485 for (f = 0; f < Nf; ++f) tmpup[f] = prob->update[f];
486 for (f = 0; f < Nf; ++f) tmpctx[f] = prob->ctx[f];
487 for (f = Nf; f < NfNew; ++f) tmpobj[f] = NULL;
488 for (f = Nf*2; f < NfNew*2; ++f) tmpf[f] = NULL;
489 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpg[f] = NULL;
490 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgp[f] = NULL;
491 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgt[f] = NULL;
492 for (f = Nf; f < NfNew; ++f) tmpr[f] = NULL;
493 for (f = Nf; f < NfNew; ++f) tmpup[f] = NULL;
494 for (f = Nf; f < NfNew; ++f) tmpctx[f] = NULL;
495 ierr = PetscFree7(prob->obj, prob->f, prob->g, prob->gp, prob->gt, prob->r, prob->ctx);CHKERRQ(ierr);
496 ierr = PetscFree(prob->update);CHKERRQ(ierr);
497 prob->obj = tmpobj;
498 prob->f = tmpf;
499 prob->g = tmpg;
500 prob->gp = tmpgp;
501 prob->gt = tmpgt;
502 prob->r = tmpr;
503 prob->update = tmpup;
504 prob->ctx = tmpctx;
505 ierr = PetscCalloc7(NfNew*2, &tmpfbd, NfNew*NfNew*4, &tmpgbd, NfNew*NfNew*4, &tmpgpbd, NfNew, &tmpexactSol, NfNew, &tmpexactCtx, NfNew, &tmpexactSol_t, NfNew, &tmpexactCtx_t);CHKERRQ(ierr);
506 for (f = 0; f < Nf*2; ++f) tmpfbd[f] = prob->fBd[f];
507 for (f = 0; f < Nf*Nf*4; ++f) tmpgbd[f] = prob->gBd[f];
508 for (f = 0; f < Nf*Nf*4; ++f) tmpgpbd[f] = prob->gpBd[f];
509 for (f = 0; f < Nf; ++f) tmpexactSol[f] = prob->exactSol[f];
510 for (f = 0; f < Nf; ++f) tmpexactCtx[f] = prob->exactCtx[f];
511 for (f = 0; f < Nf; ++f) tmpexactSol_t[f] = prob->exactSol_t[f];
512 for (f = 0; f < Nf; ++f) tmpexactCtx_t[f] = prob->exactCtx_t[f];
513 for (f = Nf*2; f < NfNew*2; ++f) tmpfbd[f] = NULL;
514 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgbd[f] = NULL;
515 for (f = Nf*Nf*4; f < NfNew*NfNew*4; ++f) tmpgpbd[f] = NULL;
516 for (f = Nf; f < NfNew; ++f) tmpexactSol[f] = NULL;
517 for (f = Nf; f < NfNew; ++f) tmpexactCtx[f] = NULL;
518 for (f = Nf; f < NfNew; ++f) tmpexactSol_t[f] = NULL;
519 for (f = Nf; f < NfNew; ++f) tmpexactCtx_t[f] = NULL;
520 ierr = PetscFree7(prob->fBd, prob->gBd, prob->gpBd, prob->exactSol, prob->exactCtx, prob->exactSol_t, prob->exactCtx_t);CHKERRQ(ierr);
521 prob->fBd = tmpfbd;
522 prob->gBd = tmpgbd;
523 prob->gpBd = tmpgpbd;
524 prob->exactSol = tmpexactSol;
525 prob->exactCtx = tmpexactCtx;
526 prob->exactSol_t = tmpexactSol_t;
527 prob->exactCtx_t = tmpexactCtx_t;
528 PetscFunctionReturn(0);
529 }
530
531 /*@
532 PetscDSDestroy - Destroys a PetscDS object
533
534 Collective on prob
535
536 Input Parameter:
537 . prob - the PetscDS object to destroy
538
539 Level: developer
540
541 .seealso PetscDSView()
542 @*/
PetscDSDestroy(PetscDS * prob)543 PetscErrorCode PetscDSDestroy(PetscDS *prob)
544 {
545 PetscInt f;
546 DSBoundary next;
547 PetscErrorCode ierr;
548
549 PetscFunctionBegin;
550 if (!*prob) PetscFunctionReturn(0);
551 PetscValidHeaderSpecific((*prob), PETSCDS_CLASSID, 1);
552
553 if (--((PetscObject)(*prob))->refct > 0) {*prob = NULL; PetscFunctionReturn(0);}
554 ((PetscObject) (*prob))->refct = 0;
555 if ((*prob)->subprobs) {
556 PetscInt dim, d;
557
558 ierr = PetscDSGetSpatialDimension(*prob, &dim);CHKERRQ(ierr);
559 for (d = 0; d < dim; ++d) {ierr = PetscDSDestroy(&(*prob)->subprobs[d]);CHKERRQ(ierr);}
560 }
561 ierr = PetscFree((*prob)->subprobs);CHKERRQ(ierr);
562 ierr = PetscDSDestroyStructs_Static(*prob);CHKERRQ(ierr);
563 for (f = 0; f < (*prob)->Nf; ++f) {
564 ierr = PetscObjectDereference((*prob)->disc[f]);CHKERRQ(ierr);
565 }
566 ierr = PetscFree2((*prob)->disc, (*prob)->implicit);CHKERRQ(ierr);
567 ierr = PetscFree7((*prob)->obj,(*prob)->f,(*prob)->g,(*prob)->gp,(*prob)->gt,(*prob)->r,(*prob)->ctx);CHKERRQ(ierr);
568 ierr = PetscFree((*prob)->update);CHKERRQ(ierr);
569 ierr = PetscFree7((*prob)->fBd,(*prob)->gBd,(*prob)->gpBd,(*prob)->exactSol,(*prob)->exactCtx,(*prob)->exactSol_t,(*prob)->exactCtx_t);CHKERRQ(ierr);
570 if ((*prob)->ops->destroy) {ierr = (*(*prob)->ops->destroy)(*prob);CHKERRQ(ierr);}
571 next = (*prob)->boundary;
572 while (next) {
573 DSBoundary b = next;
574
575 next = b->next;
576 ierr = PetscFree(b->comps);CHKERRQ(ierr);
577 ierr = PetscFree(b->ids);CHKERRQ(ierr);
578 ierr = PetscFree(b->name);CHKERRQ(ierr);
579 ierr = PetscFree(b->labelname);CHKERRQ(ierr);
580 ierr = PetscFree(b);CHKERRQ(ierr);
581 }
582 ierr = PetscFree((*prob)->constants);CHKERRQ(ierr);
583 ierr = PetscHeaderDestroy(prob);CHKERRQ(ierr);
584 PetscFunctionReturn(0);
585 }
586
587 /*@
588 PetscDSCreate - Creates an empty PetscDS object. The type can then be set with PetscDSSetType().
589
590 Collective
591
592 Input Parameter:
593 . comm - The communicator for the PetscDS object
594
595 Output Parameter:
596 . prob - The PetscDS object
597
598 Level: beginner
599
600 .seealso: PetscDSSetType(), PETSCDSBASIC
601 @*/
PetscDSCreate(MPI_Comm comm,PetscDS * prob)602 PetscErrorCode PetscDSCreate(MPI_Comm comm, PetscDS *prob)
603 {
604 PetscDS p;
605 PetscErrorCode ierr;
606
607 PetscFunctionBegin;
608 PetscValidPointer(prob, 2);
609 *prob = NULL;
610 ierr = PetscDSInitializePackage();CHKERRQ(ierr);
611
612 ierr = PetscHeaderCreate(p, PETSCDS_CLASSID, "PetscDS", "Discrete System", "PetscDS", comm, PetscDSDestroy, PetscDSView);CHKERRQ(ierr);
613
614 p->Nf = 0;
615 p->setup = PETSC_FALSE;
616 p->numConstants = 0;
617 p->constants = NULL;
618 p->dimEmbed = -1;
619 p->useJacPre = PETSC_TRUE;
620
621 *prob = p;
622 PetscFunctionReturn(0);
623 }
624
625 /*@
626 PetscDSGetNumFields - Returns the number of fields in the DS
627
628 Not collective
629
630 Input Parameter:
631 . prob - The PetscDS object
632
633 Output Parameter:
634 . Nf - The number of fields
635
636 Level: beginner
637
638 .seealso: PetscDSGetSpatialDimension(), PetscDSCreate()
639 @*/
PetscDSGetNumFields(PetscDS prob,PetscInt * Nf)640 PetscErrorCode PetscDSGetNumFields(PetscDS prob, PetscInt *Nf)
641 {
642 PetscFunctionBegin;
643 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
644 PetscValidPointer(Nf, 2);
645 *Nf = prob->Nf;
646 PetscFunctionReturn(0);
647 }
648
649 /*@
650 PetscDSGetSpatialDimension - Returns the spatial dimension of the DS, meaning the topological dimension of the discretizations
651
652 Not collective
653
654 Input Parameter:
655 . prob - The PetscDS object
656
657 Output Parameter:
658 . dim - The spatial dimension
659
660 Level: beginner
661
662 .seealso: PetscDSGetCoordinateDimension(), PetscDSGetNumFields(), PetscDSCreate()
663 @*/
PetscDSGetSpatialDimension(PetscDS prob,PetscInt * dim)664 PetscErrorCode PetscDSGetSpatialDimension(PetscDS prob, PetscInt *dim)
665 {
666 PetscErrorCode ierr;
667
668 PetscFunctionBegin;
669 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
670 PetscValidPointer(dim, 2);
671 *dim = 0;
672 if (prob->Nf) {
673 PetscObject obj;
674 PetscClassId id;
675
676 ierr = PetscDSGetDiscretization(prob, 0, &obj);CHKERRQ(ierr);
677 if (obj) {
678 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr);
679 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetSpatialDimension((PetscFE) obj, dim);CHKERRQ(ierr);}
680 else if (id == PETSCFV_CLASSID) {ierr = PetscFVGetSpatialDimension((PetscFV) obj, dim);CHKERRQ(ierr);}
681 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
682 }
683 }
684 PetscFunctionReturn(0);
685 }
686
687 /*@
688 PetscDSGetCoordinateDimension - Returns the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded
689
690 Not collective
691
692 Input Parameter:
693 . prob - The PetscDS object
694
695 Output Parameter:
696 . dimEmbed - The coordinate dimension
697
698 Level: beginner
699
700 .seealso: PetscDSSetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
701 @*/
PetscDSGetCoordinateDimension(PetscDS prob,PetscInt * dimEmbed)702 PetscErrorCode PetscDSGetCoordinateDimension(PetscDS prob, PetscInt *dimEmbed)
703 {
704 PetscFunctionBegin;
705 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
706 PetscValidPointer(dimEmbed, 2);
707 if (prob->dimEmbed < 0) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONGSTATE, "No coordinate dimension set for this DS");
708 *dimEmbed = prob->dimEmbed;
709 PetscFunctionReturn(0);
710 }
711
712 /*@
713 PetscDSSetCoordinateDimension - Set the coordinate dimension of the DS, meaning the dimension of the space into which the discretiaztions are embedded
714
715 Logically collective on prob
716
717 Input Parameters:
718 + prob - The PetscDS object
719 - dimEmbed - The coordinate dimension
720
721 Level: beginner
722
723 .seealso: PetscDSGetCoordinateDimension(), PetscDSGetSpatialDimension(), PetscDSGetNumFields(), PetscDSCreate()
724 @*/
PetscDSSetCoordinateDimension(PetscDS prob,PetscInt dimEmbed)725 PetscErrorCode PetscDSSetCoordinateDimension(PetscDS prob, PetscInt dimEmbed)
726 {
727 PetscFunctionBegin;
728 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
729 if (dimEmbed < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate dimension must be non-negative, not %D", dimEmbed);
730 prob->dimEmbed = dimEmbed;
731 PetscFunctionReturn(0);
732 }
733
734 /*@
735 PetscDSGetHybrid - Returns the flag for a hybrid (cohesive) cell
736
737 Not collective
738
739 Input Parameter:
740 . prob - The PetscDS object
741
742 Output Parameter:
743 . isHybrid - The flag
744
745 Level: developer
746
747 .seealso: PetscDSSetHybrid(), PetscDSCreate()
748 @*/
PetscDSGetHybrid(PetscDS prob,PetscBool * isHybrid)749 PetscErrorCode PetscDSGetHybrid(PetscDS prob, PetscBool *isHybrid)
750 {
751 PetscFunctionBegin;
752 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
753 PetscValidPointer(isHybrid, 2);
754 *isHybrid = prob->isHybrid;
755 PetscFunctionReturn(0);
756 }
757
758 /*@
759 PetscDSSetHybrid - Set the flag for a hybrid (cohesive) cell
760
761 Not collective
762
763 Input Parameters:
764 + prob - The PetscDS object
765 - isHybrid - The flag
766
767 Level: developer
768
769 .seealso: PetscDSGetHybrid(), PetscDSCreate()
770 @*/
PetscDSSetHybrid(PetscDS prob,PetscBool isHybrid)771 PetscErrorCode PetscDSSetHybrid(PetscDS prob, PetscBool isHybrid)
772 {
773 PetscFunctionBegin;
774 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
775 prob->isHybrid = isHybrid;
776 PetscFunctionReturn(0);
777 }
778
779 /*@
780 PetscDSGetTotalDimension - Returns the total size of the approximation space for this system
781
782 Not collective
783
784 Input Parameter:
785 . prob - The PetscDS object
786
787 Output Parameter:
788 . dim - The total problem dimension
789
790 Level: beginner
791
792 .seealso: PetscDSGetNumFields(), PetscDSCreate()
793 @*/
PetscDSGetTotalDimension(PetscDS prob,PetscInt * dim)794 PetscErrorCode PetscDSGetTotalDimension(PetscDS prob, PetscInt *dim)
795 {
796 PetscErrorCode ierr;
797
798 PetscFunctionBegin;
799 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
800 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
801 PetscValidPointer(dim, 2);
802 *dim = prob->totDim;
803 PetscFunctionReturn(0);
804 }
805
806 /*@
807 PetscDSGetTotalComponents - Returns the total number of components in this system
808
809 Not collective
810
811 Input Parameter:
812 . prob - The PetscDS object
813
814 Output Parameter:
815 . dim - The total number of components
816
817 Level: beginner
818
819 .seealso: PetscDSGetNumFields(), PetscDSCreate()
820 @*/
PetscDSGetTotalComponents(PetscDS prob,PetscInt * Nc)821 PetscErrorCode PetscDSGetTotalComponents(PetscDS prob, PetscInt *Nc)
822 {
823 PetscErrorCode ierr;
824
825 PetscFunctionBegin;
826 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
827 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
828 PetscValidPointer(Nc, 2);
829 *Nc = prob->totComp;
830 PetscFunctionReturn(0);
831 }
832
833 /*@
834 PetscDSGetDiscretization - Returns the discretization object for the given field
835
836 Not collective
837
838 Input Parameters:
839 + prob - The PetscDS object
840 - f - The field number
841
842 Output Parameter:
843 . disc - The discretization object
844
845 Level: beginner
846
847 .seealso: PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
848 @*/
PetscDSGetDiscretization(PetscDS prob,PetscInt f,PetscObject * disc)849 PetscErrorCode PetscDSGetDiscretization(PetscDS prob, PetscInt f, PetscObject *disc)
850 {
851 PetscFunctionBegin;
852 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
853 PetscValidPointer(disc, 3);
854 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
855 *disc = prob->disc[f];
856 PetscFunctionReturn(0);
857 }
858
859 /*@
860 PetscDSSetDiscretization - Sets the discretization object for the given field
861
862 Not collective
863
864 Input Parameters:
865 + prob - The PetscDS object
866 . f - The field number
867 - disc - The discretization object
868
869 Level: beginner
870
871 .seealso: PetscDSGetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
872 @*/
PetscDSSetDiscretization(PetscDS prob,PetscInt f,PetscObject disc)873 PetscErrorCode PetscDSSetDiscretization(PetscDS prob, PetscInt f, PetscObject disc)
874 {
875 PetscErrorCode ierr;
876
877 PetscFunctionBegin;
878 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
879 if (disc) PetscValidPointer(disc, 3);
880 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
881 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
882 ierr = PetscObjectDereference(prob->disc[f]);CHKERRQ(ierr);
883 prob->disc[f] = disc;
884 ierr = PetscObjectReference(disc);CHKERRQ(ierr);
885 if (disc) {
886 PetscClassId id;
887
888 ierr = PetscObjectGetClassId(disc, &id);CHKERRQ(ierr);
889 if (id == PETSCFE_CLASSID) {
890 ierr = PetscDSSetImplicit(prob, f, PETSC_TRUE);CHKERRQ(ierr);
891 } else if (id == PETSCFV_CLASSID) {
892 ierr = PetscDSSetImplicit(prob, f, PETSC_FALSE);CHKERRQ(ierr);
893 }
894 }
895 PetscFunctionReturn(0);
896 }
897
898 /*@
899 PetscDSAddDiscretization - Adds a discretization object
900
901 Not collective
902
903 Input Parameters:
904 + prob - The PetscDS object
905 - disc - The boundary discretization object
906
907 Level: beginner
908
909 .seealso: PetscDSGetDiscretization(), PetscDSSetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
910 @*/
PetscDSAddDiscretization(PetscDS prob,PetscObject disc)911 PetscErrorCode PetscDSAddDiscretization(PetscDS prob, PetscObject disc)
912 {
913 PetscErrorCode ierr;
914
915 PetscFunctionBegin;
916 ierr = PetscDSSetDiscretization(prob, prob->Nf, disc);CHKERRQ(ierr);
917 PetscFunctionReturn(0);
918 }
919
920 /*@
921 PetscDSGetQuadrature - Returns the quadrature, which must agree for all fields in the DS
922
923 Not collective
924
925 Input Parameter:
926 . prob - The PetscDS object
927
928 Output Parameter:
929 . q - The quadrature object
930
931 Level: intermediate
932
933 .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
934 @*/
PetscDSGetQuadrature(PetscDS prob,PetscQuadrature * q)935 PetscErrorCode PetscDSGetQuadrature(PetscDS prob, PetscQuadrature *q)
936 {
937 PetscObject obj;
938 PetscClassId id;
939 PetscErrorCode ierr;
940
941 PetscFunctionBegin;
942 *q = NULL;
943 if (!prob->Nf) PetscFunctionReturn(0);
944 ierr = PetscDSGetDiscretization(prob, 0, &obj);CHKERRQ(ierr);
945 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr);
946 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetQuadrature((PetscFE) obj, q);CHKERRQ(ierr);}
947 else if (id == PETSCFV_CLASSID) {ierr = PetscFVGetQuadrature((PetscFV) obj, q);CHKERRQ(ierr);}
948 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unknown discretization type for field %d", 0);
949 PetscFunctionReturn(0);
950 }
951
952 /*@
953 PetscDSGetImplicit - Returns the flag for implicit solve for this field. This is just a guide for IMEX
954
955 Not collective
956
957 Input Parameters:
958 + prob - The PetscDS object
959 - f - The field number
960
961 Output Parameter:
962 . implicit - The flag indicating what kind of solve to use for this field
963
964 Level: developer
965
966 .seealso: PetscDSSetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
967 @*/
PetscDSGetImplicit(PetscDS prob,PetscInt f,PetscBool * implicit)968 PetscErrorCode PetscDSGetImplicit(PetscDS prob, PetscInt f, PetscBool *implicit)
969 {
970 PetscFunctionBegin;
971 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
972 PetscValidPointer(implicit, 3);
973 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
974 *implicit = prob->implicit[f];
975 PetscFunctionReturn(0);
976 }
977
978 /*@
979 PetscDSSetImplicit - Set the flag for implicit solve for this field. This is just a guide for IMEX
980
981 Not collective
982
983 Input Parameters:
984 + prob - The PetscDS object
985 . f - The field number
986 - implicit - The flag indicating what kind of solve to use for this field
987
988 Level: developer
989
990 .seealso: PetscDSGetImplicit(), PetscDSSetDiscretization(), PetscDSAddDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
991 @*/
PetscDSSetImplicit(PetscDS prob,PetscInt f,PetscBool implicit)992 PetscErrorCode PetscDSSetImplicit(PetscDS prob, PetscInt f, PetscBool implicit)
993 {
994 PetscFunctionBegin;
995 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
996 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
997 prob->implicit[f] = implicit;
998 PetscFunctionReturn(0);
999 }
1000
PetscDSGetObjective(PetscDS prob,PetscInt f,void (** obj)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar obj[]))1001 PetscErrorCode PetscDSGetObjective(PetscDS prob, PetscInt f,
1002 void (**obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1003 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1004 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1005 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1006 {
1007 PetscFunctionBegin;
1008 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1009 PetscValidPointer(obj, 2);
1010 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1011 *obj = prob->obj[f];
1012 PetscFunctionReturn(0);
1013 }
1014
PetscDSSetObjective(PetscDS prob,PetscInt f,void (* obj)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar obj[]))1015 PetscErrorCode PetscDSSetObjective(PetscDS prob, PetscInt f,
1016 void (*obj)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1017 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1018 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1019 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar obj[]))
1020 {
1021 PetscErrorCode ierr;
1022
1023 PetscFunctionBegin;
1024 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1025 if (obj) PetscValidFunction(obj, 2);
1026 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1027 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
1028 prob->obj[f] = obj;
1029 PetscFunctionReturn(0);
1030 }
1031
1032 /*@C
1033 PetscDSGetResidual - Get the pointwise residual function for a given test field
1034
1035 Not collective
1036
1037 Input Parameters:
1038 + prob - The PetscDS
1039 - f - The test field number
1040
1041 Output Parameters:
1042 + f0 - integrand for the test function term
1043 - f1 - integrand for the test function gradient term
1044
1045 Note: We are using a first order FEM model for the weak form:
1046
1047 \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)
1048
1049 The calling sequence for the callbacks f0 and f1 is given by:
1050
1051 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1052 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1053 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1054 $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1055
1056 + dim - the spatial dimension
1057 . Nf - the number of fields
1058 . uOff - the offset into u[] and u_t[] for each field
1059 . uOff_x - the offset into u_x[] for each field
1060 . u - each field evaluated at the current point
1061 . u_t - the time derivative of each field evaluated at the current point
1062 . u_x - the gradient of each field evaluated at the current point
1063 . aOff - the offset into a[] and a_t[] for each auxiliary field
1064 . aOff_x - the offset into a_x[] for each auxiliary field
1065 . a - each auxiliary field evaluated at the current point
1066 . a_t - the time derivative of each auxiliary field evaluated at the current point
1067 . a_x - the gradient of auxiliary each field evaluated at the current point
1068 . t - current time
1069 . x - coordinates of the current point
1070 . numConstants - number of constant parameters
1071 . constants - constant parameters
1072 - f0 - output values at the current point
1073
1074 Level: intermediate
1075
1076 .seealso: PetscDSSetResidual()
1077 @*/
PetscDSGetResidual(PetscDS prob,PetscInt f,void (** f0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f0[]),void (** f1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f1[]))1078 PetscErrorCode PetscDSGetResidual(PetscDS prob, PetscInt f,
1079 void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1080 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1081 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1082 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1083 void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1084 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1085 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1086 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1087 {
1088 PetscFunctionBegin;
1089 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1090 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1091 if (f0) {PetscValidPointer(f0, 3); *f0 = prob->f[f*2+0];}
1092 if (f1) {PetscValidPointer(f1, 4); *f1 = prob->f[f*2+1];}
1093 PetscFunctionReturn(0);
1094 }
1095
1096 /*@C
1097 PetscDSSetResidual - Set the pointwise residual function for a given test field
1098
1099 Not collective
1100
1101 Input Parameters:
1102 + prob - The PetscDS
1103 . f - The test field number
1104 . f0 - integrand for the test function term
1105 - f1 - integrand for the test function gradient term
1106
1107 Note: We are using a first order FEM model for the weak form:
1108
1109 \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)
1110
1111 The calling sequence for the callbacks f0 and f1 is given by:
1112
1113 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1114 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1115 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1116 $ PetscReal t, const PetscReal x[], PetscScalar f0[])
1117
1118 + dim - the spatial dimension
1119 . Nf - the number of fields
1120 . uOff - the offset into u[] and u_t[] for each field
1121 . uOff_x - the offset into u_x[] for each field
1122 . u - each field evaluated at the current point
1123 . u_t - the time derivative of each field evaluated at the current point
1124 . u_x - the gradient of each field evaluated at the current point
1125 . aOff - the offset into a[] and a_t[] for each auxiliary field
1126 . aOff_x - the offset into a_x[] for each auxiliary field
1127 . a - each auxiliary field evaluated at the current point
1128 . a_t - the time derivative of each auxiliary field evaluated at the current point
1129 . a_x - the gradient of auxiliary each field evaluated at the current point
1130 . t - current time
1131 . x - coordinates of the current point
1132 . numConstants - number of constant parameters
1133 . constants - constant parameters
1134 - f0 - output values at the current point
1135
1136 Level: intermediate
1137
1138 .seealso: PetscDSGetResidual()
1139 @*/
PetscDSSetResidual(PetscDS prob,PetscInt f,void (* f0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f0[]),void (* f1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f1[]))1140 PetscErrorCode PetscDSSetResidual(PetscDS prob, PetscInt f,
1141 void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1142 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1143 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1144 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
1145 void (*f1)(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[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
1149 {
1150 PetscErrorCode ierr;
1151
1152 PetscFunctionBegin;
1153 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1154 if (f0) PetscValidFunction(f0, 3);
1155 if (f1) PetscValidFunction(f1, 4);
1156 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1157 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
1158 prob->f[f*2+0] = f0;
1159 prob->f[f*2+1] = f1;
1160 PetscFunctionReturn(0);
1161 }
1162
1163 /*@C
1164 PetscDSHasJacobian - Signals that Jacobian functions have been set
1165
1166 Not collective
1167
1168 Input Parameter:
1169 . prob - The PetscDS
1170
1171 Output Parameter:
1172 . hasJac - flag that pointwise function for the Jacobian has been set
1173
1174 Level: intermediate
1175
1176 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1177 @*/
PetscDSHasJacobian(PetscDS prob,PetscBool * hasJac)1178 PetscErrorCode PetscDSHasJacobian(PetscDS prob, PetscBool *hasJac)
1179 {
1180 PetscInt f, g, h;
1181
1182 PetscFunctionBegin;
1183 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1184 *hasJac = PETSC_FALSE;
1185 for (f = 0; f < prob->Nf; ++f) {
1186 for (g = 0; g < prob->Nf; ++g) {
1187 for (h = 0; h < 4; ++h) {
1188 if (prob->g[(f*prob->Nf + g)*4+h]) *hasJac = PETSC_TRUE;
1189 }
1190 }
1191 }
1192 PetscFunctionReturn(0);
1193 }
1194
1195 /*@C
1196 PetscDSGetJacobian - Get the pointwise Jacobian function for given test and basis field
1197
1198 Not collective
1199
1200 Input Parameters:
1201 + prob - The PetscDS
1202 . f - The test field number
1203 - g - The field number
1204
1205 Output Parameters:
1206 + g0 - integrand for the test and basis function term
1207 . g1 - integrand for the test function and basis function gradient term
1208 . g2 - integrand for the test function gradient and basis function term
1209 - g3 - integrand for the test function gradient and basis function gradient term
1210
1211 Note: We are using a first order FEM model for the weak form:
1212
1213 \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
1214
1215 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1216
1217 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1218 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1219 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1220 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1221
1222 + dim - the spatial dimension
1223 . Nf - the number of fields
1224 . uOff - the offset into u[] and u_t[] for each field
1225 . uOff_x - the offset into u_x[] for each field
1226 . u - each field evaluated at the current point
1227 . u_t - the time derivative of each field evaluated at the current point
1228 . u_x - the gradient of each field evaluated at the current point
1229 . aOff - the offset into a[] and a_t[] for each auxiliary field
1230 . aOff_x - the offset into a_x[] for each auxiliary field
1231 . a - each auxiliary field evaluated at the current point
1232 . a_t - the time derivative of each auxiliary field evaluated at the current point
1233 . a_x - the gradient of auxiliary each field evaluated at the current point
1234 . t - current time
1235 . u_tShift - the multiplier a for dF/dU_t
1236 . x - coordinates of the current point
1237 . numConstants - number of constant parameters
1238 . constants - constant parameters
1239 - g0 - output values at the current point
1240
1241 Level: intermediate
1242
1243 .seealso: PetscDSSetJacobian()
1244 @*/
PetscDSGetJacobian(PetscDS prob,PetscInt f,PetscInt g,void (** g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (** g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (** g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (** g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))1245 PetscErrorCode PetscDSGetJacobian(PetscDS prob, PetscInt f, PetscInt g,
1246 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1247 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1248 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1249 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1250 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1251 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1252 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1253 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1254 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1255 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1256 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1257 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1258 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1259 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1260 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1261 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1262 {
1263 PetscFunctionBegin;
1264 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1265 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1266 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
1267 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->g[(f*prob->Nf + g)*4+0];}
1268 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->g[(f*prob->Nf + g)*4+1];}
1269 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->g[(f*prob->Nf + g)*4+2];}
1270 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->g[(f*prob->Nf + g)*4+3];}
1271 PetscFunctionReturn(0);
1272 }
1273
1274 /*@C
1275 PetscDSSetJacobian - Set the pointwise Jacobian function for given test and basis fields
1276
1277 Not collective
1278
1279 Input Parameters:
1280 + prob - The PetscDS
1281 . f - The test field number
1282 . g - The field number
1283 . g0 - integrand for the test and basis function term
1284 . g1 - integrand for the test function and basis function gradient term
1285 . g2 - integrand for the test function gradient and basis function term
1286 - g3 - integrand for the test function gradient and basis function gradient term
1287
1288 Note: We are using a first order FEM model for the weak form:
1289
1290 \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
1291
1292 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1293
1294 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1295 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1296 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1297 $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1298
1299 + dim - the spatial dimension
1300 . Nf - the number of fields
1301 . uOff - the offset into u[] and u_t[] for each field
1302 . uOff_x - the offset into u_x[] for each field
1303 . u - each field evaluated at the current point
1304 . u_t - the time derivative of each field evaluated at the current point
1305 . u_x - the gradient of each field evaluated at the current point
1306 . aOff - the offset into a[] and a_t[] for each auxiliary field
1307 . aOff_x - the offset into a_x[] for each auxiliary field
1308 . a - each auxiliary field evaluated at the current point
1309 . a_t - the time derivative of each auxiliary field evaluated at the current point
1310 . a_x - the gradient of auxiliary each field evaluated at the current point
1311 . t - current time
1312 . u_tShift - the multiplier a for dF/dU_t
1313 . x - coordinates of the current point
1314 . numConstants - number of constant parameters
1315 . constants - constant parameters
1316 - g0 - output values at the current point
1317
1318 Level: intermediate
1319
1320 .seealso: PetscDSGetJacobian()
1321 @*/
PetscDSSetJacobian(PetscDS prob,PetscInt f,PetscInt g,void (* g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (* g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (* g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (* g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))1322 PetscErrorCode PetscDSSetJacobian(PetscDS prob, PetscInt f, PetscInt g,
1323 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1324 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1325 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1326 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1327 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1328 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1329 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1330 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1331 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1332 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1333 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1334 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1335 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1336 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1337 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1338 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1339 {
1340 PetscErrorCode ierr;
1341
1342 PetscFunctionBegin;
1343 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1344 if (g0) PetscValidFunction(g0, 4);
1345 if (g1) PetscValidFunction(g1, 5);
1346 if (g2) PetscValidFunction(g2, 6);
1347 if (g3) PetscValidFunction(g3, 7);
1348 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1349 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1350 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr);
1351 prob->g[(f*prob->Nf + g)*4+0] = g0;
1352 prob->g[(f*prob->Nf + g)*4+1] = g1;
1353 prob->g[(f*prob->Nf + g)*4+2] = g2;
1354 prob->g[(f*prob->Nf + g)*4+3] = g3;
1355 PetscFunctionReturn(0);
1356 }
1357
1358 /*@C
1359 PetscDSUseJacobianPreconditioner - Whether to construct a Jacobian preconditioner
1360
1361 Not collective
1362
1363 Input Parameters:
1364 + prob - The PetscDS
1365 - useJacPre - flag that enables construction of a Jacobian preconditioner
1366
1367 Level: intermediate
1368
1369 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1370 @*/
PetscDSUseJacobianPreconditioner(PetscDS prob,PetscBool useJacPre)1371 PetscErrorCode PetscDSUseJacobianPreconditioner(PetscDS prob, PetscBool useJacPre)
1372 {
1373 PetscFunctionBegin;
1374 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1375 prob->useJacPre = useJacPre;
1376 PetscFunctionReturn(0);
1377 }
1378
1379 /*@C
1380 PetscDSHasJacobianPreconditioner - Signals that a Jacobian preconditioner matrix has been set
1381
1382 Not collective
1383
1384 Input Parameter:
1385 . prob - The PetscDS
1386
1387 Output Parameter:
1388 . hasJacPre - flag that pointwise function for Jacobian preconditioner matrix has been set
1389
1390 Level: intermediate
1391
1392 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1393 @*/
PetscDSHasJacobianPreconditioner(PetscDS prob,PetscBool * hasJacPre)1394 PetscErrorCode PetscDSHasJacobianPreconditioner(PetscDS prob, PetscBool *hasJacPre)
1395 {
1396 PetscInt f, g, h;
1397
1398 PetscFunctionBegin;
1399 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1400 *hasJacPre = PETSC_FALSE;
1401 if (!prob->useJacPre) PetscFunctionReturn(0);
1402 for (f = 0; f < prob->Nf; ++f) {
1403 for (g = 0; g < prob->Nf; ++g) {
1404 for (h = 0; h < 4; ++h) {
1405 if (prob->gp[(f*prob->Nf + g)*4+h]) *hasJacPre = PETSC_TRUE;
1406 }
1407 }
1408 }
1409 PetscFunctionReturn(0);
1410 }
1411
1412 /*@C
1413 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.
1414
1415 Not collective
1416
1417 Input Parameters:
1418 + prob - The PetscDS
1419 . f - The test field number
1420 - g - The field number
1421
1422 Output Parameters:
1423 + g0 - integrand for the test and basis function term
1424 . g1 - integrand for the test function and basis function gradient term
1425 . g2 - integrand for the test function gradient and basis function term
1426 - g3 - integrand for the test function gradient and basis function gradient term
1427
1428 Note: We are using a first order FEM model for the weak form:
1429
1430 \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
1431
1432 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1433
1434 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1435 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1436 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1437 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1438
1439 + dim - the spatial dimension
1440 . Nf - the number of fields
1441 . uOff - the offset into u[] and u_t[] for each field
1442 . uOff_x - the offset into u_x[] for each field
1443 . u - each field evaluated at the current point
1444 . u_t - the time derivative of each field evaluated at the current point
1445 . u_x - the gradient of each field evaluated at the current point
1446 . aOff - the offset into a[] and a_t[] for each auxiliary field
1447 . aOff_x - the offset into a_x[] for each auxiliary field
1448 . a - each auxiliary field evaluated at the current point
1449 . a_t - the time derivative of each auxiliary field evaluated at the current point
1450 . a_x - the gradient of auxiliary each field evaluated at the current point
1451 . t - current time
1452 . u_tShift - the multiplier a for dF/dU_t
1453 . x - coordinates of the current point
1454 . numConstants - number of constant parameters
1455 . constants - constant parameters
1456 - g0 - output values at the current point
1457
1458 Level: intermediate
1459
1460 .seealso: PetscDSSetJacobianPreconditioner(), PetscDSGetJacobian()
1461 @*/
PetscDSGetJacobianPreconditioner(PetscDS prob,PetscInt f,PetscInt g,void (** g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (** g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (** g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (** g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))1462 PetscErrorCode PetscDSGetJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g,
1463 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1464 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1465 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1466 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1467 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1468 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1469 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1470 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1471 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1472 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1473 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1474 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1475 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1476 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1477 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1478 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1479 {
1480 PetscFunctionBegin;
1481 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1482 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1483 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
1484 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gp[(f*prob->Nf + g)*4+0];}
1485 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gp[(f*prob->Nf + g)*4+1];}
1486 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gp[(f*prob->Nf + g)*4+2];}
1487 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gp[(f*prob->Nf + g)*4+3];}
1488 PetscFunctionReturn(0);
1489 }
1490
1491 /*@C
1492 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.
1493
1494 Not collective
1495
1496 Input Parameters:
1497 + prob - The PetscDS
1498 . f - The test field number
1499 . g - The field number
1500 . g0 - integrand for the test and basis function term
1501 . g1 - integrand for the test function and basis function gradient term
1502 . g2 - integrand for the test function gradient and basis function term
1503 - g3 - integrand for the test function gradient and basis function gradient term
1504
1505 Note: We are using a first order FEM model for the weak form:
1506
1507 \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
1508
1509 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1510
1511 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1512 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1513 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1514 $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1515
1516 + dim - the spatial dimension
1517 . Nf - the number of fields
1518 . uOff - the offset into u[] and u_t[] for each field
1519 . uOff_x - the offset into u_x[] for each field
1520 . u - each field evaluated at the current point
1521 . u_t - the time derivative of each field evaluated at the current point
1522 . u_x - the gradient of each field evaluated at the current point
1523 . aOff - the offset into a[] and a_t[] for each auxiliary field
1524 . aOff_x - the offset into a_x[] for each auxiliary field
1525 . a - each auxiliary field evaluated at the current point
1526 . a_t - the time derivative of each auxiliary field evaluated at the current point
1527 . a_x - the gradient of auxiliary each field evaluated at the current point
1528 . t - current time
1529 . u_tShift - the multiplier a for dF/dU_t
1530 . x - coordinates of the current point
1531 . numConstants - number of constant parameters
1532 . constants - constant parameters
1533 - g0 - output values at the current point
1534
1535 Level: intermediate
1536
1537 .seealso: PetscDSGetJacobianPreconditioner(), PetscDSSetJacobian()
1538 @*/
PetscDSSetJacobianPreconditioner(PetscDS prob,PetscInt f,PetscInt g,void (* g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (* g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (* g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (* g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))1539 PetscErrorCode PetscDSSetJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g,
1540 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1541 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1542 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1543 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1544 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1545 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1546 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1547 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1548 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1549 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1550 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1551 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1552 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1553 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1554 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1555 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1556 {
1557 PetscErrorCode ierr;
1558
1559 PetscFunctionBegin;
1560 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1561 if (g0) PetscValidFunction(g0, 4);
1562 if (g1) PetscValidFunction(g1, 5);
1563 if (g2) PetscValidFunction(g2, 6);
1564 if (g3) PetscValidFunction(g3, 7);
1565 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1566 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1567 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr);
1568 prob->gp[(f*prob->Nf + g)*4+0] = g0;
1569 prob->gp[(f*prob->Nf + g)*4+1] = g1;
1570 prob->gp[(f*prob->Nf + g)*4+2] = g2;
1571 prob->gp[(f*prob->Nf + g)*4+3] = g3;
1572 PetscFunctionReturn(0);
1573 }
1574
1575 /*@C
1576 PetscDSHasDynamicJacobian - Signals that a dynamic Jacobian, dF/du_t, has been set
1577
1578 Not collective
1579
1580 Input Parameter:
1581 . prob - The PetscDS
1582
1583 Output Parameter:
1584 . hasDynJac - flag that pointwise function for dynamic Jacobian has been set
1585
1586 Level: intermediate
1587
1588 .seealso: PetscDSGetDynamicJacobian(), PetscDSSetDynamicJacobian(), PetscDSGetJacobian()
1589 @*/
PetscDSHasDynamicJacobian(PetscDS prob,PetscBool * hasDynJac)1590 PetscErrorCode PetscDSHasDynamicJacobian(PetscDS prob, PetscBool *hasDynJac)
1591 {
1592 PetscInt f, g, h;
1593
1594 PetscFunctionBegin;
1595 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1596 *hasDynJac = PETSC_FALSE;
1597 for (f = 0; f < prob->Nf; ++f) {
1598 for (g = 0; g < prob->Nf; ++g) {
1599 for (h = 0; h < 4; ++h) {
1600 if (prob->gt[(f*prob->Nf + g)*4+h]) *hasDynJac = PETSC_TRUE;
1601 }
1602 }
1603 }
1604 PetscFunctionReturn(0);
1605 }
1606
1607 /*@C
1608 PetscDSGetDynamicJacobian - Get the pointwise dynamic Jacobian, dF/du_t, function for given test and basis field
1609
1610 Not collective
1611
1612 Input Parameters:
1613 + prob - The PetscDS
1614 . f - The test field number
1615 - g - The field number
1616
1617 Output Parameters:
1618 + g0 - integrand for the test and basis function term
1619 . g1 - integrand for the test function and basis function gradient term
1620 . g2 - integrand for the test function gradient and basis function term
1621 - g3 - integrand for the test function gradient and basis function gradient term
1622
1623 Note: We are using a first order FEM model for the weak form:
1624
1625 \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
1626
1627 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1628
1629 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1630 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1631 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1632 $ PetscReal t, const PetscReal u_tShift, const PetscReal x[], PetscScalar g0[])
1633
1634 + dim - the spatial dimension
1635 . Nf - the number of fields
1636 . uOff - the offset into u[] and u_t[] for each field
1637 . uOff_x - the offset into u_x[] for each field
1638 . u - each field evaluated at the current point
1639 . u_t - the time derivative of each field evaluated at the current point
1640 . u_x - the gradient of each field evaluated at the current point
1641 . aOff - the offset into a[] and a_t[] for each auxiliary field
1642 . aOff_x - the offset into a_x[] for each auxiliary field
1643 . a - each auxiliary field evaluated at the current point
1644 . a_t - the time derivative of each auxiliary field evaluated at the current point
1645 . a_x - the gradient of auxiliary each field evaluated at the current point
1646 . t - current time
1647 . u_tShift - the multiplier a for dF/dU_t
1648 . x - coordinates of the current point
1649 . numConstants - number of constant parameters
1650 . constants - constant parameters
1651 - g0 - output values at the current point
1652
1653 Level: intermediate
1654
1655 .seealso: PetscDSSetJacobian()
1656 @*/
PetscDSGetDynamicJacobian(PetscDS prob,PetscInt f,PetscInt g,void (** g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (** g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (** g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (** g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))1657 PetscErrorCode PetscDSGetDynamicJacobian(PetscDS prob, PetscInt f, PetscInt g,
1658 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1659 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1660 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1661 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1662 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1663 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1664 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1665 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1666 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1667 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1668 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1669 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1670 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1671 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1672 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1673 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1674 {
1675 PetscFunctionBegin;
1676 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1677 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1678 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
1679 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gt[(f*prob->Nf + g)*4+0];}
1680 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gt[(f*prob->Nf + g)*4+1];}
1681 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gt[(f*prob->Nf + g)*4+2];}
1682 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gt[(f*prob->Nf + g)*4+3];}
1683 PetscFunctionReturn(0);
1684 }
1685
1686 /*@C
1687 PetscDSSetDynamicJacobian - Set the pointwise dynamic Jacobian, dF/du_t, function for given test and basis fields
1688
1689 Not collective
1690
1691 Input Parameters:
1692 + prob - The PetscDS
1693 . f - The test field number
1694 . g - The field number
1695 . g0 - integrand for the test and basis function term
1696 . g1 - integrand for the test function and basis function gradient term
1697 . g2 - integrand for the test function gradient and basis function term
1698 - g3 - integrand for the test function gradient and basis function gradient term
1699
1700 Note: We are using a first order FEM model for the weak form:
1701
1702 \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
1703
1704 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
1705
1706 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1707 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1708 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1709 $ PetscReal t, const PetscReal x[], PetscScalar g0[])
1710
1711 + dim - the spatial dimension
1712 . Nf - the number of fields
1713 . uOff - the offset into u[] and u_t[] for each field
1714 . uOff_x - the offset into u_x[] for each field
1715 . u - each field evaluated at the current point
1716 . u_t - the time derivative of each field evaluated at the current point
1717 . u_x - the gradient of each field evaluated at the current point
1718 . aOff - the offset into a[] and a_t[] for each auxiliary field
1719 . aOff_x - the offset into a_x[] for each auxiliary field
1720 . a - each auxiliary field evaluated at the current point
1721 . a_t - the time derivative of each auxiliary field evaluated at the current point
1722 . a_x - the gradient of auxiliary each field evaluated at the current point
1723 . t - current time
1724 . u_tShift - the multiplier a for dF/dU_t
1725 . x - coordinates of the current point
1726 . numConstants - number of constant parameters
1727 . constants - constant parameters
1728 - g0 - output values at the current point
1729
1730 Level: intermediate
1731
1732 .seealso: PetscDSGetJacobian()
1733 @*/
PetscDSSetDynamicJacobian(PetscDS prob,PetscInt f,PetscInt g,void (* g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (* g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (* g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (* g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))1734 PetscErrorCode PetscDSSetDynamicJacobian(PetscDS prob, PetscInt f, PetscInt g,
1735 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1736 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1737 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1738 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
1739 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1740 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1741 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1742 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
1743 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1744 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1745 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1746 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
1747 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1748 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1749 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1750 PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
1751 {
1752 PetscErrorCode ierr;
1753
1754 PetscFunctionBegin;
1755 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1756 if (g0) PetscValidFunction(g0, 4);
1757 if (g1) PetscValidFunction(g1, 5);
1758 if (g2) PetscValidFunction(g2, 6);
1759 if (g3) PetscValidFunction(g3, 7);
1760 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1761 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
1762 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr);
1763 prob->gt[(f*prob->Nf + g)*4+0] = g0;
1764 prob->gt[(f*prob->Nf + g)*4+1] = g1;
1765 prob->gt[(f*prob->Nf + g)*4+2] = g2;
1766 prob->gt[(f*prob->Nf + g)*4+3] = g3;
1767 PetscFunctionReturn(0);
1768 }
1769
1770 /*@C
1771 PetscDSGetRiemannSolver - Returns the Riemann solver for the given field
1772
1773 Not collective
1774
1775 Input Arguments:
1776 + prob - The PetscDS object
1777 - f - The field number
1778
1779 Output Argument:
1780 . r - Riemann solver
1781
1782 Calling sequence for r:
1783
1784 $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1785
1786 + dim - The spatial dimension
1787 . Nf - The number of fields
1788 . x - The coordinates at a point on the interface
1789 . n - The normal vector to the interface
1790 . uL - The state vector to the left of the interface
1791 . uR - The state vector to the right of the interface
1792 . flux - output array of flux through the interface
1793 . numConstants - number of constant parameters
1794 . constants - constant parameters
1795 - ctx - optional user context
1796
1797 Level: intermediate
1798
1799 .seealso: PetscDSSetRiemannSolver()
1800 @*/
PetscDSGetRiemannSolver(PetscDS prob,PetscInt f,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))1801 PetscErrorCode PetscDSGetRiemannSolver(PetscDS prob, PetscInt f,
1802 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))
1803 {
1804 PetscFunctionBegin;
1805 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1806 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1807 PetscValidPointer(r, 3);
1808 *r = prob->r[f];
1809 PetscFunctionReturn(0);
1810 }
1811
1812 /*@C
1813 PetscDSSetRiemannSolver - Sets the Riemann solver for the given field
1814
1815 Not collective
1816
1817 Input Arguments:
1818 + prob - The PetscDS object
1819 . f - The field number
1820 - r - Riemann solver
1821
1822 Calling sequence for r:
1823
1824 $ r(PetscInt dim, PetscInt Nf, const PetscReal x[], const PetscReal n[], const PetscScalar uL[], const PetscScalar uR[], PetscScalar flux[], void *ctx)
1825
1826 + dim - The spatial dimension
1827 . Nf - The number of fields
1828 . x - The coordinates at a point on the interface
1829 . n - The normal vector to the interface
1830 . uL - The state vector to the left of the interface
1831 . uR - The state vector to the right of the interface
1832 . flux - output array of flux through the interface
1833 . numConstants - number of constant parameters
1834 . constants - constant parameters
1835 - ctx - optional user context
1836
1837 Level: intermediate
1838
1839 .seealso: PetscDSGetRiemannSolver()
1840 @*/
PetscDSSetRiemannSolver(PetscDS prob,PetscInt f,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))1841 PetscErrorCode PetscDSSetRiemannSolver(PetscDS prob, PetscInt f,
1842 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))
1843 {
1844 PetscErrorCode ierr;
1845
1846 PetscFunctionBegin;
1847 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1848 if (r) PetscValidFunction(r, 3);
1849 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1850 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
1851 prob->r[f] = r;
1852 PetscFunctionReturn(0);
1853 }
1854
1855 /*@C
1856 PetscDSGetUpdate - Get the pointwise update function for a given field
1857
1858 Not collective
1859
1860 Input Parameters:
1861 + prob - The PetscDS
1862 - f - The field number
1863
1864 Output Parameters:
1865 . update - update function
1866
1867 Note: The calling sequence for the callback update is given by:
1868
1869 $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1870 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1871 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1872 $ PetscReal t, const PetscReal x[], PetscScalar uNew[])
1873
1874 + dim - the spatial dimension
1875 . Nf - the number of fields
1876 . uOff - the offset into u[] and u_t[] for each field
1877 . uOff_x - the offset into u_x[] for each field
1878 . u - each field evaluated at the current point
1879 . u_t - the time derivative of each field evaluated at the current point
1880 . u_x - the gradient of each field evaluated at the current point
1881 . aOff - the offset into a[] and a_t[] for each auxiliary field
1882 . aOff_x - the offset into a_x[] for each auxiliary field
1883 . a - each auxiliary field evaluated at the current point
1884 . a_t - the time derivative of each auxiliary field evaluated at the current point
1885 . a_x - the gradient of auxiliary each field evaluated at the current point
1886 . t - current time
1887 . x - coordinates of the current point
1888 - uNew - new value for field at the current point
1889
1890 Level: intermediate
1891
1892 .seealso: PetscDSSetUpdate(), PetscDSSetResidual()
1893 @*/
PetscDSGetUpdate(PetscDS prob,PetscInt f,void (** update)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar uNew[]))1894 PetscErrorCode PetscDSGetUpdate(PetscDS prob, PetscInt f,
1895 void (**update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1896 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1897 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1898 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
1899 {
1900 PetscFunctionBegin;
1901 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1902 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1903 if (update) {PetscValidPointer(update, 3); *update = prob->update[f];}
1904 PetscFunctionReturn(0);
1905 }
1906
1907 /*@C
1908 PetscDSSetUpdate - Set the pointwise update function for a given field
1909
1910 Not collective
1911
1912 Input Parameters:
1913 + prob - The PetscDS
1914 . f - The field number
1915 - update - update function
1916
1917 Note: The calling sequence for the callback update is given by:
1918
1919 $ update(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1920 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1921 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1922 $ PetscReal t, const PetscReal x[], PetscScalar uNew[])
1923
1924 + dim - the spatial dimension
1925 . Nf - the number of fields
1926 . uOff - the offset into u[] and u_t[] for each field
1927 . uOff_x - the offset into u_x[] for each field
1928 . u - each field evaluated at the current point
1929 . u_t - the time derivative of each field evaluated at the current point
1930 . u_x - the gradient of each field evaluated at the current point
1931 . aOff - the offset into a[] and a_t[] for each auxiliary field
1932 . aOff_x - the offset into a_x[] for each auxiliary field
1933 . a - each auxiliary field evaluated at the current point
1934 . a_t - the time derivative of each auxiliary field evaluated at the current point
1935 . a_x - the gradient of auxiliary each field evaluated at the current point
1936 . t - current time
1937 . x - coordinates of the current point
1938 - uNew - new field values at the current point
1939
1940 Level: intermediate
1941
1942 .seealso: PetscDSGetResidual()
1943 @*/
PetscDSSetUpdate(PetscDS prob,PetscInt f,void (* update)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],PetscInt numConstants,const PetscScalar constants[],PetscScalar uNew[]))1944 PetscErrorCode PetscDSSetUpdate(PetscDS prob, PetscInt f,
1945 void (*update)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
1946 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
1947 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
1948 PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar uNew[]))
1949 {
1950 PetscErrorCode ierr;
1951
1952 PetscFunctionBegin;
1953 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1954 if (update) PetscValidFunction(update, 3);
1955 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1956 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
1957 prob->update[f] = update;
1958 PetscFunctionReturn(0);
1959 }
1960
PetscDSGetContext(PetscDS prob,PetscInt f,void ** ctx)1961 PetscErrorCode PetscDSGetContext(PetscDS prob, PetscInt f, void **ctx)
1962 {
1963 PetscFunctionBegin;
1964 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1965 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
1966 PetscValidPointer(ctx, 3);
1967 *ctx = prob->ctx[f];
1968 PetscFunctionReturn(0);
1969 }
1970
PetscDSSetContext(PetscDS prob,PetscInt f,void * ctx)1971 PetscErrorCode PetscDSSetContext(PetscDS prob, PetscInt f, void *ctx)
1972 {
1973 PetscErrorCode ierr;
1974
1975 PetscFunctionBegin;
1976 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
1977 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
1978 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
1979 prob->ctx[f] = ctx;
1980 PetscFunctionReturn(0);
1981 }
1982
1983 /*@C
1984 PetscDSGetBdResidual - Get the pointwise boundary residual function for a given test field
1985
1986 Not collective
1987
1988 Input Parameters:
1989 + prob - The PetscDS
1990 - f - The test field number
1991
1992 Output Parameters:
1993 + f0 - boundary integrand for the test function term
1994 - f1 - boundary integrand for the test function gradient term
1995
1996 Note: We are using a first order FEM model for the weak form:
1997
1998 \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
1999
2000 The calling sequence for the callbacks f0 and f1 is given by:
2001
2002 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2003 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2004 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2005 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2006
2007 + dim - the spatial dimension
2008 . Nf - the number of fields
2009 . uOff - the offset into u[] and u_t[] for each field
2010 . uOff_x - the offset into u_x[] for each field
2011 . u - each field evaluated at the current point
2012 . u_t - the time derivative of each field evaluated at the current point
2013 . u_x - the gradient of each field evaluated at the current point
2014 . aOff - the offset into a[] and a_t[] for each auxiliary field
2015 . aOff_x - the offset into a_x[] for each auxiliary field
2016 . a - each auxiliary field evaluated at the current point
2017 . a_t - the time derivative of each auxiliary field evaluated at the current point
2018 . a_x - the gradient of auxiliary each field evaluated at the current point
2019 . t - current time
2020 . x - coordinates of the current point
2021 . n - unit normal at the current point
2022 . numConstants - number of constant parameters
2023 . constants - constant parameters
2024 - f0 - output values at the current point
2025
2026 Level: intermediate
2027
2028 .seealso: PetscDSSetBdResidual()
2029 @*/
PetscDSGetBdResidual(PetscDS prob,PetscInt f,void (** f0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f0[]),void (** f1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f1[]))2030 PetscErrorCode PetscDSGetBdResidual(PetscDS prob, PetscInt f,
2031 void (**f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2032 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2033 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2034 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
2035 void (**f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2036 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2037 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2038 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2039 {
2040 PetscFunctionBegin;
2041 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2042 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2043 if (f0) {PetscValidPointer(f0, 3); *f0 = prob->fBd[f*2+0];}
2044 if (f1) {PetscValidPointer(f1, 4); *f1 = prob->fBd[f*2+1];}
2045 PetscFunctionReturn(0);
2046 }
2047
2048 /*@C
2049 PetscDSSetBdResidual - Get the pointwise boundary residual function for a given test field
2050
2051 Not collective
2052
2053 Input Parameters:
2054 + prob - The PetscDS
2055 . f - The test field number
2056 . f0 - boundary integrand for the test function term
2057 - f1 - boundary integrand for the test function gradient term
2058
2059 Note: We are using a first order FEM model for the weak form:
2060
2061 \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
2062
2063 The calling sequence for the callbacks f0 and f1 is given by:
2064
2065 $ f0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2066 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2067 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2068 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar f0[])
2069
2070 + dim - the spatial dimension
2071 . Nf - the number of fields
2072 . uOff - the offset into u[] and u_t[] for each field
2073 . uOff_x - the offset into u_x[] for each field
2074 . u - each field evaluated at the current point
2075 . u_t - the time derivative of each field evaluated at the current point
2076 . u_x - the gradient of each field evaluated at the current point
2077 . aOff - the offset into a[] and a_t[] for each auxiliary field
2078 . aOff_x - the offset into a_x[] for each auxiliary field
2079 . a - each auxiliary field evaluated at the current point
2080 . a_t - the time derivative of each auxiliary field evaluated at the current point
2081 . a_x - the gradient of auxiliary each field evaluated at the current point
2082 . t - current time
2083 . x - coordinates of the current point
2084 . n - unit normal at the current point
2085 . numConstants - number of constant parameters
2086 . constants - constant parameters
2087 - f0 - output values at the current point
2088
2089 Level: intermediate
2090
2091 .seealso: PetscDSGetBdResidual()
2092 @*/
PetscDSSetBdResidual(PetscDS prob,PetscInt f,void (* f0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f0[]),void (* f1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar f1[]))2093 PetscErrorCode PetscDSSetBdResidual(PetscDS prob, PetscInt f,
2094 void (*f0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2095 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2096 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2097 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]),
2098 void (*f1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2099 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2100 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2101 PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]))
2102 {
2103 PetscErrorCode ierr;
2104
2105 PetscFunctionBegin;
2106 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2107 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2108 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
2109 if (f0) {PetscValidFunction(f0, 3); prob->fBd[f*2+0] = f0;}
2110 if (f1) {PetscValidFunction(f1, 4); prob->fBd[f*2+1] = f1;}
2111 PetscFunctionReturn(0);
2112 }
2113
2114 /*@
2115 PetscDSHasBdJacobian - Signals that boundary Jacobian functions have been set
2116
2117 Not collective
2118
2119 Input Parameter:
2120 . prob - The PetscDS
2121
2122 Output Parameter:
2123 . hasBdJac - flag that pointwise function for the boundary Jacobian has been set
2124
2125 Level: intermediate
2126
2127 .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian()
2128 @*/
PetscDSHasBdJacobian(PetscDS prob,PetscBool * hasBdJac)2129 PetscErrorCode PetscDSHasBdJacobian(PetscDS prob, PetscBool *hasBdJac)
2130 {
2131 PetscInt f, g, h;
2132
2133 PetscFunctionBegin;
2134 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2135 *hasBdJac = PETSC_FALSE;
2136 for (f = 0; f < prob->Nf; ++f) {
2137 for (g = 0; g < prob->Nf; ++g) {
2138 for (h = 0; h < 4; ++h) {
2139 if (prob->gBd[(f*prob->Nf + g)*4+h]) *hasBdJac = PETSC_TRUE;
2140 }
2141 }
2142 }
2143 PetscFunctionReturn(0);
2144 }
2145
2146 /*@C
2147 PetscDSGetBdJacobian - Get the pointwise boundary Jacobian function for given test and basis field
2148
2149 Not collective
2150
2151 Input Parameters:
2152 + prob - The PetscDS
2153 . f - The test field number
2154 - g - The field number
2155
2156 Output Parameters:
2157 + g0 - integrand for the test and basis function term
2158 . g1 - integrand for the test function and basis function gradient term
2159 . g2 - integrand for the test function gradient and basis function term
2160 - g3 - integrand for the test function gradient and basis function gradient term
2161
2162 Note: We are using a first order FEM model for the weak form:
2163
2164 \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
2165
2166 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2167
2168 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2169 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2170 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2171 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2172
2173 + dim - the spatial dimension
2174 . Nf - the number of fields
2175 . uOff - the offset into u[] and u_t[] for each field
2176 . uOff_x - the offset into u_x[] for each field
2177 . u - each field evaluated at the current point
2178 . u_t - the time derivative of each field evaluated at the current point
2179 . u_x - the gradient of each field evaluated at the current point
2180 . aOff - the offset into a[] and a_t[] for each auxiliary field
2181 . aOff_x - the offset into a_x[] for each auxiliary field
2182 . a - each auxiliary field evaluated at the current point
2183 . a_t - the time derivative of each auxiliary field evaluated at the current point
2184 . a_x - the gradient of auxiliary each field evaluated at the current point
2185 . t - current time
2186 . u_tShift - the multiplier a for dF/dU_t
2187 . x - coordinates of the current point
2188 . n - normal at the current point
2189 . numConstants - number of constant parameters
2190 . constants - constant parameters
2191 - g0 - output values at the current point
2192
2193 Level: intermediate
2194
2195 .seealso: PetscDSSetBdJacobian()
2196 @*/
PetscDSGetBdJacobian(PetscDS prob,PetscInt f,PetscInt g,void (** g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (** g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (** g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (** g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))2197 PetscErrorCode PetscDSGetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
2198 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2199 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2200 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2201 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2202 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2203 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2204 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2205 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2206 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2207 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2208 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2209 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2210 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2211 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2212 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2213 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2214 {
2215 PetscFunctionBegin;
2216 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2217 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2218 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
2219 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gBd[(f*prob->Nf + g)*4+0];}
2220 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gBd[(f*prob->Nf + g)*4+1];}
2221 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gBd[(f*prob->Nf + g)*4+2];}
2222 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gBd[(f*prob->Nf + g)*4+3];}
2223 PetscFunctionReturn(0);
2224 }
2225
2226 /*@C
2227 PetscDSSetBdJacobian - Set the pointwise boundary Jacobian function for given test and basis field
2228
2229 Not collective
2230
2231 Input Parameters:
2232 + prob - The PetscDS
2233 . f - The test field number
2234 . g - The field number
2235 . g0 - integrand for the test and basis function term
2236 . g1 - integrand for the test function and basis function gradient term
2237 . g2 - integrand for the test function gradient and basis function term
2238 - g3 - integrand for the test function gradient and basis function gradient term
2239
2240 Note: We are using a first order FEM model for the weak form:
2241
2242 \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
2243
2244 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2245
2246 $ g0(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2247 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2248 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2249 $ PetscReal t, const PetscReal x[], const PetscReal n[], PetscScalar g0[])
2250
2251 + dim - the spatial dimension
2252 . Nf - the number of fields
2253 . uOff - the offset into u[] and u_t[] for each field
2254 . uOff_x - the offset into u_x[] for each field
2255 . u - each field evaluated at the current point
2256 . u_t - the time derivative of each field evaluated at the current point
2257 . u_x - the gradient of each field evaluated at the current point
2258 . aOff - the offset into a[] and a_t[] for each auxiliary field
2259 . aOff_x - the offset into a_x[] for each auxiliary field
2260 . a - each auxiliary field evaluated at the current point
2261 . a_t - the time derivative of each auxiliary field evaluated at the current point
2262 . a_x - the gradient of auxiliary each field evaluated at the current point
2263 . t - current time
2264 . u_tShift - the multiplier a for dF/dU_t
2265 . x - coordinates of the current point
2266 . n - normal at the current point
2267 . numConstants - number of constant parameters
2268 . constants - constant parameters
2269 - g0 - output values at the current point
2270
2271 Level: intermediate
2272
2273 .seealso: PetscDSGetBdJacobian()
2274 @*/
PetscDSSetBdJacobian(PetscDS prob,PetscInt f,PetscInt g,void (* g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (* g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (* g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (* g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))2275 PetscErrorCode PetscDSSetBdJacobian(PetscDS prob, PetscInt f, PetscInt g,
2276 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2277 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2278 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2279 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2280 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2281 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2282 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2283 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2284 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2285 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2286 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2287 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2288 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2289 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2290 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2291 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2292 {
2293 PetscErrorCode ierr;
2294
2295 PetscFunctionBegin;
2296 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2297 if (g0) PetscValidFunction(g0, 4);
2298 if (g1) PetscValidFunction(g1, 5);
2299 if (g2) PetscValidFunction(g2, 6);
2300 if (g3) PetscValidFunction(g3, 7);
2301 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2302 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
2303 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr);
2304 prob->gBd[(f*prob->Nf + g)*4+0] = g0;
2305 prob->gBd[(f*prob->Nf + g)*4+1] = g1;
2306 prob->gBd[(f*prob->Nf + g)*4+2] = g2;
2307 prob->gBd[(f*prob->Nf + g)*4+3] = g3;
2308 PetscFunctionReturn(0);
2309 }
2310
2311 /*@
2312 PetscDSHasBdJacobianPreconditioner - Signals that boundary Jacobian preconditioner functions have been set
2313
2314 Not collective
2315
2316 Input Parameter:
2317 . prob - The PetscDS
2318
2319 Output Parameter:
2320 . hasBdJac - flag that pointwise function for the boundary Jacobian preconditioner has been set
2321
2322 Level: intermediate
2323
2324 .seealso: PetscDSHasJacobian(), PetscDSSetBdJacobian(), PetscDSGetBdJacobian()
2325 @*/
PetscDSHasBdJacobianPreconditioner(PetscDS prob,PetscBool * hasBdJacPre)2326 PetscErrorCode PetscDSHasBdJacobianPreconditioner(PetscDS prob, PetscBool *hasBdJacPre)
2327 {
2328 PetscInt f, g, h;
2329
2330 PetscFunctionBegin;
2331 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2332 *hasBdJacPre = PETSC_FALSE;
2333 for (f = 0; f < prob->Nf; ++f) {
2334 for (g = 0; g < prob->Nf; ++g) {
2335 for (h = 0; h < 4; ++h) {
2336 if (prob->gpBd[(f*prob->Nf + g)*4+h]) *hasBdJacPre = PETSC_TRUE;
2337 }
2338 }
2339 }
2340 PetscFunctionReturn(0);
2341 }
2342
2343 /*@C
2344 PetscDSGetBdJacobianPreconditioner - Get the pointwise boundary Jacobian preconditioner function for given test and basis field
2345
2346 Not collective
2347
2348 Input Parameters:
2349 + prob - The PetscDS
2350 . f - The test field number
2351 - g - The field number
2352
2353 Output Parameters:
2354 + g0 - integrand for the test and basis function term
2355 . g1 - integrand for the test function and basis function gradient term
2356 . g2 - integrand for the test function gradient and basis function term
2357 - g3 - integrand for the test function gradient and basis function gradient term
2358
2359 Note: We are using a first order FEM model for the weak form:
2360
2361 \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
2362
2363 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2364
2365 $ g0(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, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2369
2370 + dim - the spatial dimension
2371 . Nf - the number of fields
2372 . NfAux - the number of auxiliary fields
2373 . uOff - the offset into u[] and u_t[] for each field
2374 . uOff_x - the offset into u_x[] for each field
2375 . u - each field evaluated at the current point
2376 . u_t - the time derivative of each field evaluated at the current point
2377 . u_x - the gradient of each field evaluated at the current point
2378 . aOff - the offset into a[] and a_t[] for each auxiliary field
2379 . aOff_x - the offset into a_x[] for each auxiliary field
2380 . a - each auxiliary field evaluated at the current point
2381 . a_t - the time derivative of each auxiliary field evaluated at the current point
2382 . a_x - the gradient of auxiliary each field evaluated at the current point
2383 . t - current time
2384 . u_tShift - the multiplier a for dF/dU_t
2385 . x - coordinates of the current point
2386 . n - normal at the current point
2387 . numConstants - number of constant parameters
2388 . constants - constant parameters
2389 - g0 - output values at the current point
2390
2391 This is not yet available in Fortran.
2392
2393 Level: intermediate
2394
2395 .seealso: PetscDSSetBdJacobianPreconditioner()
2396 @*/
PetscDSGetBdJacobianPreconditioner(PetscDS prob,PetscInt f,PetscInt g,void (** g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (** g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (** g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (** g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))2397 PetscErrorCode PetscDSGetBdJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g,
2398 void (**g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2399 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2400 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2401 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2402 void (**g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2403 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2404 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2405 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2406 void (**g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2407 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2408 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2409 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2410 void (**g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2411 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2412 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2413 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2414 {
2415 PetscFunctionBegin;
2416 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2417 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2418 if ((g < 0) || (g >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", g, prob->Nf);
2419 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->gpBd[(f*prob->Nf + g)*4+0];}
2420 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->gpBd[(f*prob->Nf + g)*4+1];}
2421 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->gpBd[(f*prob->Nf + g)*4+2];}
2422 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->gpBd[(f*prob->Nf + g)*4+3];}
2423 PetscFunctionReturn(0);
2424 }
2425
2426 /*@C
2427 PetscDSSetBdJacobianPreconditioner - Set the pointwise boundary Jacobian preconditioner function for given test and basis field
2428
2429 Not collective
2430
2431 Input Parameters:
2432 + prob - The PetscDS
2433 . f - The test field number
2434 . g - The field number
2435 . g0 - integrand for the test and basis function term
2436 . g1 - integrand for the test function and basis function gradient term
2437 . g2 - integrand for the test function gradient and basis function term
2438 - g3 - integrand for the test function gradient and basis function gradient term
2439
2440 Note: We are using a first order FEM model for the weak form:
2441
2442 \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
2443
2444 The calling sequence for the callbacks g0, g1, g2 and g3 is given by:
2445
2446 $ g0(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, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[])
2450
2451 + dim - the spatial dimension
2452 . Nf - the number of fields
2453 . NfAux - the number of auxiliary fields
2454 . uOff - the offset into u[] and u_t[] for each field
2455 . uOff_x - the offset into u_x[] for each field
2456 . u - each field evaluated at the current point
2457 . u_t - the time derivative of each field evaluated at the current point
2458 . u_x - the gradient of each field evaluated at the current point
2459 . aOff - the offset into a[] and a_t[] for each auxiliary field
2460 . aOff_x - the offset into a_x[] for each auxiliary field
2461 . a - each auxiliary field evaluated at the current point
2462 . a_t - the time derivative of each auxiliary field evaluated at the current point
2463 . a_x - the gradient of auxiliary each field evaluated at the current point
2464 . t - current time
2465 . u_tShift - the multiplier a for dF/dU_t
2466 . x - coordinates of the current point
2467 . n - normal at the current point
2468 . numConstants - number of constant parameters
2469 . constants - constant parameters
2470 - g0 - output values at the current point
2471
2472 This is not yet available in Fortran.
2473
2474 Level: intermediate
2475
2476 .seealso: PetscDSGetBdJacobianPreconditioner()
2477 @*/
PetscDSSetBdJacobianPreconditioner(PetscDS prob,PetscInt f,PetscInt g,void (* g0)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g0[]),void (* g1)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g1[]),void (* g2)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g2[]),void (* g3)(PetscInt dim,PetscInt Nf,PetscInt NfAux,const PetscInt uOff[],const PetscInt uOff_x[],const PetscScalar u[],const PetscScalar u_t[],const PetscScalar u_x[],const PetscInt aOff[],const PetscInt aOff_x[],const PetscScalar a[],const PetscScalar a_t[],const PetscScalar a_x[],PetscReal t,PetscReal u_tShift,const PetscReal x[],const PetscReal n[],PetscInt numConstants,const PetscScalar constants[],PetscScalar g3[]))2478 PetscErrorCode PetscDSSetBdJacobianPreconditioner(PetscDS prob, PetscInt f, PetscInt g,
2479 void (*g0)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2480 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2481 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2482 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]),
2483 void (*g1)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2484 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2485 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2486 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]),
2487 void (*g2)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2488 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2489 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2490 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]),
2491 void (*g3)(PetscInt dim, PetscInt Nf, PetscInt NfAux,
2492 const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
2493 const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
2494 PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]))
2495 {
2496 PetscErrorCode ierr;
2497
2498 PetscFunctionBegin;
2499 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2500 if (g0) PetscValidFunction(g0, 4);
2501 if (g1) PetscValidFunction(g1, 5);
2502 if (g2) PetscValidFunction(g2, 6);
2503 if (g3) PetscValidFunction(g3, 7);
2504 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2505 if (g < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", g);
2506 ierr = PetscDSEnlarge_Static(prob, PetscMax(f, g)+1);CHKERRQ(ierr);
2507 prob->gpBd[(f*prob->Nf + g)*4+0] = g0;
2508 prob->gpBd[(f*prob->Nf + g)*4+1] = g1;
2509 prob->gpBd[(f*prob->Nf + g)*4+2] = g2;
2510 prob->gpBd[(f*prob->Nf + g)*4+3] = g3;
2511 PetscFunctionReturn(0);
2512 }
2513
2514 /*@C
2515 PetscDSGetExactSolution - Get the pointwise exact solution function for a given test field
2516
2517 Not collective
2518
2519 Input Parameters:
2520 + prob - The PetscDS
2521 - f - The test field number
2522
2523 Output Parameter:
2524 + exactSol - exact solution for the test field
2525 - exactCtx - exact solution context
2526
2527 Note: The calling sequence for the solution functions is given by:
2528
2529 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2530
2531 + dim - the spatial dimension
2532 . t - current time
2533 . x - coordinates of the current point
2534 . Nc - the number of field components
2535 . u - the solution field evaluated at the current point
2536 - ctx - a user context
2537
2538 Level: intermediate
2539
2540 .seealso: PetscDSSetExactSolution(), PetscDSGetExactSolutionTimeDerivative()
2541 @*/
PetscDSGetExactSolution(PetscDS prob,PetscInt f,PetscErrorCode (** sol)(PetscInt dim,PetscReal t,const PetscReal x[],PetscInt Nc,PetscScalar u[],void * ctx),void ** ctx)2542 PetscErrorCode PetscDSGetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2543 {
2544 PetscFunctionBegin;
2545 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2546 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2547 if (sol) {PetscValidPointer(sol, 3); *sol = prob->exactSol[f];}
2548 if (ctx) {PetscValidPointer(ctx, 4); *ctx = prob->exactCtx[f];}
2549 PetscFunctionReturn(0);
2550 }
2551
2552 /*@C
2553 PetscDSSetExactSolution - Set the pointwise exact solution function for a given test field
2554
2555 Not collective
2556
2557 Input Parameters:
2558 + prob - The PetscDS
2559 . f - The test field number
2560 . sol - solution function for the test fields
2561 - ctx - solution context or NULL
2562
2563 Note: The calling sequence for solution functions is given by:
2564
2565 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2566
2567 + dim - the spatial dimension
2568 . t - current time
2569 . x - coordinates of the current point
2570 . Nc - the number of field components
2571 . u - the solution field evaluated at the current point
2572 - ctx - a user context
2573
2574 Level: intermediate
2575
2576 .seealso: PetscDSGetExactSolution()
2577 @*/
PetscDSSetExactSolution(PetscDS prob,PetscInt f,PetscErrorCode (* sol)(PetscInt dim,PetscReal t,const PetscReal x[],PetscInt Nc,PetscScalar u[],void * ctx),void * ctx)2578 PetscErrorCode PetscDSSetExactSolution(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2579 {
2580 PetscErrorCode ierr;
2581
2582 PetscFunctionBegin;
2583 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2584 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2585 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
2586 if (sol) {PetscValidFunction(sol, 3); prob->exactSol[f] = sol;}
2587 if (ctx) {PetscValidFunction(ctx, 4); prob->exactCtx[f] = ctx;}
2588 PetscFunctionReturn(0);
2589 }
2590
2591 /*@C
2592 PetscDSGetExactSolutionTimeDerivative - Get the pointwise time derivative of the exact solution function for a given test field
2593
2594 Not collective
2595
2596 Input Parameters:
2597 + prob - The PetscDS
2598 - f - The test field number
2599
2600 Output Parameter:
2601 + exactSol - time derivative of the exact solution for the test field
2602 - exactCtx - time derivative of the exact solution context
2603
2604 Note: The calling sequence for the solution functions is given by:
2605
2606 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2607
2608 + dim - the spatial dimension
2609 . t - current time
2610 . x - coordinates of the current point
2611 . Nc - the number of field components
2612 . u - the solution field evaluated at the current point
2613 - ctx - a user context
2614
2615 Level: intermediate
2616
2617 .seealso: PetscDSSetExactSolutionTimeDerivative(), PetscDSGetExactSolution()
2618 @*/
PetscDSGetExactSolutionTimeDerivative(PetscDS prob,PetscInt f,PetscErrorCode (** sol)(PetscInt dim,PetscReal t,const PetscReal x[],PetscInt Nc,PetscScalar u[],void * ctx),void ** ctx)2619 PetscErrorCode PetscDSGetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (**sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void **ctx)
2620 {
2621 PetscFunctionBegin;
2622 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2623 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2624 if (sol) {PetscValidPointer(sol, 3); *sol = prob->exactSol_t[f];}
2625 if (ctx) {PetscValidPointer(ctx, 4); *ctx = prob->exactCtx_t[f];}
2626 PetscFunctionReturn(0);
2627 }
2628
2629 /*@C
2630 PetscDSSetExactSolutionTimeDerivative - Set the pointwise time derivative of the exact solution function for a given test field
2631
2632 Not collective
2633
2634 Input Parameters:
2635 + prob - The PetscDS
2636 . f - The test field number
2637 . sol - time derivative of the solution function for the test fields
2638 - ctx - time derivative of the solution context or NULL
2639
2640 Note: The calling sequence for solution functions is given by:
2641
2642 $ sol(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx)
2643
2644 + dim - the spatial dimension
2645 . t - current time
2646 . x - coordinates of the current point
2647 . Nc - the number of field components
2648 . u - the solution field evaluated at the current point
2649 - ctx - a user context
2650
2651 Level: intermediate
2652
2653 .seealso: PetscDSGetExactSolutionTimeDerivative(), PetscDSSetExactSolution()
2654 @*/
PetscDSSetExactSolutionTimeDerivative(PetscDS prob,PetscInt f,PetscErrorCode (* sol)(PetscInt dim,PetscReal t,const PetscReal x[],PetscInt Nc,PetscScalar u[],void * ctx),void * ctx)2655 PetscErrorCode PetscDSSetExactSolutionTimeDerivative(PetscDS prob, PetscInt f, PetscErrorCode (*sol)(PetscInt dim, PetscReal t, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx), void *ctx)
2656 {
2657 PetscErrorCode ierr;
2658
2659 PetscFunctionBegin;
2660 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2661 if (f < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be non-negative", f);
2662 ierr = PetscDSEnlarge_Static(prob, f+1);CHKERRQ(ierr);
2663 if (sol) {PetscValidFunction(sol, 3); prob->exactSol_t[f] = sol;}
2664 if (ctx) {PetscValidFunction(ctx, 4); prob->exactCtx_t[f] = ctx;}
2665 PetscFunctionReturn(0);
2666 }
2667
2668 /*@C
2669 PetscDSGetConstants - Returns the array of constants passed to point functions
2670
2671 Not collective
2672
2673 Input Parameter:
2674 . prob - The PetscDS object
2675
2676 Output Parameters:
2677 + numConstants - The number of constants
2678 - constants - The array of constants, NULL if there are none
2679
2680 Level: intermediate
2681
2682 .seealso: PetscDSSetConstants(), PetscDSCreate()
2683 @*/
PetscDSGetConstants(PetscDS prob,PetscInt * numConstants,const PetscScalar * constants[])2684 PetscErrorCode PetscDSGetConstants(PetscDS prob, PetscInt *numConstants, const PetscScalar *constants[])
2685 {
2686 PetscFunctionBegin;
2687 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2688 if (numConstants) {PetscValidPointer(numConstants, 2); *numConstants = prob->numConstants;}
2689 if (constants) {PetscValidPointer(constants, 3); *constants = prob->constants;}
2690 PetscFunctionReturn(0);
2691 }
2692
2693 /*@C
2694 PetscDSSetConstants - Set the array of constants passed to point functions
2695
2696 Not collective
2697
2698 Input Parameters:
2699 + prob - The PetscDS object
2700 . numConstants - The number of constants
2701 - constants - The array of constants, NULL if there are none
2702
2703 Level: intermediate
2704
2705 .seealso: PetscDSGetConstants(), PetscDSCreate()
2706 @*/
PetscDSSetConstants(PetscDS prob,PetscInt numConstants,PetscScalar constants[])2707 PetscErrorCode PetscDSSetConstants(PetscDS prob, PetscInt numConstants, PetscScalar constants[])
2708 {
2709 PetscErrorCode ierr;
2710
2711 PetscFunctionBegin;
2712 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2713 if (numConstants != prob->numConstants) {
2714 ierr = PetscFree(prob->constants);CHKERRQ(ierr);
2715 prob->numConstants = numConstants;
2716 if (prob->numConstants) {
2717 ierr = PetscMalloc1(prob->numConstants, &prob->constants);CHKERRQ(ierr);
2718 } else {
2719 prob->constants = NULL;
2720 }
2721 }
2722 if (prob->numConstants) {
2723 PetscValidPointer(constants, 3);
2724 ierr = PetscArraycpy(prob->constants, constants, prob->numConstants);CHKERRQ(ierr);
2725 }
2726 PetscFunctionReturn(0);
2727 }
2728
2729 /*@
2730 PetscDSGetFieldIndex - Returns the index of the given field
2731
2732 Not collective
2733
2734 Input Parameters:
2735 + prob - The PetscDS object
2736 - disc - The discretization object
2737
2738 Output Parameter:
2739 . f - The field number
2740
2741 Level: beginner
2742
2743 .seealso: PetscGetDiscretization(), PetscDSGetNumFields(), PetscDSCreate()
2744 @*/
PetscDSGetFieldIndex(PetscDS prob,PetscObject disc,PetscInt * f)2745 PetscErrorCode PetscDSGetFieldIndex(PetscDS prob, PetscObject disc, PetscInt *f)
2746 {
2747 PetscInt g;
2748
2749 PetscFunctionBegin;
2750 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2751 PetscValidPointer(f, 3);
2752 *f = -1;
2753 for (g = 0; g < prob->Nf; ++g) {if (disc == prob->disc[g]) break;}
2754 if (g == prob->Nf) SETERRQ(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Field not found in PetscDS.");
2755 *f = g;
2756 PetscFunctionReturn(0);
2757 }
2758
2759 /*@
2760 PetscDSGetFieldSize - Returns the size of the given field in the full space basis
2761
2762 Not collective
2763
2764 Input Parameters:
2765 + prob - The PetscDS object
2766 - f - The field number
2767
2768 Output Parameter:
2769 . size - The size
2770
2771 Level: beginner
2772
2773 .seealso: PetscDSGetFieldOffset(), PetscDSGetNumFields(), PetscDSCreate()
2774 @*/
PetscDSGetFieldSize(PetscDS prob,PetscInt f,PetscInt * size)2775 PetscErrorCode PetscDSGetFieldSize(PetscDS prob, PetscInt f, PetscInt *size)
2776 {
2777 PetscErrorCode ierr;
2778
2779 PetscFunctionBegin;
2780 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2781 PetscValidPointer(size, 3);
2782 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2783 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
2784 *size = prob->Nb[f];
2785 PetscFunctionReturn(0);
2786 }
2787
2788 /*@
2789 PetscDSGetFieldOffset - Returns the offset of the given field in the full space basis
2790
2791 Not collective
2792
2793 Input Parameters:
2794 + prob - The PetscDS object
2795 - f - The field number
2796
2797 Output Parameter:
2798 . off - The offset
2799
2800 Level: beginner
2801
2802 .seealso: PetscDSGetFieldSize(), PetscDSGetNumFields(), PetscDSCreate()
2803 @*/
PetscDSGetFieldOffset(PetscDS prob,PetscInt f,PetscInt * off)2804 PetscErrorCode PetscDSGetFieldOffset(PetscDS prob, PetscInt f, PetscInt *off)
2805 {
2806 PetscInt size, g;
2807 PetscErrorCode ierr;
2808
2809 PetscFunctionBegin;
2810 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2811 PetscValidPointer(off, 3);
2812 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2813 *off = 0;
2814 for (g = 0; g < f; ++g) {
2815 ierr = PetscDSGetFieldSize(prob, g, &size);CHKERRQ(ierr);
2816 *off += size;
2817 }
2818 PetscFunctionReturn(0);
2819 }
2820
2821 /*@
2822 PetscDSGetDimensions - Returns the size of the approximation space for each field on an evaluation point
2823
2824 Not collective
2825
2826 Input Parameter:
2827 . prob - The PetscDS object
2828
2829 Output Parameter:
2830 . dimensions - The number of dimensions
2831
2832 Level: beginner
2833
2834 .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
2835 @*/
PetscDSGetDimensions(PetscDS prob,PetscInt * dimensions[])2836 PetscErrorCode PetscDSGetDimensions(PetscDS prob, PetscInt *dimensions[])
2837 {
2838 PetscErrorCode ierr;
2839
2840 PetscFunctionBegin;
2841 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2842 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
2843 PetscValidPointer(dimensions, 2);
2844 *dimensions = prob->Nb;
2845 PetscFunctionReturn(0);
2846 }
2847
2848 /*@
2849 PetscDSGetComponents - Returns the number of components for each field on an evaluation point
2850
2851 Not collective
2852
2853 Input Parameter:
2854 . prob - The PetscDS object
2855
2856 Output Parameter:
2857 . components - The number of components
2858
2859 Level: beginner
2860
2861 .seealso: PetscDSGetComponentOffsets(), PetscDSGetNumFields(), PetscDSCreate()
2862 @*/
PetscDSGetComponents(PetscDS prob,PetscInt * components[])2863 PetscErrorCode PetscDSGetComponents(PetscDS prob, PetscInt *components[])
2864 {
2865 PetscErrorCode ierr;
2866
2867 PetscFunctionBegin;
2868 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2869 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
2870 PetscValidPointer(components, 2);
2871 *components = prob->Nc;
2872 PetscFunctionReturn(0);
2873 }
2874
2875 /*@
2876 PetscDSGetComponentOffset - Returns the offset of the given field on an evaluation point
2877
2878 Not collective
2879
2880 Input Parameters:
2881 + prob - The PetscDS object
2882 - f - The field number
2883
2884 Output Parameter:
2885 . off - The offset
2886
2887 Level: beginner
2888
2889 .seealso: PetscDSGetNumFields(), PetscDSCreate()
2890 @*/
PetscDSGetComponentOffset(PetscDS prob,PetscInt f,PetscInt * off)2891 PetscErrorCode PetscDSGetComponentOffset(PetscDS prob, PetscInt f, PetscInt *off)
2892 {
2893 PetscFunctionBegin;
2894 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2895 PetscValidPointer(off, 3);
2896 if ((f < 0) || (f >= prob->Nf)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Field number %d must be in [0, %d)", f, prob->Nf);
2897 *off = prob->off[f];
2898 PetscFunctionReturn(0);
2899 }
2900
2901 /*@
2902 PetscDSGetComponentOffsets - Returns the offset of each field on an evaluation point
2903
2904 Not collective
2905
2906 Input Parameter:
2907 . prob - The PetscDS object
2908
2909 Output Parameter:
2910 . offsets - The offsets
2911
2912 Level: beginner
2913
2914 .seealso: PetscDSGetNumFields(), PetscDSCreate()
2915 @*/
PetscDSGetComponentOffsets(PetscDS prob,PetscInt * offsets[])2916 PetscErrorCode PetscDSGetComponentOffsets(PetscDS prob, PetscInt *offsets[])
2917 {
2918 PetscFunctionBegin;
2919 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2920 PetscValidPointer(offsets, 2);
2921 *offsets = prob->off;
2922 PetscFunctionReturn(0);
2923 }
2924
2925 /*@
2926 PetscDSGetComponentDerivativeOffsets - Returns the offset of each field derivative on an evaluation point
2927
2928 Not collective
2929
2930 Input Parameter:
2931 . prob - The PetscDS object
2932
2933 Output Parameter:
2934 . offsets - The offsets
2935
2936 Level: beginner
2937
2938 .seealso: PetscDSGetNumFields(), PetscDSCreate()
2939 @*/
PetscDSGetComponentDerivativeOffsets(PetscDS prob,PetscInt * offsets[])2940 PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS prob, PetscInt *offsets[])
2941 {
2942 PetscFunctionBegin;
2943 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2944 PetscValidPointer(offsets, 2);
2945 *offsets = prob->offDer;
2946 PetscFunctionReturn(0);
2947 }
2948
2949 /*@C
2950 PetscDSGetTabulation - Return the basis tabulation at quadrature points for the volume discretization
2951
2952 Not collective
2953
2954 Input Parameter:
2955 . prob - The PetscDS object
2956
2957 Output Parameter:
2958 . T - The basis function and derivatives tabulation at quadrature points for each field
2959
2960 Level: intermediate
2961
2962 .seealso: PetscDSCreate()
2963 @*/
PetscDSGetTabulation(PetscDS prob,PetscTabulation * T[])2964 PetscErrorCode PetscDSGetTabulation(PetscDS prob, PetscTabulation *T[])
2965 {
2966 PetscErrorCode ierr;
2967
2968 PetscFunctionBegin;
2969 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2970 PetscValidPointer(T, 2);
2971 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
2972 *T = prob->T;
2973 PetscFunctionReturn(0);
2974 }
2975
2976 /*@C
2977 PetscDSGetFaceTabulation - Return the basis tabulation at quadrature points on the faces
2978
2979 Not collective
2980
2981 Input Parameter:
2982 . prob - The PetscDS object
2983
2984 Output Parameter:
2985 . Tf - The basis function and derviative tabulation on each local face at quadrature points for each and field
2986
2987 Level: intermediate
2988
2989 .seealso: PetscDSGetTabulation(), PetscDSCreate()
2990 @*/
PetscDSGetFaceTabulation(PetscDS prob,PetscTabulation * Tf[])2991 PetscErrorCode PetscDSGetFaceTabulation(PetscDS prob, PetscTabulation *Tf[])
2992 {
2993 PetscErrorCode ierr;
2994
2995 PetscFunctionBegin;
2996 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
2997 PetscValidPointer(Tf, 2);
2998 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
2999 *Tf = prob->Tf;
3000 PetscFunctionReturn(0);
3001 }
3002
PetscDSGetEvaluationArrays(PetscDS prob,PetscScalar ** u,PetscScalar ** u_t,PetscScalar ** u_x)3003 PetscErrorCode PetscDSGetEvaluationArrays(PetscDS prob, PetscScalar **u, PetscScalar **u_t, PetscScalar **u_x)
3004 {
3005 PetscErrorCode ierr;
3006
3007 PetscFunctionBegin;
3008 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3009 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
3010 if (u) {PetscValidPointer(u, 2); *u = prob->u;}
3011 if (u_t) {PetscValidPointer(u_t, 3); *u_t = prob->u_t;}
3012 if (u_x) {PetscValidPointer(u_x, 4); *u_x = prob->u_x;}
3013 PetscFunctionReturn(0);
3014 }
3015
PetscDSGetWeakFormArrays(PetscDS prob,PetscScalar ** f0,PetscScalar ** f1,PetscScalar ** g0,PetscScalar ** g1,PetscScalar ** g2,PetscScalar ** g3)3016 PetscErrorCode PetscDSGetWeakFormArrays(PetscDS prob, PetscScalar **f0, PetscScalar **f1, PetscScalar **g0, PetscScalar **g1, PetscScalar **g2, PetscScalar **g3)
3017 {
3018 PetscErrorCode ierr;
3019
3020 PetscFunctionBegin;
3021 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3022 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
3023 if (f0) {PetscValidPointer(f0, 2); *f0 = prob->f0;}
3024 if (f1) {PetscValidPointer(f1, 3); *f1 = prob->f1;}
3025 if (g0) {PetscValidPointer(g0, 4); *g0 = prob->g0;}
3026 if (g1) {PetscValidPointer(g1, 5); *g1 = prob->g1;}
3027 if (g2) {PetscValidPointer(g2, 6); *g2 = prob->g2;}
3028 if (g3) {PetscValidPointer(g3, 7); *g3 = prob->g3;}
3029 PetscFunctionReturn(0);
3030 }
3031
PetscDSGetWorkspace(PetscDS prob,PetscReal ** x,PetscScalar ** basisReal,PetscScalar ** basisDerReal,PetscScalar ** testReal,PetscScalar ** testDerReal)3032 PetscErrorCode PetscDSGetWorkspace(PetscDS prob, PetscReal **x, PetscScalar **basisReal, PetscScalar **basisDerReal, PetscScalar **testReal, PetscScalar **testDerReal)
3033 {
3034 PetscErrorCode ierr;
3035
3036 PetscFunctionBegin;
3037 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3038 ierr = PetscDSSetUp(prob);CHKERRQ(ierr);
3039 if (x) {PetscValidPointer(x, 2); *x = prob->x;}
3040 if (basisReal) {PetscValidPointer(basisReal, 3); *basisReal = prob->basisReal;}
3041 if (basisDerReal) {PetscValidPointer(basisDerReal, 4); *basisDerReal = prob->basisDerReal;}
3042 if (testReal) {PetscValidPointer(testReal, 5); *testReal = prob->testReal;}
3043 if (testDerReal) {PetscValidPointer(testDerReal, 6); *testDerReal = prob->testDerReal;}
3044 PetscFunctionReturn(0);
3045 }
3046
3047 /*@C
3048 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 performaed, using the kernels from PetscDSSetBdResidual().
3049
3050 Collective on ds
3051
3052 Input Parameters:
3053 + ds - The PetscDS object
3054 . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3055 . name - The BC name
3056 . labelname - The label defining constrained points
3057 . field - The field to constrain
3058 . numcomps - The number of constrained field components (0 will constrain all fields)
3059 . comps - An array of constrained component numbers
3060 . bcFunc - A pointwise function giving boundary values
3061 . bcFunc_t - A pointwise function giving the time derviative of the boundary values, or NULL
3062 . numids - The number of DMLabel ids for constrained points
3063 . ids - An array of ids for constrained points
3064 - ctx - An optional user context for bcFunc
3065
3066 Options Database Keys:
3067 + -bc_<boundary name> <num> - Overrides the boundary ids
3068 - -bc_<boundary name>_comp <num> - Overrides the boundary components
3069
3070 Note:
3071 Both bcFunc abd bcFunc_t will depend on the boundary condition type. If the type if DM_BC_ESSENTIAL, Then the calling sequence is:
3072
3073 $ bcFunc(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar bcval[])
3074
3075 If the type is DM_BC_ESSENTIAL_FIELD or other _FIELD value, then the calling sequence is:
3076
3077 $ bcFunc(PetscInt dim, PetscInt Nf, PetscInt NfAux,
3078 $ const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[],
3079 $ const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[],
3080 $ PetscReal time, const PetscReal x[], PetscScalar bcval[])
3081
3082 + dim - the spatial dimension
3083 . Nf - the number of fields
3084 . uOff - the offset into u[] and u_t[] for each field
3085 . uOff_x - the offset into u_x[] for each field
3086 . u - each field evaluated at the current point
3087 . u_t - the time derivative of each field evaluated at the current point
3088 . u_x - the gradient of each field evaluated at the current point
3089 . aOff - the offset into a[] and a_t[] for each auxiliary field
3090 . aOff_x - the offset into a_x[] for each auxiliary field
3091 . a - each auxiliary field evaluated at the current point
3092 . a_t - the time derivative of each auxiliary field evaluated at the current point
3093 . a_x - the gradient of auxiliary each field evaluated at the current point
3094 . t - current time
3095 . x - coordinates of the current point
3096 . numConstants - number of constant parameters
3097 . constants - constant parameters
3098 - bcval - output values at the current point
3099
3100 Level: developer
3101
3102 .seealso: PetscDSGetBoundary(), PetscDSSetResidual(), PetscDSSetBdResidual()
3103 @*/
PetscDSAddBoundary(PetscDS ds,DMBoundaryConditionType type,const char name[],const char labelname[],PetscInt field,PetscInt numcomps,const PetscInt * comps,void (* bcFunc)(void),void (* bcFunc_t)(void),PetscInt numids,const PetscInt * ids,void * ctx)3104 PetscErrorCode PetscDSAddBoundary(PetscDS ds, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), void (*bcFunc_t)(void), PetscInt numids, const PetscInt *ids, void *ctx)
3105 {
3106 DSBoundary b;
3107 PetscErrorCode ierr;
3108
3109 PetscFunctionBegin;
3110 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3111 PetscValidLogicalCollectiveEnum(ds, type, 2);
3112 PetscValidLogicalCollectiveInt(ds, field, 5);
3113 PetscValidLogicalCollectiveInt(ds, numcomps, 6);
3114 PetscValidLogicalCollectiveInt(ds, numids, 9);
3115 ierr = PetscNew(&b);CHKERRQ(ierr);
3116 ierr = PetscStrallocpy(name, (char **) &b->name);CHKERRQ(ierr);
3117 ierr = PetscStrallocpy(labelname, (char **) &b->labelname);CHKERRQ(ierr);
3118 ierr = PetscMalloc1(numcomps, &b->comps);CHKERRQ(ierr);
3119 if (numcomps) {ierr = PetscArraycpy(b->comps, comps, numcomps);CHKERRQ(ierr);}
3120 ierr = PetscMalloc1(numids, &b->ids);CHKERRQ(ierr);
3121 if (numids) {ierr = PetscArraycpy(b->ids, ids, numids);CHKERRQ(ierr);}
3122 b->type = type;
3123 b->field = field;
3124 b->numcomps = numcomps;
3125 b->func = bcFunc;
3126 b->func_t = bcFunc_t;
3127 b->numids = numids;
3128 b->ctx = ctx;
3129 b->next = ds->boundary;
3130 ds->boundary = b;
3131 PetscFunctionReturn(0);
3132 }
3133
3134 /*@C
3135 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 performaed, using the kernels from PetscDSSetBdResidual().
3136
3137 Input Parameters:
3138 + ds - The PetscDS object
3139 . bd - The boundary condition number
3140 . type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3141 . name - The BC name
3142 . labelname - The label defining constrained points
3143 . field - The field to constrain
3144 . numcomps - The number of constrained field components
3145 . comps - An array of constrained component numbers
3146 . bcFunc - A pointwise function giving boundary values
3147 . bcFunc_t - A pointwise function giving the time derviative of the boundary values, or NULL
3148 . numids - The number of DMLabel ids for constrained points
3149 . ids - An array of ids for constrained points
3150 - ctx - An optional user context for bcFunc
3151
3152 Note:
3153 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.
3154
3155 Level: developer
3156
3157 .seealso: PetscDSAddBoundary(), PetscDSGetBoundary(), PetscDSGetNumBoundary()
3158 @*/
PetscDSUpdateBoundary(PetscDS ds,PetscInt bd,DMBoundaryConditionType type,const char name[],const char labelname[],PetscInt field,PetscInt numcomps,const PetscInt * comps,void (* bcFunc)(void),void (* bcFunc_t)(void),PetscInt numids,const PetscInt * ids,void * ctx)3159 PetscErrorCode PetscDSUpdateBoundary(PetscDS ds, PetscInt bd, DMBoundaryConditionType type, const char name[], const char labelname[], PetscInt field, PetscInt numcomps, const PetscInt *comps, void (*bcFunc)(void), void (*bcFunc_t)(void), PetscInt numids, const PetscInt *ids, void *ctx)
3160 {
3161 DSBoundary b = ds->boundary;
3162 PetscInt n = 0;
3163 PetscErrorCode ierr;
3164
3165 PetscFunctionBegin;
3166 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3167 while (b) {
3168 if (n == bd) break;
3169 b = b->next;
3170 ++n;
3171 }
3172 if (!b) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %d is not in [0, %d)", bd, n);
3173 if (name) {
3174 ierr = PetscFree(b->name);CHKERRQ(ierr);
3175 ierr = PetscStrallocpy(name, (char **) &b->name);CHKERRQ(ierr);
3176 }
3177 if (labelname) {
3178 ierr = PetscFree(b->labelname);CHKERRQ(ierr);
3179 ierr = PetscStrallocpy(labelname, (char **) &b->labelname);CHKERRQ(ierr);
3180 }
3181 if (numcomps >= 0 && numcomps != b->numcomps) {
3182 b->numcomps = numcomps;
3183 ierr = PetscFree(b->comps);CHKERRQ(ierr);
3184 ierr = PetscMalloc1(numcomps, &b->comps);CHKERRQ(ierr);
3185 if (numcomps) {ierr = PetscArraycpy(b->comps, comps, numcomps);CHKERRQ(ierr);}
3186 }
3187 if (numids >= 0 && numids != b->numids) {
3188 b->numids = numids;
3189 ierr = PetscFree(b->ids);CHKERRQ(ierr);
3190 ierr = PetscMalloc1(numids, &b->ids);CHKERRQ(ierr);
3191 if (numids) {ierr = PetscArraycpy(b->ids, ids, numids);CHKERRQ(ierr);}
3192 }
3193 b->type = type;
3194 if (field >= 0) {b->field = field;}
3195 if (bcFunc) {b->func = bcFunc;}
3196 if (bcFunc_t) {b->func_t = bcFunc_t;}
3197 if (ctx) {b->ctx = ctx;}
3198 PetscFunctionReturn(0);
3199 }
3200
3201 /*@
3202 PetscDSGetNumBoundary - Get the number of registered BC
3203
3204 Input Parameters:
3205 . ds - The PetscDS object
3206
3207 Output Parameters:
3208 . numBd - The number of BC
3209
3210 Level: intermediate
3211
3212 .seealso: PetscDSAddBoundary(), PetscDSGetBoundary()
3213 @*/
PetscDSGetNumBoundary(PetscDS ds,PetscInt * numBd)3214 PetscErrorCode PetscDSGetNumBoundary(PetscDS ds, PetscInt *numBd)
3215 {
3216 DSBoundary b = ds->boundary;
3217
3218 PetscFunctionBegin;
3219 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3220 PetscValidPointer(numBd, 2);
3221 *numBd = 0;
3222 while (b) {++(*numBd); b = b->next;}
3223 PetscFunctionReturn(0);
3224 }
3225
3226 /*@C
3227 PetscDSGetBoundary - Gets a boundary condition to the model
3228
3229 Input Parameters:
3230 + ds - The PetscDS object
3231 - bd - The BC number
3232
3233 Output Parameters:
3234 + type - The type of condition, e.g. DM_BC_ESSENTIAL/DM_BC_ESSENTIAL_FIELD (Dirichlet), or DM_BC_NATURAL (Neumann)
3235 . name - The BC name
3236 . labelname - The label defining constrained points
3237 . field - The field to constrain
3238 . numcomps - The number of constrained field components
3239 . comps - An array of constrained component numbers
3240 . bcFunc - A pointwise function giving boundary values
3241 . bcFunc_t - A pointwise function giving the time derviative of the boundary values
3242 . numids - The number of DMLabel ids for constrained points
3243 . ids - An array of ids for constrained points
3244 - ctx - An optional user context for bcFunc
3245
3246 Options Database Keys:
3247 + -bc_<boundary name> <num> - Overrides the boundary ids
3248 - -bc_<boundary name>_comp <num> - Overrides the boundary components
3249
3250 Level: developer
3251
3252 .seealso: PetscDSAddBoundary()
3253 @*/
PetscDSGetBoundary(PetscDS ds,PetscInt bd,DMBoundaryConditionType * type,const char ** name,const char ** labelname,PetscInt * field,PetscInt * numcomps,const PetscInt ** comps,void (** func)(void),void (** func_t)(void),PetscInt * numids,const PetscInt ** ids,void ** ctx)3254 PetscErrorCode PetscDSGetBoundary(PetscDS ds, PetscInt bd, DMBoundaryConditionType *type, const char **name, const char **labelname, PetscInt *field, PetscInt *numcomps, const PetscInt **comps, void (**func)(void), void (**func_t)(void), PetscInt *numids, const PetscInt **ids, void **ctx)
3255 {
3256 DSBoundary b = ds->boundary;
3257 PetscInt n = 0;
3258
3259 PetscFunctionBegin;
3260 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3261 while (b) {
3262 if (n == bd) break;
3263 b = b->next;
3264 ++n;
3265 }
3266 if (!b) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boundary %d is not in [0, %d)", bd, n);
3267 if (type) {
3268 PetscValidPointer(type, 3);
3269 *type = b->type;
3270 }
3271 if (name) {
3272 PetscValidPointer(name, 4);
3273 *name = b->name;
3274 }
3275 if (labelname) {
3276 PetscValidPointer(labelname, 5);
3277 *labelname = b->labelname;
3278 }
3279 if (field) {
3280 PetscValidPointer(field, 6);
3281 *field = b->field;
3282 }
3283 if (numcomps) {
3284 PetscValidPointer(numcomps, 7);
3285 *numcomps = b->numcomps;
3286 }
3287 if (comps) {
3288 PetscValidPointer(comps, 8);
3289 *comps = b->comps;
3290 }
3291 if (func) {
3292 PetscValidPointer(func, 9);
3293 *func = b->func;
3294 }
3295 if (func_t) {
3296 PetscValidPointer(func_t, 10);
3297 *func_t = b->func_t;
3298 }
3299 if (numids) {
3300 PetscValidPointer(numids, 11);
3301 *numids = b->numids;
3302 }
3303 if (ids) {
3304 PetscValidPointer(ids, 12);
3305 *ids = b->ids;
3306 }
3307 if (ctx) {
3308 PetscValidPointer(ctx, 13);
3309 *ctx = b->ctx;
3310 }
3311 PetscFunctionReturn(0);
3312 }
3313
3314 /*@
3315 PetscDSCopyBoundary - Copy all boundary condition objects to the new problem
3316
3317 Not collective
3318
3319 Input Parameter:
3320 . prob - The PetscDS object
3321
3322 Output Parameter:
3323 . newprob - The PetscDS copy
3324
3325 Level: intermediate
3326
3327 .seealso: PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3328 @*/
PetscDSCopyBoundary(PetscDS probA,PetscDS probB)3329 PetscErrorCode PetscDSCopyBoundary(PetscDS probA, PetscDS probB)
3330 {
3331 DSBoundary b, next, *lastnext;
3332 PetscErrorCode ierr;
3333
3334 PetscFunctionBegin;
3335 PetscValidHeaderSpecific(probA, PETSCDS_CLASSID, 1);
3336 PetscValidHeaderSpecific(probB, PETSCDS_CLASSID, 2);
3337 if (probA == probB) PetscFunctionReturn(0);
3338 next = probB->boundary;
3339 while (next) {
3340 DSBoundary b = next;
3341
3342 next = b->next;
3343 ierr = PetscFree(b->comps);CHKERRQ(ierr);
3344 ierr = PetscFree(b->ids);CHKERRQ(ierr);
3345 ierr = PetscFree(b->name);CHKERRQ(ierr);
3346 ierr = PetscFree(b->labelname);CHKERRQ(ierr);
3347 ierr = PetscFree(b);CHKERRQ(ierr);
3348 }
3349 lastnext = &(probB->boundary);
3350 for (b = probA->boundary; b; b = b->next) {
3351 DSBoundary bNew;
3352
3353 ierr = PetscNew(&bNew);CHKERRQ(ierr);
3354 bNew->numcomps = b->numcomps;
3355 ierr = PetscMalloc1(bNew->numcomps, &bNew->comps);CHKERRQ(ierr);
3356 ierr = PetscArraycpy(bNew->comps, b->comps, bNew->numcomps);CHKERRQ(ierr);
3357 bNew->numids = b->numids;
3358 ierr = PetscMalloc1(bNew->numids, &bNew->ids);CHKERRQ(ierr);
3359 ierr = PetscArraycpy(bNew->ids, b->ids, bNew->numids);CHKERRQ(ierr);
3360 ierr = PetscStrallocpy(b->labelname,(char **) &(bNew->labelname));CHKERRQ(ierr);
3361 ierr = PetscStrallocpy(b->name,(char **) &(bNew->name));CHKERRQ(ierr);
3362 bNew->ctx = b->ctx;
3363 bNew->type = b->type;
3364 bNew->field = b->field;
3365 bNew->func = b->func;
3366
3367 *lastnext = bNew;
3368 lastnext = &(bNew->next);
3369 }
3370 PetscFunctionReturn(0);
3371 }
3372
3373 /*@
3374 PetscDSSelectDiscretizations - Copy discretizations to the new problem with different field layout
3375
3376 Not collective
3377
3378 Input Parameter:
3379 + prob - The PetscDS object
3380 . numFields - Number of new fields
3381 - fields - Old field number for each new field
3382
3383 Output Parameter:
3384 . newprob - The PetscDS copy
3385
3386 Level: intermediate
3387
3388 .seealso: PetscDSSelectEquations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3389 @*/
PetscDSSelectDiscretizations(PetscDS prob,PetscInt numFields,const PetscInt fields[],PetscDS newprob)3390 PetscErrorCode PetscDSSelectDiscretizations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3391 {
3392 PetscInt Nf, Nfn, fn;
3393 PetscErrorCode ierr;
3394
3395 PetscFunctionBegin;
3396 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3397 if (fields) PetscValidPointer(fields, 3);
3398 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
3399 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
3400 ierr = PetscDSGetNumFields(newprob, &Nfn);CHKERRQ(ierr);
3401 if (numFields > Nfn) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields %D to transfer must not be greater then the total number of fields %D", numFields, Nfn);
3402 for (fn = 0; fn < numFields; ++fn) {
3403 const PetscInt f = fields ? fields[fn] : fn;
3404 PetscObject disc;
3405
3406 if (f >= Nf) continue;
3407 ierr = PetscDSGetDiscretization(prob, f, &disc);CHKERRQ(ierr);
3408 ierr = PetscDSSetDiscretization(newprob, fn, disc);CHKERRQ(ierr);
3409 }
3410 PetscFunctionReturn(0);
3411 }
3412
3413 /*@
3414 PetscDSSelectEquations - Copy pointwise function pointers to the new problem with different field layout
3415
3416 Not collective
3417
3418 Input Parameter:
3419 + prob - The PetscDS object
3420 . numFields - Number of new fields
3421 - fields - Old field number for each new field
3422
3423 Output Parameter:
3424 . newprob - The PetscDS copy
3425
3426 Level: intermediate
3427
3428 .seealso: PetscDSSelectDiscretizations(), PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3429 @*/
PetscDSSelectEquations(PetscDS prob,PetscInt numFields,const PetscInt fields[],PetscDS newprob)3430 PetscErrorCode PetscDSSelectEquations(PetscDS prob, PetscInt numFields, const PetscInt fields[], PetscDS newprob)
3431 {
3432 PetscInt Nf, Nfn, fn, gn;
3433 PetscErrorCode ierr;
3434
3435 PetscFunctionBegin;
3436 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3437 if (fields) PetscValidPointer(fields, 3);
3438 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 4);
3439 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
3440 ierr = PetscDSGetNumFields(newprob, &Nfn);CHKERRQ(ierr);
3441 if (numFields > Nfn) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields %D to transfer must not be greater then the total number of fields %D", numFields, Nfn);
3442 for (fn = 0; fn < numFields; ++fn) {
3443 const PetscInt f = fields ? fields[fn] : fn;
3444 PetscPointFunc obj;
3445 PetscPointFunc f0, f1;
3446 PetscBdPointFunc f0Bd, f1Bd;
3447 PetscRiemannFunc r;
3448
3449 if (f >= Nf) continue;
3450 ierr = PetscDSGetObjective(prob, f, &obj);CHKERRQ(ierr);
3451 ierr = PetscDSGetResidual(prob, f, &f0, &f1);CHKERRQ(ierr);
3452 ierr = PetscDSGetBdResidual(prob, f, &f0Bd, &f1Bd);CHKERRQ(ierr);
3453 ierr = PetscDSGetRiemannSolver(prob, f, &r);CHKERRQ(ierr);
3454 ierr = PetscDSSetObjective(newprob, fn, obj);CHKERRQ(ierr);
3455 ierr = PetscDSSetResidual(newprob, fn, f0, f1);CHKERRQ(ierr);
3456 ierr = PetscDSSetBdResidual(newprob, fn, f0Bd, f1Bd);CHKERRQ(ierr);
3457 ierr = PetscDSSetRiemannSolver(newprob, fn, r);CHKERRQ(ierr);
3458 for (gn = 0; gn < numFields; ++gn) {
3459 const PetscInt g = fields ? fields[gn] : gn;
3460 PetscPointJac g0, g1, g2, g3;
3461 PetscPointJac g0p, g1p, g2p, g3p;
3462 PetscBdPointJac g0Bd, g1Bd, g2Bd, g3Bd;
3463
3464 if (g >= Nf) continue;
3465 ierr = PetscDSGetJacobian(prob, f, g, &g0, &g1, &g2, &g3);CHKERRQ(ierr);
3466 ierr = PetscDSGetJacobianPreconditioner(prob, f, g, &g0p, &g1p, &g2p, &g3p);CHKERRQ(ierr);
3467 ierr = PetscDSGetBdJacobian(prob, f, g, &g0Bd, &g1Bd, &g2Bd, &g3Bd);CHKERRQ(ierr);
3468 ierr = PetscDSSetJacobian(newprob, fn, gn, g0, g1, g2, g3);CHKERRQ(ierr);
3469 ierr = PetscDSSetJacobianPreconditioner(newprob, fn, gn, g0p, g1p, g2p, g3p);CHKERRQ(ierr);
3470 ierr = PetscDSSetBdJacobian(newprob, fn, gn, g0Bd, g1Bd, g2Bd, g3Bd);CHKERRQ(ierr);
3471 }
3472 }
3473 PetscFunctionReturn(0);
3474 }
3475
3476 /*@
3477 PetscDSCopyEquations - Copy all pointwise function pointers to the new problem
3478
3479 Not collective
3480
3481 Input Parameter:
3482 . prob - The PetscDS object
3483
3484 Output Parameter:
3485 . newprob - The PetscDS copy
3486
3487 Level: intermediate
3488
3489 .seealso: PetscDSCopyBoundary(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3490 @*/
PetscDSCopyEquations(PetscDS prob,PetscDS newprob)3491 PetscErrorCode PetscDSCopyEquations(PetscDS prob, PetscDS newprob)
3492 {
3493 PetscInt Nf, Ng;
3494 PetscErrorCode ierr;
3495
3496 PetscFunctionBegin;
3497 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3498 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
3499 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
3500 ierr = PetscDSGetNumFields(newprob, &Ng);CHKERRQ(ierr);
3501 if (Nf != Ng) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_SIZ, "Number of fields must match %D != %D", Nf, Ng);
3502 ierr = PetscDSSelectEquations(prob, Nf, NULL, newprob);CHKERRQ(ierr);
3503 PetscFunctionReturn(0);
3504 }
3505 /*@
3506 PetscDSCopyConstants - Copy all constants to the new problem
3507
3508 Not collective
3509
3510 Input Parameter:
3511 . prob - The PetscDS object
3512
3513 Output Parameter:
3514 . newprob - The PetscDS copy
3515
3516 Level: intermediate
3517
3518 .seealso: PetscDSCopyBoundary(), PetscDSCopyEquations(), PetscDSSetResidual(), PetscDSSetJacobian(), PetscDSSetRiemannSolver(), PetscDSSetBdResidual(), PetscDSSetBdJacobian(), PetscDSCreate()
3519 @*/
PetscDSCopyConstants(PetscDS prob,PetscDS newprob)3520 PetscErrorCode PetscDSCopyConstants(PetscDS prob, PetscDS newprob)
3521 {
3522 PetscInt Nc;
3523 const PetscScalar *constants;
3524 PetscErrorCode ierr;
3525
3526 PetscFunctionBegin;
3527 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3528 PetscValidHeaderSpecific(newprob, PETSCDS_CLASSID, 2);
3529 ierr = PetscDSGetConstants(prob, &Nc, &constants);CHKERRQ(ierr);
3530 ierr = PetscDSSetConstants(newprob, Nc, (PetscScalar *) constants);CHKERRQ(ierr);
3531 PetscFunctionReturn(0);
3532 }
3533
PetscDSGetHeightSubspace(PetscDS prob,PetscInt height,PetscDS * subprob)3534 PetscErrorCode PetscDSGetHeightSubspace(PetscDS prob, PetscInt height, PetscDS *subprob)
3535 {
3536 PetscInt dim, Nf, f;
3537 PetscErrorCode ierr;
3538
3539 PetscFunctionBegin;
3540 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3541 PetscValidPointer(subprob, 3);
3542 if (height == 0) {*subprob = prob; PetscFunctionReturn(0);}
3543 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
3544 ierr = PetscDSGetSpatialDimension(prob, &dim);CHKERRQ(ierr);
3545 if (height > dim) SETERRQ2(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_OUTOFRANGE, "DS can only handle height in [0, %D], not %D", dim, height);
3546 if (!prob->subprobs) {ierr = PetscCalloc1(dim, &prob->subprobs);CHKERRQ(ierr);}
3547 if (!prob->subprobs[height-1]) {
3548 PetscInt cdim;
3549
3550 ierr = PetscDSCreate(PetscObjectComm((PetscObject) prob), &prob->subprobs[height-1]);CHKERRQ(ierr);
3551 ierr = PetscDSGetCoordinateDimension(prob, &cdim);CHKERRQ(ierr);
3552 ierr = PetscDSSetCoordinateDimension(prob->subprobs[height-1], cdim);CHKERRQ(ierr);
3553 for (f = 0; f < Nf; ++f) {
3554 PetscFE subfe;
3555 PetscObject obj;
3556 PetscClassId id;
3557
3558 ierr = PetscDSGetDiscretization(prob, f, &obj);CHKERRQ(ierr);
3559 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr);
3560 if (id == PETSCFE_CLASSID) {ierr = PetscFEGetHeightSubspace((PetscFE) obj, height, &subfe);CHKERRQ(ierr);}
3561 else SETERRQ1(PetscObjectComm((PetscObject) prob), PETSC_ERR_ARG_WRONG, "Unsupported discretization type for field %d", f);
3562 ierr = PetscDSSetDiscretization(prob->subprobs[height-1], f, (PetscObject) subfe);CHKERRQ(ierr);
3563 }
3564 }
3565 *subprob = prob->subprobs[height-1];
3566 PetscFunctionReturn(0);
3567 }
3568
PetscDSGetDiscType_Internal(PetscDS ds,PetscInt f,PetscDiscType * disctype)3569 PetscErrorCode PetscDSGetDiscType_Internal(PetscDS ds, PetscInt f, PetscDiscType *disctype)
3570 {
3571 PetscObject obj;
3572 PetscClassId id;
3573 PetscInt Nf;
3574 PetscErrorCode ierr;
3575
3576 PetscFunctionBegin;
3577 PetscValidHeaderSpecific(ds, PETSCDS_CLASSID, 1);
3578 PetscValidPointer(disctype, 3);
3579 *disctype = PETSC_DISC_NONE;
3580 ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr);
3581 if (f >= Nf) SETERRQ2(PetscObjectComm((PetscObject) ds), PETSC_ERR_ARG_SIZ, "Field %D must be in [0, %D)", f, Nf);
3582 ierr = PetscDSGetDiscretization(ds, f, &obj);CHKERRQ(ierr);
3583 if (obj) {
3584 ierr = PetscObjectGetClassId(obj, &id);CHKERRQ(ierr);
3585 if (id == PETSCFE_CLASSID) *disctype = PETSC_DISC_FE;
3586 else *disctype = PETSC_DISC_FV;
3587 }
3588 PetscFunctionReturn(0);
3589 }
3590
PetscDSDestroy_Basic(PetscDS prob)3591 static PetscErrorCode PetscDSDestroy_Basic(PetscDS prob)
3592 {
3593 PetscErrorCode ierr;
3594
3595 PetscFunctionBegin;
3596 ierr = PetscFree(prob->data);CHKERRQ(ierr);
3597 PetscFunctionReturn(0);
3598 }
3599
PetscDSInitialize_Basic(PetscDS prob)3600 static PetscErrorCode PetscDSInitialize_Basic(PetscDS prob)
3601 {
3602 PetscFunctionBegin;
3603 prob->ops->setfromoptions = NULL;
3604 prob->ops->setup = NULL;
3605 prob->ops->view = NULL;
3606 prob->ops->destroy = PetscDSDestroy_Basic;
3607 PetscFunctionReturn(0);
3608 }
3609
3610 /*MC
3611 PETSCDSBASIC = "basic" - A discrete system with pointwise residual and boundary residual functions
3612
3613 Level: intermediate
3614
3615 .seealso: PetscDSType, PetscDSCreate(), PetscDSSetType()
3616 M*/
3617
PetscDSCreate_Basic(PetscDS prob)3618 PETSC_EXTERN PetscErrorCode PetscDSCreate_Basic(PetscDS prob)
3619 {
3620 PetscDS_Basic *b;
3621 PetscErrorCode ierr;
3622
3623 PetscFunctionBegin;
3624 PetscValidHeaderSpecific(prob, PETSCDS_CLASSID, 1);
3625 ierr = PetscNewLog(prob, &b);CHKERRQ(ierr);
3626 prob->data = b;
3627
3628 ierr = PetscDSInitialize_Basic(prob);CHKERRQ(ierr);
3629 PetscFunctionReturn(0);
3630 }
3631