Actual source code: dtweakform.c

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

  3: PetscClassId PETSCWEAKFORM_CLASSID = 0;

  5: const char *const PetscWeakFormKinds[] = {"objective", "residual_f0", "residual_f1", "jacobian_g0", "jacobian_g1", "jacobian_g2", "jacobian_g3", "jacobian_preconditioner_g0", "jacobian_preconditioner_g1", "jacobian_preconditioner_g2", "jacobian_preconditioner_g3", "dynamic_jacobian_g0", "dynamic_jacobian_g1", "dynamic_jacobian_g2", "dynamic_jacobian_g3", "boundary_residual_f0", "boundary_residual_f1", "boundary_jacobian_g0", "boundary_jacobian_g1", "boundary_jacobian_g2", "boundary_jacobian_g3", "boundary_jacobian_preconditioner_g0", "boundary_jacobian_preconditioner_g1", "boundary_jacobian_preconditioner_g2", "boundary_jacobian_preconditioner_g3", "riemann_solver", "PetscWeakFormKind", "PETSC_WF_", NULL};

  7: static PetscErrorCode PetscChunkBufferCreate(size_t unitbytes, PetscCount expected, PetscChunkBuffer *buffer[])
  8: {
  9:   PetscFunctionBegin;
 10:   PetscCall(PetscNew(buffer));
 11:   PetscCall(PetscCalloc1(expected * unitbytes, &(*buffer)->array));
 12:   (*buffer)->size      = expected;
 13:   (*buffer)->unitbytes = unitbytes;
 14:   (*buffer)->alloc     = expected * unitbytes;
 15:   PetscFunctionReturn(PETSC_SUCCESS);
 16: }

 18: static PetscErrorCode PetscChunkBufferDuplicate(PetscChunkBuffer *buffer, PetscChunkBuffer *bufferNew[])
 19: {
 20:   PetscFunctionBegin;
 21:   PetscCall(PetscNew(bufferNew));
 22:   PetscCall(PetscCalloc1(buffer->size * buffer->unitbytes, &(*bufferNew)->array));
 23:   PetscCall(PetscMemcpy((*bufferNew)->array, buffer->array, buffer->size * buffer->unitbytes));
 24:   (*bufferNew)->size      = buffer->size;
 25:   (*bufferNew)->unitbytes = buffer->unitbytes;
 26:   (*bufferNew)->alloc     = buffer->size * buffer->unitbytes;
 27:   PetscFunctionReturn(PETSC_SUCCESS);
 28: }

 30: static PetscErrorCode PetscChunkBufferDestroy(PetscChunkBuffer **buffer)
 31: {
 32:   PetscFunctionBegin;
 33:   PetscCall(PetscFree((*buffer)->array));
 34:   PetscCall(PetscFree(*buffer));
 35:   PetscFunctionReturn(PETSC_SUCCESS);
 36: }

 38: static PetscErrorCode PetscChunkBufferCreateChunk(PetscChunkBuffer *buffer, PetscCount size, PetscChunk *chunk)
 39: {
 40:   PetscFunctionBegin;
 41:   if ((buffer->size + size) * buffer->unitbytes > buffer->alloc) {
 42:     char *tmp;

 44:     if (!buffer->alloc) buffer->alloc = (buffer->size + size) * buffer->unitbytes;
 45:     while ((buffer->size + size) * buffer->unitbytes > buffer->alloc) buffer->alloc *= 2;
 46:     PetscCall(PetscMalloc(buffer->alloc, &tmp));
 47:     PetscCall(PetscMemcpy(tmp, buffer->array, buffer->size * buffer->unitbytes));
 48:     PetscCall(PetscFree(buffer->array));
 49:     buffer->array = tmp;
 50:   }
 51:   chunk->start    = buffer->size * buffer->unitbytes;
 52:   chunk->size     = size;
 53:   chunk->reserved = size;
 54:   buffer->size += size;
 55:   PetscFunctionReturn(PETSC_SUCCESS);
 56: }

 58: static PetscErrorCode PetscChunkBufferEnlargeChunk(PetscChunkBuffer *buffer, PetscCount size, PetscChunk *chunk)
 59: {
 60:   size_t siz = size;

 62:   PetscFunctionBegin;
 63:   if (chunk->size + size > chunk->reserved) {
 64:     PetscChunk newchunk;
 65:     PetscCount reserved = chunk->size;

 67:     /* TODO Here if we had a chunk list, we could update them all to reclaim unused space */
 68:     while (reserved < chunk->size + size) reserved *= 2;
 69:     PetscCall(PetscChunkBufferCreateChunk(buffer, (size_t)reserved, &newchunk));
 70:     newchunk.size = chunk->size + size;
 71:     PetscCall(PetscMemcpy(&buffer->array[newchunk.start], &buffer->array[chunk->start], chunk->size * buffer->unitbytes));
 72:     *chunk = newchunk;
 73:   } else {
 74:     chunk->size += siz;
 75:   }
 76:   PetscFunctionReturn(PETSC_SUCCESS);
 77: }

 79: /*@C
 80:   PetscFormKeySort - Sorts an array of `PetscFormKey` in place in increasing order.

 82:   Not Collective

 84:   Input Parameters:
 85: + n   - number of values
 86: - arr - array of `PetscFormKey`

 88:   Level: intermediate

 90: .seealso: `PetscFormKey`, `PetscIntSortSemiOrdered()`, `PetscSortInt()`
 91: @*/
 92: PetscErrorCode PetscFormKeySort(PetscInt n, PetscFormKey arr[])
 93: {
 94:   PetscFunctionBegin;
 95:   if (n <= 1) PetscFunctionReturn(PETSC_SUCCESS);
 96:   PetscAssertPointer(arr, 2);
 97:   PetscCall(PetscTimSort(n, arr, sizeof(PetscFormKey), Compare_PetscFormKey_Private, NULL));
 98:   PetscFunctionReturn(PETSC_SUCCESS);
 99: }

101: static PetscErrorCode PetscWeakFormGetFunction_Private(PetscWeakForm wf, PetscHMapForm ht, DMLabel label, PetscInt value, PetscInt f, PetscInt part, PetscInt *n, void (***func)(void))
102: {
103:   PetscFormKey key;
104:   PetscChunk   chunk;

106:   PetscFunctionBegin;
107:   key.label = label;
108:   key.value = value;
109:   key.field = f;
110:   key.part  = part;
111:   PetscCall(PetscHMapFormGet(ht, key, &chunk));
112:   if (chunk.size < 0) {
113:     *n    = 0;
114:     *func = NULL;
115:   } else {
116:     PetscCall(PetscIntCast(chunk.size, n));
117:     *func = (PetscVoidFn **)&wf->funcs->array[chunk.start];
118:   }
119:   PetscFunctionReturn(PETSC_SUCCESS);
120: }

122: /* A NULL argument for func causes this to clear the key */
123: static PetscErrorCode PetscWeakFormSetFunction_Private(PetscWeakForm wf, PetscHMapForm ht, DMLabel label, PetscInt value, PetscInt f, PetscInt part, PetscInt n, PetscVoidFn **func)
124: {
125:   PetscFormKey key;
126:   PetscChunk   chunk;
127:   PetscInt     i;

129:   PetscFunctionBegin;
130:   key.label = label;
131:   key.value = value;
132:   key.field = f;
133:   key.part  = part;
134:   if (!func) {
135:     PetscCall(PetscHMapFormDel(ht, key));
136:     PetscFunctionReturn(PETSC_SUCCESS);
137:   } else PetscCall(PetscHMapFormGet(ht, key, &chunk));
138:   if (chunk.size < 0) {
139:     PetscCall(PetscChunkBufferCreateChunk(wf->funcs, n, &chunk));
140:     PetscCall(PetscHMapFormSet(ht, key, chunk));
141:   } else if (chunk.size <= n) {
142:     PetscCall(PetscChunkBufferEnlargeChunk(wf->funcs, n - chunk.size, &chunk));
143:     PetscCall(PetscHMapFormSet(ht, key, chunk));
144:   }
145:   for (i = 0; i < n; ++i) ((PetscVoidFn **)&wf->funcs->array[chunk.start])[i] = func[i];
146:   PetscFunctionReturn(PETSC_SUCCESS);
147: }

149: static PetscErrorCode PetscWeakFormAddFunction_Private(PetscWeakForm wf, PetscHMapForm ht, DMLabel label, PetscInt value, PetscInt f, PetscInt part, PetscVoidFn *func)
150: {
151:   PetscFormKey key;
152:   PetscChunk   chunk;

154:   PetscFunctionBegin;
155:   if (!func) PetscFunctionReturn(PETSC_SUCCESS);
156:   key.label = label;
157:   key.value = value;
158:   key.field = f;
159:   key.part  = part;
160:   PetscCall(PetscHMapFormGet(ht, key, &chunk));
161:   if (chunk.size < 0) {
162:     PetscCall(PetscChunkBufferCreateChunk(wf->funcs, 1, &chunk));
163:     PetscCall(PetscHMapFormSet(ht, key, chunk));
164:     ((PetscVoidFn **)&wf->funcs->array[chunk.start])[0] = func;
165:   } else {
166:     PetscCall(PetscChunkBufferEnlargeChunk(wf->funcs, 1, &chunk));
167:     PetscCall(PetscHMapFormSet(ht, key, chunk));
168:     ((PetscVoidFn **)&wf->funcs->array[chunk.start])[chunk.size - 1] = func;
169:   }
170:   PetscFunctionReturn(PETSC_SUCCESS);
171: }

173: static PetscErrorCode PetscWeakFormGetIndexFunction_Private(PetscWeakForm wf, PetscHMapForm ht, DMLabel label, PetscInt value, PetscInt f, PetscInt part, PetscInt ind, PetscVoidFn **func)
174: {
175:   PetscFormKey key;
176:   PetscChunk   chunk;

178:   PetscFunctionBegin;
179:   key.label = label;
180:   key.value = value;
181:   key.field = f;
182:   key.part  = part;
183:   PetscCall(PetscHMapFormGet(ht, key, &chunk));
184:   if (chunk.size < 0) {
185:     *func = NULL;
186:   } else {
187:     PetscCheck(ind < chunk.size, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " not in [0, %" PetscCount_FMT ")", ind, chunk.size);
188:     *func = ((PetscVoidFn **)&wf->funcs->array[chunk.start])[ind];
189:   }
190:   PetscFunctionReturn(PETSC_SUCCESS);
191: }

193: /* Ignore a NULL func */
194: static PetscErrorCode PetscWeakFormSetIndexFunction_Private(PetscWeakForm wf, PetscHMapForm ht, DMLabel label, PetscInt value, PetscInt f, PetscInt part, PetscInt ind, PetscVoidFn *func)
195: {
196:   PetscFormKey key;
197:   PetscChunk   chunk;

199:   PetscFunctionBegin;
200:   if (!func) PetscFunctionReturn(PETSC_SUCCESS);
201:   key.label = label;
202:   key.value = value;
203:   key.field = f;
204:   key.part  = part;
205:   PetscCall(PetscHMapFormGet(ht, key, &chunk));
206:   if (chunk.size < 0) {
207:     PetscCall(PetscChunkBufferCreateChunk(wf->funcs, ind + 1, &chunk));
208:     PetscCall(PetscHMapFormSet(ht, key, chunk));
209:   } else if (chunk.size <= ind) {
210:     PetscCall(PetscChunkBufferEnlargeChunk(wf->funcs, ind - chunk.size + 1, &chunk));
211:     PetscCall(PetscHMapFormSet(ht, key, chunk));
212:   }
213:   ((PetscVoidFn **)&wf->funcs->array[chunk.start])[ind] = func;
214:   PetscFunctionReturn(PETSC_SUCCESS);
215: }

217: static PetscErrorCode PetscWeakFormClearIndexFunction_Private(PetscWeakForm wf, PetscHMapForm ht, DMLabel label, PetscInt value, PetscInt f, PetscInt part, PetscInt ind)
218: {
219:   PetscFormKey key;
220:   PetscChunk   chunk;

222:   PetscFunctionBegin;
223:   key.label = label;
224:   key.value = value;
225:   key.field = f;
226:   key.part  = part;
227:   PetscCall(PetscHMapFormGet(ht, key, &chunk));
228:   if (chunk.size < 0) PetscFunctionReturn(PETSC_SUCCESS);
229:   else if (!ind && chunk.size == 1) {
230:     PetscCall(PetscHMapFormDel(ht, key));
231:     PetscFunctionReturn(PETSC_SUCCESS);
232:   } else if (chunk.size <= ind) PetscFunctionReturn(PETSC_SUCCESS);
233:   ((PetscVoidFn **)&wf->funcs->array[chunk.start])[ind] = NULL;
234:   PetscFunctionReturn(PETSC_SUCCESS);
235: }

237: /*@
238:   PetscWeakFormCopy - Copy the pointwise functions to another `PetscWeakForm`

240:   Not Collective

242:   Input Parameter:
243: . wf - The original `PetscWeakForm`

245:   Output Parameter:
246: . wfNew - The copy of the `PetscWeakForm`

248:   Level: intermediate

250: .seealso: `PetscWeakForm`, `PetscWeakFormCreate()`, `PetscWeakFormDestroy()`
251: @*/
252: PetscErrorCode PetscWeakFormCopy(PetscWeakForm wf, PetscWeakForm wfNew)
253: {
254:   PetscInt f;

256:   PetscFunctionBegin;
257:   wfNew->Nf = wf->Nf;
258:   PetscCall(PetscChunkBufferDestroy(&wfNew->funcs));
259:   PetscCall(PetscChunkBufferDuplicate(wf->funcs, &wfNew->funcs));
260:   for (f = 0; f < PETSC_NUM_WF; ++f) {
261:     PetscCall(PetscHMapFormDestroy(&wfNew->form[f]));
262:     PetscCall(PetscHMapFormDuplicate(wf->form[f], &wfNew->form[f]));
263:   }
264:   PetscFunctionReturn(PETSC_SUCCESS);
265: }

267: /*@
268:   PetscWeakFormClear - Clear all functions from the `PetscWeakForm`

270:   Not Collective

272:   Input Parameter:
273: . wf - The original `PetscWeakForm`

275:   Level: intermediate

277: .seealso: `PetscWeakForm`, `PetscWeakFormCopy()`, `PetscWeakFormCreate()`, `PetscWeakFormDestroy()`
278: @*/
279: PetscErrorCode PetscWeakFormClear(PetscWeakForm wf)
280: {
281:   PetscInt f;

283:   PetscFunctionBegin;
284:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscHMapFormClear(wf->form[f]));
285:   PetscFunctionReturn(PETSC_SUCCESS);
286: }

288: static PetscErrorCode PetscWeakFormRewriteKeys_Internal(PetscWeakForm wf, PetscHMapForm hmap, DMLabel label, PetscInt Nv, const PetscInt values[])
289: {
290:   PetscFormKey *keys;
291:   PetscVoidFn **tmpfuncs;
292:   PetscInt      n, off = 0, maxNf = 0;

294:   PetscFunctionBegin;
295:   PetscCall(PetscHMapFormGetSize(hmap, &n));
296:   PetscCall(PetscMalloc1(n, &keys));
297:   PetscCall(PetscHMapFormGetKeys(hmap, &off, keys));
298:   // Need to make a copy since SetFunction() can invalidate the storage
299:   for (PetscInt i = 0; i < n; ++i) {
300:     if (keys[i].label == label) {
301:       PetscVoidFn **funcs;
302:       PetscInt      Nf;

304:       PetscCall(PetscWeakFormGetFunction_Private(wf, hmap, keys[i].label, keys[i].value, keys[i].field, keys[i].part, &Nf, &funcs));
305:       maxNf = PetscMax(maxNf, Nf);
306:     }
307:   }
308:   PetscCall(PetscMalloc1(maxNf, &tmpfuncs));
309:   for (PetscInt i = 0; i < n; ++i) {
310:     if (keys[i].label == label) {
311:       PetscBool     clear = PETSC_TRUE;
312:       PetscVoidFn **funcs;
313:       PetscInt      Nf;

315:       PetscCall(PetscWeakFormGetFunction_Private(wf, hmap, keys[i].label, keys[i].value, keys[i].field, keys[i].part, &Nf, &funcs));
316:       for (PetscInt f = 0; f < Nf; ++f) tmpfuncs[f] = funcs[f];
317:       for (PetscInt v = 0; v < Nv; ++v) {
318:         PetscCall(PetscWeakFormSetFunction_Private(wf, hmap, keys[i].label, values[v], keys[i].field, keys[i].part, Nf, tmpfuncs));
319:         if (values[v] == keys[i].value) clear = PETSC_FALSE;
320:       }
321:       if (clear) PetscCall(PetscWeakFormSetFunction_Private(wf, hmap, keys[i].label, keys[i].value, keys[i].field, keys[i].part, 0, NULL));
322:     }
323:   }
324:   PetscCall(PetscFree(tmpfuncs));
325:   PetscCall(PetscFree(keys));
326:   PetscFunctionReturn(PETSC_SUCCESS);
327: }

329: /*@
330:   PetscWeakFormRewriteKeys - Change any key on the given label to use the new set of label values

332:   Not Collective

334:   Input Parameters:
335: + wf     - The original `PetscWeakForm`
336: . label  - The label to change keys for
337: . Nv     - The number of new label values
338: - values - The set of new values to relabel keys with

340:   Level: intermediate

342:   Note:
343:   This is used internally when boundary label values are specified from the command line.

345: .seealso: `PetscWeakForm`, `DMLabel`, `PetscWeakFormReplaceLabel()`, `PetscWeakFormCreate()`, `PetscWeakFormDestroy()`
346: @*/
347: PetscErrorCode PetscWeakFormRewriteKeys(PetscWeakForm wf, DMLabel label, PetscInt Nv, const PetscInt values[])
348: {
349:   PetscInt f;

351:   PetscFunctionBegin;
352:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscWeakFormRewriteKeys_Internal(wf, wf->form[f], label, Nv, values));
353:   PetscFunctionReturn(PETSC_SUCCESS);
354: }

356: static PetscErrorCode PetscWeakFormReplaceLabel_Internal(PetscWeakForm wf, PetscHMapForm hmap, DMLabel label)
357: {
358:   PetscFormKey *keys;
359:   PetscInt      n, i, off = 0, maxFuncs = 0;
360:   PetscVoidFn **tmpf;
361:   const char   *name = NULL;

363:   PetscFunctionBegin;
364:   if (label) PetscCall(PetscObjectGetName((PetscObject)label, &name));
365:   PetscCall(PetscHMapFormGetSize(hmap, &n));
366:   PetscCall(PetscMalloc1(n, &keys));
367:   PetscCall(PetscHMapFormGetKeys(hmap, &off, keys));
368:   for (i = 0; i < n; ++i) {
369:     PetscBool   match = PETSC_FALSE;
370:     const char *lname = NULL;

372:     if (label == keys[i].label) continue;
373:     if (keys[i].label) PetscCall(PetscObjectGetName((PetscObject)keys[i].label, &lname));
374:     PetscCall(PetscStrcmp(name, lname, &match));
375:     if ((!name && !lname) || match) {
376:       PetscVoidFn **funcs;
377:       PetscInt      Nf;

379:       PetscCall(PetscWeakFormGetFunction_Private(wf, hmap, keys[i].label, keys[i].value, keys[i].field, keys[i].part, &Nf, &funcs));
380:       maxFuncs = PetscMax(maxFuncs, Nf);
381:     }
382:   }
383:   /* Need temp space because chunk buffer can be reallocated in SetFunction() call */
384:   PetscCall(PetscMalloc1(maxFuncs, &tmpf));
385:   for (i = 0; i < n; ++i) {
386:     PetscBool   match = PETSC_FALSE;
387:     const char *lname = NULL;

389:     if (label == keys[i].label) continue;
390:     if (keys[i].label) PetscCall(PetscObjectGetName((PetscObject)keys[i].label, &lname));
391:     PetscCall(PetscStrcmp(name, lname, &match));
392:     if ((!name && !lname) || match) {
393:       PetscVoidFn **funcs;
394:       PetscInt      Nf, j;

396:       PetscCall(PetscWeakFormGetFunction_Private(wf, hmap, keys[i].label, keys[i].value, keys[i].field, keys[i].part, &Nf, &funcs));
397:       for (j = 0; j < Nf; ++j) tmpf[j] = funcs[j];
398:       PetscCall(PetscWeakFormSetFunction_Private(wf, hmap, label, keys[i].value, keys[i].field, keys[i].part, Nf, tmpf));
399:       PetscCall(PetscWeakFormSetFunction_Private(wf, hmap, keys[i].label, keys[i].value, keys[i].field, keys[i].part, 0, NULL));
400:     }
401:   }
402:   PetscCall(PetscFree(tmpf));
403:   PetscCall(PetscFree(keys));
404:   PetscFunctionReturn(PETSC_SUCCESS);
405: }

407: /*@
408:   PetscWeakFormReplaceLabel - Change any key on a label of the same name to use the new label

410:   Not Collective

412:   Input Parameters:
413: + wf    - The original `PetscWeakForm`
414: - label - The label to change keys for

416:   Level: intermediate

418:   Note:
419:   This is used internally when meshes are modified

421: .seealso: `PetscWeakForm`, `DMLabel`, `PetscWeakFormRewriteKeys()`, `PetscWeakFormCreate()`, `PetscWeakFormDestroy()`
422: @*/
423: PetscErrorCode PetscWeakFormReplaceLabel(PetscWeakForm wf, DMLabel label)
424: {
425:   PetscInt f;

427:   PetscFunctionBegin;
428:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscWeakFormReplaceLabel_Internal(wf, wf->form[f], label));
429:   PetscFunctionReturn(PETSC_SUCCESS);
430: }

432: /*@
433:   PetscWeakFormClearIndex - Clear the pointwise function at a given index for the given key from a `PetscWeakForm`

435:   Not Collective

437:   Input Parameters:
438: + wf    - The `PetscWeakForm`
439: . label - The label selecting the mesh region, or `NULL` for the entire domain
440: . val   - The label value selecting the mesh region
441: . f     - The field number
442: . part  - The equation part, or 0 if unused
443: . kind  - The kind of weak form, see `PetscWeakFormKind`
444: - ind   - The index of the function to clear in the function list for this key

446:   Level: intermediate

448: .seealso: `PetscWeakForm`, `PetscWeakFormKind`, `PetscWeakFormCreate()`
449: @*/
450: PetscErrorCode PetscWeakFormClearIndex(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscWeakFormKind kind, PetscInt ind)
451: {
452:   PetscFunctionBegin;
453:   PetscCall(PetscWeakFormClearIndexFunction_Private(wf, wf->form[kind], label, val, f, part, ind));
454:   PetscFunctionReturn(PETSC_SUCCESS);
455: }

457: /*@C
458:   PetscWeakFormGetObjective - Retrieve the list of objective pointwise functions for a given key from a `PetscWeakForm`

460:   Not Collective

462:   Input Parameters:
463: + wf    - The `PetscWeakForm`
464: . label - The label selecting the mesh region, or `NULL` for the entire domain
465: . val   - The label value selecting the mesh region
466: . f     - The field number
467: - part  - The equation part, or 0 if unused

469:   Output Parameters:
470: + n   - The number of objective pointwise functions registered for this key
471: - obj - The array of objective pointwise functions

473:   Level: intermediate

475: .seealso: `PetscWeakForm`, `PetscWeakFormSetObjective()`, `PetscWeakFormAddObjective()`, `PetscWeakFormSetIndexObjective()`, `PetscWeakFormGetIndexObjective()`
476: @*/
477: PetscErrorCode PetscWeakFormGetObjective(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt *n, void (***obj)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
478: {
479:   PetscFunctionBegin;
480:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, n, (void (***)(void))obj));
481:   PetscFunctionReturn(PETSC_SUCCESS);
482: }

484: /*@C
485:   PetscWeakFormSetObjective - Set the list of objective pointwise functions for a given key in a `PetscWeakForm`

487:   Not Collective

489:   Input Parameters:
490: + wf    - The `PetscWeakForm`
491: . label - The label selecting the mesh region, or `NULL` for the entire domain
492: . val   - The label value selecting the mesh region
493: . f     - The field number
494: . part  - The equation part, or 0 if unused
495: . n     - The number of objective pointwise functions to set
496: - obj   - The array of objective pointwise functions, or `NULL` to clear the key

498:   Level: intermediate

500: .seealso: `PetscWeakForm`, `PetscWeakFormGetObjective()`, `PetscWeakFormAddObjective()`, `PetscWeakFormSetIndexObjective()`
501: @*/
502: PetscErrorCode PetscWeakFormSetObjective(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt n, void (**obj)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
503: {
504:   PetscFunctionBegin;
505:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, n, (PetscVoidFn **)obj));
506:   PetscFunctionReturn(PETSC_SUCCESS);
507: }

509: /*@C
510:   PetscWeakFormAddObjective - Append an objective pointwise function to the list for a given key in a `PetscWeakForm`

512:   Not Collective

514:   Input Parameters:
515: + wf    - The `PetscWeakForm`
516: . label - The label selecting the mesh region, or `NULL` for the entire domain
517: . val   - The label value selecting the mesh region
518: . f     - The field number
519: . part  - The equation part, or 0 if unused
520: - obj   - The objective pointwise function to append; a `NULL` is ignored

522:   Level: intermediate

524: .seealso: `PetscWeakForm`, `PetscWeakFormSetObjective()`, `PetscWeakFormGetObjective()`, `PetscWeakFormSetIndexObjective()`
525: @*/
526: PetscErrorCode PetscWeakFormAddObjective(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, void (*obj)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
527: {
528:   PetscFunctionBegin;
529:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, (PetscVoidFn *)obj));
530:   PetscFunctionReturn(PETSC_SUCCESS);
531: }

533: /*@C
534:   PetscWeakFormGetIndexObjective - Retrieve a single objective pointwise function at the given index for a given key from a `PetscWeakForm`

536:   Not Collective

538:   Input Parameters:
539: + wf    - The `PetscWeakForm`
540: . label - The label selecting the mesh region, or `NULL` for the entire domain
541: . val   - The label value selecting the mesh region
542: . f     - The field number
543: . part  - The equation part, or 0 if unused
544: - ind   - The index into the list of objective pointwise functions for this key

546:   Output Parameter:
547: . obj - The objective pointwise function at position `ind`, or `NULL` if no function is registered for this key

549:   Level: intermediate

551: .seealso: `PetscWeakForm`, `PetscWeakFormSetIndexObjective()`, `PetscWeakFormGetObjective()`, `PetscWeakFormSetObjective()`, `PetscWeakFormAddObjective()`
552: @*/
553: PetscErrorCode PetscWeakFormGetIndexObjective(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt ind, void (**obj)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
554: {
555:   PetscFunctionBegin;
556:   PetscCall(PetscWeakFormGetIndexFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, ind, (PetscVoidFn **)obj));
557:   PetscFunctionReturn(PETSC_SUCCESS);
558: }

560: /*@C
561:   PetscWeakFormSetIndexObjective - Set a single objective pointwise function at the given index for a given key in a `PetscWeakForm`

563:   Not Collective

565:   Input Parameters:
566: + wf    - The `PetscWeakForm`
567: . label - The label selecting the mesh region, or `NULL` for the entire domain
568: . val   - The label value selecting the mesh region
569: . f     - The field number
570: . part  - The equation part, or 0 if unused
571: . ind   - The index into the list of objective pointwise functions for this key
572: - obj   - The objective pointwise function to store at position `ind`; a `NULL` is ignored

574:   Level: intermediate

576: .seealso: `PetscWeakForm`, `PetscWeakFormGetIndexObjective()`, `PetscWeakFormSetObjective()`, `PetscWeakFormAddObjective()`, `PetscWeakFormClearIndex()`
577: @*/
578: PetscErrorCode PetscWeakFormSetIndexObjective(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt ind, void (*obj)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
579: {
580:   PetscFunctionBegin;
581:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, ind, (PetscVoidFn *)obj));
582:   PetscFunctionReturn(PETSC_SUCCESS);
583: }

585: /*@C
586:   PetscWeakFormGetResidual - Retrieve the lists of residual pointwise functions `f0` and `f1` for a given key from a `PetscWeakForm`

588:   Not Collective

590:   Input Parameters:
591: + wf    - The `PetscWeakForm`
592: . label - The label selecting the mesh region, or `NULL` for the entire domain
593: . val   - The label value selecting the mesh region
594: . f     - The field number
595: - part  - The equation part, or 0 if unused

597:   Output Parameters:
598: + n0 - The number of `f0` pointwise functions registered for this key
599: . f0 - The array of `f0` residual pointwise functions
600: . n1 - The number of `f1` pointwise functions registered for this key
601: - f1 - The array of `f1` residual pointwise functions

603:   Level: intermediate

605: .seealso: `PetscWeakForm`, `PetscWeakFormSetResidual()`, `PetscWeakFormAddResidual()`, `PetscWeakFormGetBdResidual()`
606: @*/
607: PetscErrorCode PetscWeakFormGetResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt *n0, void (***f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
608: {
609:   PetscFunctionBegin;
610:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, n0, (void (***)(void))f0));
611:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, n1, (void (***)(void))f1));
612:   PetscFunctionReturn(PETSC_SUCCESS);
613: }

615: /*@C
616:   PetscWeakFormAddResidual - Append residual pointwise functions `f0` and `f1` to the lists for a given key in a `PetscWeakForm`

618:   Not Collective

620:   Input Parameters:
621: + wf    - The `PetscWeakForm`
622: . label - The label selecting the mesh region, or `NULL` for the entire domain
623: . val   - The label value selecting the mesh region
624: . f     - The field number
625: . part  - The equation part, or 0 if unused
626: . f0    - The `f0` residual pointwise function to append; a `NULL` is ignored
627: - f1    - The `f1` residual pointwise function to append; a `NULL` is ignored

629:   Level: intermediate

631: .seealso: `PetscWeakForm`, `PetscWeakFormSetResidual()`, `PetscWeakFormGetResidual()`, `PetscWeakFormSetIndexResidual()`, `PetscWeakFormAddBdResidual()`
632: @*/
633: PetscErrorCode PetscWeakFormAddResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, void (*f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
634: {
635:   PetscFunctionBegin;
636:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, (PetscVoidFn *)f0));
637:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, (PetscVoidFn *)f1));
638:   PetscFunctionReturn(PETSC_SUCCESS);
639: }

641: /*@C
642:   PetscWeakFormSetResidual - Set the lists of residual pointwise functions `f0` and `f1` for a given key in a `PetscWeakForm`

644:   Not Collective

646:   Input Parameters:
647: + wf    - The `PetscWeakForm`
648: . label - The label selecting the mesh region, or `NULL` for the entire domain
649: . val   - The label value selecting the mesh region
650: . f     - The field number
651: . part  - The equation part, or 0 if unused
652: . n0    - The number of `f0` pointwise functions to set
653: . f0    - The array of `f0` residual pointwise functions, or `NULL` to clear the key
654: . n1    - The number of `f1` pointwise functions to set
655: - f1    - The array of `f1` residual pointwise functions, or `NULL` to clear the key

657:   Level: intermediate

659: .seealso: `PetscWeakForm`, `PetscWeakFormGetResidual()`, `PetscWeakFormAddResidual()`, `PetscWeakFormSetIndexResidual()`
660: @*/
661: PetscErrorCode PetscWeakFormSetResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt n0, void (**f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
662: {
663:   PetscFunctionBegin;
664:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, n0, (PetscVoidFn **)f0));
665:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, n1, (PetscVoidFn **)f1));
666:   PetscFunctionReturn(PETSC_SUCCESS);
667: }

669: /*@C
670:   PetscWeakFormSetIndexResidual - Set the residual pointwise functions `f0` and `f1` at the given indices for a given key in a `PetscWeakForm`

672:   Not Collective

674:   Input Parameters:
675: + wf    - The `PetscWeakForm`
676: . label - The label selecting the mesh region, or `NULL` for the entire domain
677: . val   - The label value selecting the mesh region
678: . f     - The field number
679: . part  - The equation part, or 0 if unused
680: . i0    - The index at which to store `f0` in the `f0` list
681: . f0    - The `f0` residual pointwise function; a `NULL` is ignored
682: . i1    - The index at which to store `f1` in the `f1` list
683: - f1    - The `f1` residual pointwise function; a `NULL` is ignored

685:   Level: intermediate

687: .seealso: `PetscWeakForm`, `PetscWeakFormSetResidual()`, `PetscWeakFormAddResidual()`, `PetscWeakFormGetResidual()`, `PetscWeakFormClearIndex()`
688: @*/
689: PetscErrorCode PetscWeakFormSetIndexResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt i0, void (*f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
690: {
691:   PetscFunctionBegin;
692:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, i0, (PetscVoidFn *)f0));
693:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, i1, (PetscVoidFn *)f1));
694:   PetscFunctionReturn(PETSC_SUCCESS);
695: }

697: /*@C
698:   PetscWeakFormGetBdResidual - Retrieve the lists of boundary residual pointwise functions `f0` and `f1` for a given key from a `PetscWeakForm`

700:   Not Collective

702:   Input Parameters:
703: + wf    - The `PetscWeakForm`
704: . label - The label selecting the boundary region, or `NULL` for the entire boundary
705: . val   - The label value selecting the boundary region
706: . f     - The field number
707: - part  - The equation part, or 0 if unused

709:   Output Parameters:
710: + n0 - The number of `f0` boundary pointwise functions registered for this key
711: . f0 - The array of `f0` boundary residual pointwise functions
712: . n1 - The number of `f1` boundary pointwise functions registered for this key
713: - f1 - The array of `f1` boundary residual pointwise functions

715:   Level: intermediate

717: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdResidual()`, `PetscWeakFormAddBdResidual()`, `PetscWeakFormGetResidual()`
718: @*/
719: PetscErrorCode PetscWeakFormGetBdResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt *n0, void (***f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
720: {
721:   PetscFunctionBegin;
722:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, n0, (void (***)(void))f0));
723:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, n1, (void (***)(void))f1));
724:   PetscFunctionReturn(PETSC_SUCCESS);
725: }

727: /*@C
728:   PetscWeakFormAddBdResidual - Append boundary residual pointwise functions `f0` and `f1` to the lists for a given key in a `PetscWeakForm`

730:   Not Collective

732:   Input Parameters:
733: + wf    - The `PetscWeakForm`
734: . label - The label selecting the boundary region, or `NULL` for the entire boundary
735: . val   - The label value selecting the boundary region
736: . f     - The field number
737: . part  - The equation part, or 0 if unused
738: . f0    - The `f0` boundary residual pointwise function to append; a `NULL` is ignored
739: - f1    - The `f1` boundary residual pointwise function to append; a `NULL` is ignored

741:   Level: intermediate

743: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdResidual()`, `PetscWeakFormGetBdResidual()`, `PetscWeakFormAddResidual()`
744: @*/
745: PetscErrorCode PetscWeakFormAddBdResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, void (*f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
746: {
747:   PetscFunctionBegin;
748:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, (PetscVoidFn *)f0));
749:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, (PetscVoidFn *)f1));
750:   PetscFunctionReturn(PETSC_SUCCESS);
751: }

753: /*@C
754:   PetscWeakFormSetBdResidual - Set the lists of boundary residual pointwise functions `f0` and `f1` for a given key in a `PetscWeakForm`

756:   Not Collective

758:   Input Parameters:
759: + wf    - The `PetscWeakForm`
760: . label - The label selecting the boundary region, or `NULL` for the entire boundary
761: . val   - The label value selecting the boundary region
762: . f     - The field number
763: . part  - The equation part, or 0 if unused
764: . n0    - The number of `f0` boundary pointwise functions to set
765: . f0    - The array of `f0` boundary residual pointwise functions, or `NULL` to clear the key
766: . n1    - The number of `f1` boundary pointwise functions to set
767: - f1    - The array of `f1` boundary residual pointwise functions, or `NULL` to clear the key

769:   Level: intermediate

771: .seealso: `PetscWeakForm`, `PetscWeakFormGetBdResidual()`, `PetscWeakFormAddBdResidual()`, `PetscWeakFormSetResidual()`
772: @*/
773: PetscErrorCode PetscWeakFormSetBdResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt n0, void (**f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
774: {
775:   PetscFunctionBegin;
776:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, n0, (PetscVoidFn **)f0));
777:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, n1, (PetscVoidFn **)f1));
778:   PetscFunctionReturn(PETSC_SUCCESS);
779: }

781: /*@C
782:   PetscWeakFormSetIndexBdResidual - Set the boundary residual pointwise functions `f0` and `f1` at the given indices for a given key in a `PetscWeakForm`

784:   Not Collective

786:   Input Parameters:
787: + wf    - The `PetscWeakForm`
788: . label - The label selecting the boundary region, or `NULL` for the entire boundary
789: . val   - The label value selecting the boundary region
790: . f     - The field number
791: . part  - The equation part, or 0 if unused
792: . i0    - The index at which to store `f0` in the `f0` list
793: . f0    - The `f0` boundary residual pointwise function; a `NULL` is ignored
794: . i1    - The index at which to store `f1` in the `f1` list
795: - f1    - The `f1` boundary residual pointwise function; a `NULL` is ignored

797:   Level: intermediate

799: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdResidual()`, `PetscWeakFormAddBdResidual()`, `PetscWeakFormGetBdResidual()`, `PetscWeakFormClearIndex()`
800: @*/
801: PetscErrorCode PetscWeakFormSetIndexBdResidual(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt i0, void (*f0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*f1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
802: {
803:   PetscFunctionBegin;
804:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, i0, (PetscVoidFn *)f0));
805:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, i1, (PetscVoidFn *)f1));
806:   PetscFunctionReturn(PETSC_SUCCESS);
807: }

809: /*@
810:   PetscWeakFormHasJacobian - Returns whether the `PetscWeakForm` has any Jacobian (`g0`, `g1`, `g2`, or `g3`) pointwise functions registered

812:   Not Collective

814:   Input Parameter:
815: . wf - The `PetscWeakForm`

817:   Output Parameter:
818: . hasJac - `PETSC_TRUE` if any Jacobian pointwise functions are registered, `PETSC_FALSE` otherwise

820:   Level: intermediate

822: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormGetJacobian()`, `PetscWeakFormHasJacobianPreconditioner()`, `PetscWeakFormHasBdJacobian()`
823: @*/
824: PetscErrorCode PetscWeakFormHasJacobian(PetscWeakForm wf, PetscBool *hasJac)
825: {
826:   PetscInt n0, n1, n2, n3;

828:   PetscFunctionBegin;
830:   PetscAssertPointer(hasJac, 2);
831:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G0], &n0));
832:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G1], &n1));
833:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G2], &n2));
834:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G3], &n3));
835:   *hasJac = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
836:   PetscFunctionReturn(PETSC_SUCCESS);
837: }

839: /*@C
840:   PetscWeakFormGetJacobian - Retrieve the lists of Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key from a `PetscWeakForm`

842:   Not Collective

844:   Input Parameters:
845: + wf    - The `PetscWeakForm`
846: . label - The label selecting the mesh region, or `NULL` for the entire domain
847: . val   - The label value selecting the mesh region
848: . f     - The test field number
849: . g     - The trial field number
850: - part  - The equation part, or 0 if unused

852:   Output Parameters:
853: + n0 - The number of `g0` pointwise functions registered for this key
854: . g0 - The array of `g0` Jacobian pointwise functions
855: . n1 - The number of `g1` pointwise functions registered for this key
856: . g1 - The array of `g1` Jacobian pointwise functions
857: . n2 - The number of `g2` pointwise functions registered for this key
858: . g2 - The array of `g2` Jacobian pointwise functions
859: . n3 - The number of `g3` pointwise functions registered for this key
860: - g3 - The array of `g3` Jacobian pointwise functions

862:   Level: intermediate

864: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormAddJacobian()`, `PetscWeakFormHasJacobian()`, `PetscWeakFormGetJacobianPreconditioner()`
865: @*/
866: PetscErrorCode PetscWeakFormGetJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt *n0, void (***g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n2, void (***g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n3, void (***g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
867: {
868:   PetscInt find = f * wf->Nf + g;

870:   PetscFunctionBegin;
871:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, n0, (void (***)(void))g0));
872:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, n1, (void (***)(void))g1));
873:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, n2, (void (***)(void))g2));
874:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, n3, (void (***)(void))g3));
875:   PetscFunctionReturn(PETSC_SUCCESS);
876: }

878: /*@C
879:   PetscWeakFormAddJacobian - Append Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` to the lists for a given key in a `PetscWeakForm`

881:   Not Collective

883:   Input Parameters:
884: + wf    - The `PetscWeakForm`
885: . label - The label selecting the mesh region, or `NULL` for the entire domain
886: . val   - The label value selecting the mesh region
887: . f     - The test field number
888: . g     - The trial field number
889: . part  - The equation part, or 0 if unused
890: . g0    - The `g0` Jacobian pointwise function to append; a `NULL` is ignored
891: . g1    - The `g1` Jacobian pointwise function to append; a `NULL` is ignored
892: . g2    - The `g2` Jacobian pointwise function to append; a `NULL` is ignored
893: - g3    - The `g3` Jacobian pointwise function to append; a `NULL` is ignored

895:   Level: intermediate

897: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormGetJacobian()`, `PetscWeakFormSetIndexJacobian()`
898: @*/
899: PetscErrorCode PetscWeakFormAddJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
900: {
901:   PetscInt find = f * wf->Nf + g;

903:   PetscFunctionBegin;
904:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, (PetscVoidFn *)g0));
905:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, (PetscVoidFn *)g1));
906:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, (PetscVoidFn *)g2));
907:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, (PetscVoidFn *)g3));
908:   PetscFunctionReturn(PETSC_SUCCESS);
909: }

911: /*@C
912:   PetscWeakFormSetJacobian - Set the lists of Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key in a `PetscWeakForm`

914:   Not Collective

916:   Input Parameters:
917: + wf    - The `PetscWeakForm`
918: . label - The label selecting the mesh region, or `NULL` for the entire domain
919: . val   - The label value selecting the mesh region
920: . f     - The test field number
921: . g     - The trial field number
922: . part  - The equation part, or 0 if unused
923: . n0    - The number of `g0` pointwise functions to set
924: . g0    - The array of `g0` Jacobian pointwise functions, or `NULL` to clear the key
925: . n1    - The number of `g1` pointwise functions to set
926: . g1    - The array of `g1` Jacobian pointwise functions, or `NULL` to clear the key
927: . n2    - The number of `g2` pointwise functions to set
928: . g2    - The array of `g2` Jacobian pointwise functions, or `NULL` to clear the key
929: . n3    - The number of `g3` pointwise functions to set
930: - g3    - The array of `g3` Jacobian pointwise functions, or `NULL` to clear the key

932:   Level: intermediate

934: .seealso: `PetscWeakForm`, `PetscWeakFormGetJacobian()`, `PetscWeakFormAddJacobian()`, `PetscWeakFormSetIndexJacobian()`, `PetscWeakFormSetJacobianPreconditioner()`
935: @*/
936: PetscErrorCode PetscWeakFormSetJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt n0, void (**g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n2, void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n3, void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
937: {
938:   PetscInt find = f * wf->Nf + g;

940:   PetscFunctionBegin;
941:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, n0, (PetscVoidFn **)g0));
942:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, n1, (PetscVoidFn **)g1));
943:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, n2, (PetscVoidFn **)g2));
944:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, n3, (PetscVoidFn **)g3));
945:   PetscFunctionReturn(PETSC_SUCCESS);
946: }

948: /*@C
949:   PetscWeakFormSetIndexJacobian - Set the Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` at the given indices for a given key in a `PetscWeakForm`

951:   Not Collective

953:   Input Parameters:
954: + wf    - The `PetscWeakForm`
955: . label - The label selecting the mesh region, or `NULL` for the entire domain
956: . val   - The label value selecting the mesh region
957: . f     - The test field number
958: . g     - The trial field number
959: . part  - The equation part, or 0 if unused
960: . i0    - The index at which to store `g0` in the `g0` list
961: . g0    - The `g0` Jacobian pointwise function; a `NULL` is ignored
962: . i1    - The index at which to store `g1` in the `g1` list
963: . g1    - The `g1` Jacobian pointwise function; a `NULL` is ignored
964: . i2    - The index at which to store `g2` in the `g2` list
965: . g2    - The `g2` Jacobian pointwise function; a `NULL` is ignored
966: . i3    - The index at which to store `g3` in the `g3` list
967: - g3    - The `g3` Jacobian pointwise function; a `NULL` is ignored

969:   Level: intermediate

971: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormAddJacobian()`, `PetscWeakFormGetJacobian()`, `PetscWeakFormClearIndex()`
972: @*/
973: PetscErrorCode PetscWeakFormSetIndexJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt i0, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i2, void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i3, void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
974: {
975:   PetscInt find = f * wf->Nf + g;

977:   PetscFunctionBegin;
978:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, i0, (PetscVoidFn *)g0));
979:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, i1, (PetscVoidFn *)g1));
980:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, i2, (PetscVoidFn *)g2));
981:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, i3, (PetscVoidFn *)g3));
982:   PetscFunctionReturn(PETSC_SUCCESS);
983: }

985: /*@
986:   PetscWeakFormHasJacobianPreconditioner - Returns whether the `PetscWeakForm` has any Jacobian preconditioner (`g0`, `g1`, `g2`, or `g3`) pointwise functions registered

988:   Not Collective

990:   Input Parameter:
991: . wf - The `PetscWeakForm`

993:   Output Parameter:
994: . hasJacPre - `PETSC_TRUE` if any Jacobian preconditioner pointwise functions are registered, `PETSC_FALSE` otherwise

996:   Level: intermediate

998: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormHasJacobian()`, `PetscWeakFormHasBdJacobianPreconditioner()`
999: @*/
1000: PetscErrorCode PetscWeakFormHasJacobianPreconditioner(PetscWeakForm wf, PetscBool *hasJacPre)
1001: {
1002:   PetscInt n0, n1, n2, n3;

1004:   PetscFunctionBegin;
1006:   PetscAssertPointer(hasJacPre, 2);
1007:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP0], &n0));
1008:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP1], &n1));
1009:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP2], &n2));
1010:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP3], &n3));
1011:   *hasJacPre = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1012:   PetscFunctionReturn(PETSC_SUCCESS);
1013: }

1015: /*@C
1016:   PetscWeakFormGetJacobianPreconditioner - Retrieve the lists of Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key from a `PetscWeakForm`

1018:   Not Collective

1020:   Input Parameters:
1021: + wf    - The `PetscWeakForm`
1022: . label - The label selecting the mesh region, or `NULL` for the entire domain
1023: . val   - The label value selecting the mesh region
1024: . f     - The test field number
1025: . g     - The trial field number
1026: - part  - The equation part, or 0 if unused

1028:   Output Parameters:
1029: + n0 - The number of `g0` pointwise functions registered for this key
1030: . g0 - The array of `g0` Jacobian preconditioner pointwise functions
1031: . n1 - The number of `g1` pointwise functions registered for this key
1032: . g1 - The array of `g1` Jacobian preconditioner pointwise functions
1033: . n2 - The number of `g2` pointwise functions registered for this key
1034: . g2 - The array of `g2` Jacobian preconditioner pointwise functions
1035: . n3 - The number of `g3` pointwise functions registered for this key
1036: - g3 - The array of `g3` Jacobian preconditioner pointwise functions

1038:   Level: intermediate

1040: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormAddJacobianPreconditioner()`, `PetscWeakFormHasJacobianPreconditioner()`, `PetscWeakFormGetJacobian()`
1041: @*/
1042: PetscErrorCode PetscWeakFormGetJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt *n0, void (***g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n2, void (***g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n3, void (***g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1043: {
1044:   PetscInt find = f * wf->Nf + g;

1046:   PetscFunctionBegin;
1047:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, n0, (void (***)(void))g0));
1048:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, n1, (void (***)(void))g1));
1049:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, n2, (void (***)(void))g2));
1050:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, n3, (void (***)(void))g3));
1051:   PetscFunctionReturn(PETSC_SUCCESS);
1052: }

1054: /*@C
1055:   PetscWeakFormAddJacobianPreconditioner - Append Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` to the lists for a given key in a `PetscWeakForm`

1057:   Not Collective

1059:   Input Parameters:
1060: + wf    - The `PetscWeakForm`
1061: . label - The label selecting the mesh region, or `NULL` for the entire domain
1062: . val   - The label value selecting the mesh region
1063: . f     - The test field number
1064: . g     - The trial field number
1065: . part  - The equation part, or 0 if unused
1066: . g0    - The `g0` Jacobian preconditioner pointwise function to append; a `NULL` is ignored
1067: . g1    - The `g1` Jacobian preconditioner pointwise function to append; a `NULL` is ignored
1068: . g2    - The `g2` Jacobian preconditioner pointwise function to append; a `NULL` is ignored
1069: - g3    - The `g3` Jacobian preconditioner pointwise function to append; a `NULL` is ignored

1071:   Level: intermediate

1073: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormAddJacobian()`
1074: @*/
1075: PetscErrorCode PetscWeakFormAddJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1076: {
1077:   PetscInt find = f * wf->Nf + g;

1079:   PetscFunctionBegin;
1080:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, (PetscVoidFn *)g0));
1081:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, (PetscVoidFn *)g1));
1082:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, (PetscVoidFn *)g2));
1083:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, (PetscVoidFn *)g3));
1084:   PetscFunctionReturn(PETSC_SUCCESS);
1085: }

1087: /*@C
1088:   PetscWeakFormSetJacobianPreconditioner - Set the lists of Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key in a `PetscWeakForm`

1090:   Not Collective

1092:   Input Parameters:
1093: + wf    - The `PetscWeakForm`
1094: . label - The label selecting the mesh region, or `NULL` for the entire domain
1095: . val   - The label value selecting the mesh region
1096: . f     - The test field number
1097: . g     - The trial field number
1098: . part  - The equation part, or 0 if unused
1099: . n0    - The number of `g0` pointwise functions to set
1100: . g0    - The array of `g0` Jacobian preconditioner pointwise functions, or `NULL` to clear the key
1101: . n1    - The number of `g1` pointwise functions to set
1102: . g1    - The array of `g1` Jacobian preconditioner pointwise functions, or `NULL` to clear the key
1103: . n2    - The number of `g2` pointwise functions to set
1104: . g2    - The array of `g2` Jacobian preconditioner pointwise functions, or `NULL` to clear the key
1105: . n3    - The number of `g3` pointwise functions to set
1106: - g3    - The array of `g3` Jacobian preconditioner pointwise functions, or `NULL` to clear the key

1108:   Level: intermediate

1110: .seealso: `PetscWeakForm`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormAddJacobianPreconditioner()`, `PetscWeakFormSetJacobian()`
1111: @*/
1112: PetscErrorCode PetscWeakFormSetJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt n0, void (**g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n2, void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n3, void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1113: {
1114:   PetscInt find = f * wf->Nf + g;

1116:   PetscFunctionBegin;
1117:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, n0, (PetscVoidFn **)g0));
1118:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, n1, (PetscVoidFn **)g1));
1119:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, n2, (PetscVoidFn **)g2));
1120:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, n3, (PetscVoidFn **)g3));
1121:   PetscFunctionReturn(PETSC_SUCCESS);
1122: }

1124: /*@C
1125:   PetscWeakFormSetIndexJacobianPreconditioner - Set the Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` at the given indices for a given key in a `PetscWeakForm`

1127:   Not Collective

1129:   Input Parameters:
1130: + wf    - The `PetscWeakForm`
1131: . label - The label selecting the mesh region, or `NULL` for the entire domain
1132: . val   - The label value selecting the mesh region
1133: . f     - The test field number
1134: . g     - The trial field number
1135: . part  - The equation part, or 0 if unused
1136: . i0    - The index at which to store `g0` in the `g0` list
1137: . g0    - The `g0` Jacobian preconditioner pointwise function; a `NULL` is ignored
1138: . i1    - The index at which to store `g1` in the `g1` list
1139: . g1    - The `g1` Jacobian preconditioner pointwise function; a `NULL` is ignored
1140: . i2    - The index at which to store `g2` in the `g2` list
1141: . g2    - The `g2` Jacobian preconditioner pointwise function; a `NULL` is ignored
1142: . i3    - The index at which to store `g3` in the `g3` list
1143: - g3    - The `g3` Jacobian preconditioner pointwise function; a `NULL` is ignored

1145:   Level: intermediate

1147: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormAddJacobianPreconditioner()`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormClearIndex()`
1148: @*/
1149: PetscErrorCode PetscWeakFormSetIndexJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt i0, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i2, void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i3, void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1150: {
1151:   PetscInt find = f * wf->Nf + g;

1153:   PetscFunctionBegin;
1154:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, i0, (PetscVoidFn *)g0));
1155:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, i1, (PetscVoidFn *)g1));
1156:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, i2, (PetscVoidFn *)g2));
1157:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, i3, (PetscVoidFn *)g3));
1158:   PetscFunctionReturn(PETSC_SUCCESS);
1159: }

1161: /*@
1162:   PetscWeakFormHasBdJacobian - Returns whether the `PetscWeakForm` has any boundary Jacobian (`g0`, `g1`, `g2`, or `g3`) pointwise functions registered

1164:   Not Collective

1166:   Input Parameter:
1167: . wf - The `PetscWeakForm`

1169:   Output Parameter:
1170: . hasJac - `PETSC_TRUE` if any boundary Jacobian pointwise functions are registered, `PETSC_FALSE` otherwise

1172:   Level: intermediate

1174: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormHasJacobian()`, `PetscWeakFormHasBdJacobianPreconditioner()`
1175: @*/
1176: PetscErrorCode PetscWeakFormHasBdJacobian(PetscWeakForm wf, PetscBool *hasJac)
1177: {
1178:   PetscInt n0, n1, n2, n3;

1180:   PetscFunctionBegin;
1182:   PetscAssertPointer(hasJac, 2);
1183:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG0], &n0));
1184:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG1], &n1));
1185:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG2], &n2));
1186:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG3], &n3));
1187:   *hasJac = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1188:   PetscFunctionReturn(PETSC_SUCCESS);
1189: }

1191: /*@C
1192:   PetscWeakFormGetBdJacobian - Retrieve the lists of boundary Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key from a `PetscWeakForm`

1194:   Not Collective

1196:   Input Parameters:
1197: + wf    - The `PetscWeakForm`
1198: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1199: . val   - The label value selecting the boundary region
1200: . f     - The test field number
1201: . g     - The trial field number
1202: - part  - The equation part, or 0 if unused

1204:   Output Parameters:
1205: + n0 - The number of `g0` boundary pointwise functions registered for this key
1206: . g0 - The array of `g0` boundary Jacobian pointwise functions
1207: . n1 - The number of `g1` boundary pointwise functions registered for this key
1208: . g1 - The array of `g1` boundary Jacobian pointwise functions
1209: . n2 - The number of `g2` boundary pointwise functions registered for this key
1210: . g2 - The array of `g2` boundary Jacobian pointwise functions
1211: . n3 - The number of `g3` boundary pointwise functions registered for this key
1212: - g3 - The array of `g3` boundary Jacobian pointwise functions

1214:   Level: intermediate

1216: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormAddBdJacobian()`, `PetscWeakFormHasBdJacobian()`, `PetscWeakFormGetJacobian()`
1217: @*/
1218: PetscErrorCode PetscWeakFormGetBdJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt *n0, void (***g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n2, void (***g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n3, void (***g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1219: {
1220:   PetscInt find = f * wf->Nf + g;

1222:   PetscFunctionBegin;
1223:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, n0, (void (***)(void))g0));
1224:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, n1, (void (***)(void))g1));
1225:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, n2, (void (***)(void))g2));
1226:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, n3, (void (***)(void))g3));
1227:   PetscFunctionReturn(PETSC_SUCCESS);
1228: }

1230: /*@C
1231:   PetscWeakFormAddBdJacobian - Append boundary Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` to the lists for a given key in a `PetscWeakForm`

1233:   Not Collective

1235:   Input Parameters:
1236: + wf    - The `PetscWeakForm`
1237: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1238: . val   - The label value selecting the boundary region
1239: . f     - The test field number
1240: . g     - The trial field number
1241: . part  - The equation part, or 0 if unused
1242: . g0    - The `g0` boundary Jacobian pointwise function to append; a `NULL` is ignored
1243: . g1    - The `g1` boundary Jacobian pointwise function to append; a `NULL` is ignored
1244: . g2    - The `g2` boundary Jacobian pointwise function to append; a `NULL` is ignored
1245: - g3    - The `g3` boundary Jacobian pointwise function to append; a `NULL` is ignored

1247:   Level: intermediate

1249: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormAddJacobian()`
1250: @*/
1251: PetscErrorCode PetscWeakFormAddBdJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1252: {
1253:   PetscInt find = f * wf->Nf + g;

1255:   PetscFunctionBegin;
1256:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, (PetscVoidFn *)g0));
1257:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, (PetscVoidFn *)g1));
1258:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, (PetscVoidFn *)g2));
1259:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, (PetscVoidFn *)g3));
1260:   PetscFunctionReturn(PETSC_SUCCESS);
1261: }

1263: /*@C
1264:   PetscWeakFormSetBdJacobian - Set the lists of boundary Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key in a `PetscWeakForm`

1266:   Not Collective

1268:   Input Parameters:
1269: + wf    - The `PetscWeakForm`
1270: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1271: . val   - The label value selecting the boundary region
1272: . f     - The test field number
1273: . g     - The trial field number
1274: . part  - The equation part, or 0 if unused
1275: . n0    - The number of `g0` boundary pointwise functions to set
1276: . g0    - The array of `g0` boundary Jacobian pointwise functions, or `NULL` to clear the key
1277: . n1    - The number of `g1` boundary pointwise functions to set
1278: . g1    - The array of `g1` boundary Jacobian pointwise functions, or `NULL` to clear the key
1279: . n2    - The number of `g2` boundary pointwise functions to set
1280: . g2    - The array of `g2` boundary Jacobian pointwise functions, or `NULL` to clear the key
1281: . n3    - The number of `g3` boundary pointwise functions to set
1282: - g3    - The array of `g3` boundary Jacobian pointwise functions, or `NULL` to clear the key

1284:   Level: intermediate

1286: .seealso: `PetscWeakForm`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormAddBdJacobian()`, `PetscWeakFormSetJacobian()`
1287: @*/
1288: PetscErrorCode PetscWeakFormSetBdJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt n0, void (**g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n2, void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n3, void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1289: {
1290:   PetscInt find = f * wf->Nf + g;

1292:   PetscFunctionBegin;
1293:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, n0, (PetscVoidFn **)g0));
1294:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, n1, (PetscVoidFn **)g1));
1295:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, n2, (PetscVoidFn **)g2));
1296:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, n3, (PetscVoidFn **)g3));
1297:   PetscFunctionReturn(PETSC_SUCCESS);
1298: }

1300: /*@C
1301:   PetscWeakFormSetIndexBdJacobian - Set the boundary Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` at the given indices for a given key in a `PetscWeakForm`

1303:   Not Collective

1305:   Input Parameters:
1306: + wf    - The `PetscWeakForm`
1307: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1308: . val   - The label value selecting the boundary region
1309: . f     - The test field number
1310: . g     - The trial field number
1311: . part  - The equation part, or 0 if unused
1312: . i0    - The index at which to store `g0` in the `g0` list
1313: . g0    - The `g0` boundary Jacobian pointwise function; a `NULL` is ignored
1314: . i1    - The index at which to store `g1` in the `g1` list
1315: . g1    - The `g1` boundary Jacobian pointwise function; a `NULL` is ignored
1316: . i2    - The index at which to store `g2` in the `g2` list
1317: . g2    - The `g2` boundary Jacobian pointwise function; a `NULL` is ignored
1318: . i3    - The index at which to store `g3` in the `g3` list
1319: - g3    - The `g3` boundary Jacobian pointwise function; a `NULL` is ignored

1321:   Level: intermediate

1323: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormAddBdJacobian()`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormClearIndex()`
1324: @*/
1325: PetscErrorCode PetscWeakFormSetIndexBdJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt i0, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i2, void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i3, void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1326: {
1327:   PetscInt find = f * wf->Nf + g;

1329:   PetscFunctionBegin;
1330:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, i0, (PetscVoidFn *)g0));
1331:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, i1, (PetscVoidFn *)g1));
1332:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, i2, (PetscVoidFn *)g2));
1333:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, i3, (PetscVoidFn *)g3));
1334:   PetscFunctionReturn(PETSC_SUCCESS);
1335: }

1337: /*@
1338:   PetscWeakFormHasBdJacobianPreconditioner - Returns whether the `PetscWeakForm` has any boundary Jacobian preconditioner (`g0`, `g1`, `g2`, or `g3`) pointwise functions registered

1340:   Not Collective

1342:   Input Parameter:
1343: . wf - The `PetscWeakForm`

1345:   Output Parameter:
1346: . hasJacPre - `PETSC_TRUE` if any boundary Jacobian preconditioner pointwise functions are registered, `PETSC_FALSE` otherwise

1348:   Level: intermediate

1350: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormHasBdJacobian()`, `PetscWeakFormHasJacobianPreconditioner()`
1351: @*/
1352: PetscErrorCode PetscWeakFormHasBdJacobianPreconditioner(PetscWeakForm wf, PetscBool *hasJacPre)
1353: {
1354:   PetscInt n0, n1, n2, n3;

1356:   PetscFunctionBegin;
1358:   PetscAssertPointer(hasJacPre, 2);
1359:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP0], &n0));
1360:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP1], &n1));
1361:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP2], &n2));
1362:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP3], &n3));
1363:   *hasJacPre = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1364:   PetscFunctionReturn(PETSC_SUCCESS);
1365: }

1367: /*@C
1368:   PetscWeakFormGetBdJacobianPreconditioner - Retrieve the lists of boundary Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key from a `PetscWeakForm`

1370:   Not Collective

1372:   Input Parameters:
1373: + wf    - The `PetscWeakForm`
1374: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1375: . val   - The label value selecting the boundary region
1376: . f     - The test field number
1377: . g     - The trial field number
1378: - part  - The equation part, or 0 if unused

1380:   Output Parameters:
1381: + n0 - The number of `g0` boundary pointwise functions registered for this key
1382: . g0 - The array of `g0` boundary Jacobian preconditioner pointwise functions
1383: . n1 - The number of `g1` boundary pointwise functions registered for this key
1384: . g1 - The array of `g1` boundary Jacobian preconditioner pointwise functions
1385: . n2 - The number of `g2` boundary pointwise functions registered for this key
1386: . g2 - The array of `g2` boundary Jacobian preconditioner pointwise functions
1387: . n3 - The number of `g3` boundary pointwise functions registered for this key
1388: - g3 - The array of `g3` boundary Jacobian preconditioner pointwise functions

1390:   Level: intermediate

1392: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobianPreconditioner()`, `PetscWeakFormHasBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobian()`
1393: @*/
1394: PetscErrorCode PetscWeakFormGetBdJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt *n0, void (***g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n2, void (***g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n3, void (***g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1395: {
1396:   PetscInt find = f * wf->Nf + g;

1398:   PetscFunctionBegin;
1399:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, n0, (void (***)(void))g0));
1400:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, n1, (void (***)(void))g1));
1401:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, n2, (void (***)(void))g2));
1402:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, n3, (void (***)(void))g3));
1403:   PetscFunctionReturn(PETSC_SUCCESS);
1404: }

1406: /*@C
1407:   PetscWeakFormAddBdJacobianPreconditioner - Append boundary Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` to the lists for a given key in a `PetscWeakForm`

1409:   Not Collective

1411:   Input Parameters:
1412: + wf    - The `PetscWeakForm`
1413: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1414: . val   - The label value selecting the boundary region
1415: . f     - The test field number
1416: . g     - The trial field number
1417: . part  - The equation part, or 0 if unused
1418: . g0    - The `g0` boundary Jacobian preconditioner pointwise function to append; a `NULL` is ignored
1419: . g1    - The `g1` boundary Jacobian preconditioner pointwise function to append; a `NULL` is ignored
1420: . g2    - The `g2` boundary Jacobian preconditioner pointwise function to append; a `NULL` is ignored
1421: - g3    - The `g3` boundary Jacobian preconditioner pointwise function to append; a `NULL` is ignored

1423:   Level: intermediate

1425: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobian()`
1426: @*/
1427: PetscErrorCode PetscWeakFormAddBdJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1428: {
1429:   PetscInt find = f * wf->Nf + g;

1431:   PetscFunctionBegin;
1432:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, (PetscVoidFn *)g0));
1433:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, (PetscVoidFn *)g1));
1434:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, (PetscVoidFn *)g2));
1435:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, (PetscVoidFn *)g3));
1436:   PetscFunctionReturn(PETSC_SUCCESS);
1437: }

1439: /*@C
1440:   PetscWeakFormSetBdJacobianPreconditioner - Set the lists of boundary Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key in a `PetscWeakForm`

1442:   Not Collective

1444:   Input Parameters:
1445: + wf    - The `PetscWeakForm`
1446: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1447: . val   - The label value selecting the boundary region
1448: . f     - The test field number
1449: . g     - The trial field number
1450: . part  - The equation part, or 0 if unused
1451: . n0    - The number of `g0` boundary pointwise functions to set
1452: . g0    - The array of `g0` boundary Jacobian preconditioner pointwise functions, or `NULL` to clear the key
1453: . n1    - The number of `g1` boundary pointwise functions to set
1454: . g1    - The array of `g1` boundary Jacobian preconditioner pointwise functions, or `NULL` to clear the key
1455: . n2    - The number of `g2` boundary pointwise functions to set
1456: . g2    - The array of `g2` boundary Jacobian preconditioner pointwise functions, or `NULL` to clear the key
1457: . n3    - The number of `g3` boundary pointwise functions to set
1458: - g3    - The array of `g3` boundary Jacobian preconditioner pointwise functions, or `NULL` to clear the key

1460:   Level: intermediate

1462: .seealso: `PetscWeakForm`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobianPreconditioner()`, `PetscWeakFormSetBdJacobian()`
1463: @*/
1464: PetscErrorCode PetscWeakFormSetBdJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt n0, void (**g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n2, void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n3, void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1465: {
1466:   PetscInt find = f * wf->Nf + g;

1468:   PetscFunctionBegin;
1469:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, n0, (PetscVoidFn **)g0));
1470:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, n1, (PetscVoidFn **)g1));
1471:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, n2, (PetscVoidFn **)g2));
1472:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, n3, (PetscVoidFn **)g3));
1473:   PetscFunctionReturn(PETSC_SUCCESS);
1474: }

1476: /*@C
1477:   PetscWeakFormSetIndexBdJacobianPreconditioner - Set the boundary Jacobian preconditioner pointwise functions `g0`, `g1`, `g2`, and `g3` at the given indices for a given key in a `PetscWeakForm`

1479:   Not Collective

1481:   Input Parameters:
1482: + wf    - The `PetscWeakForm`
1483: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1484: . val   - The label value selecting the boundary region
1485: . f     - The test field number
1486: . g     - The trial field number
1487: . part  - The equation part, or 0 if unused
1488: . i0    - The index at which to store `g0` in the `g0` list
1489: . g0    - The `g0` boundary Jacobian preconditioner pointwise function; a `NULL` is ignored
1490: . i1    - The index at which to store `g1` in the `g1` list
1491: . g1    - The `g1` boundary Jacobian preconditioner pointwise function; a `NULL` is ignored
1492: . i2    - The index at which to store `g2` in the `g2` list
1493: . g2    - The `g2` boundary Jacobian preconditioner pointwise function; a `NULL` is ignored
1494: . i3    - The index at which to store `g3` in the `g3` list
1495: - g3    - The `g3` boundary Jacobian preconditioner pointwise function; a `NULL` is ignored

1497:   Level: intermediate

1499: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormClearIndex()`
1500: @*/
1501: PetscErrorCode PetscWeakFormSetIndexBdJacobianPreconditioner(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt i0, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i2, void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i3, void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1502: {
1503:   PetscInt find = f * wf->Nf + g;

1505:   PetscFunctionBegin;
1506:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, i0, (PetscVoidFn *)g0));
1507:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, i1, (PetscVoidFn *)g1));
1508:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, i2, (PetscVoidFn *)g2));
1509:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, i3, (PetscVoidFn *)g3));
1510:   PetscFunctionReturn(PETSC_SUCCESS);
1511: }

1513: /*@
1514:   PetscWeakFormHasDynamicJacobian - Returns whether the `PetscWeakForm` has any dynamic Jacobian (`g0`, `g1`, `g2`, or `g3`) pointwise functions registered

1516:   Not Collective

1518:   Input Parameter:
1519: . wf - The `PetscWeakForm`

1521:   Output Parameter:
1522: . hasDynJac - `PETSC_TRUE` if any dynamic Jacobian pointwise functions are registered, `PETSC_FALSE` otherwise

1524:   Level: intermediate

1526:   Note:
1527:   The dynamic Jacobian is the Jacobian of the time-derivative term for transient problems.

1529: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormHasJacobian()`
1530: @*/
1531: PetscErrorCode PetscWeakFormHasDynamicJacobian(PetscWeakForm wf, PetscBool *hasDynJac)
1532: {
1533:   PetscInt n0, n1, n2, n3;

1535:   PetscFunctionBegin;
1537:   PetscAssertPointer(hasDynJac, 2);
1538:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT0], &n0));
1539:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT1], &n1));
1540:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT2], &n2));
1541:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT3], &n3));
1542:   *hasDynJac = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1543:   PetscFunctionReturn(PETSC_SUCCESS);
1544: }

1546: /*@C
1547:   PetscWeakFormGetDynamicJacobian - Retrieve the lists of dynamic Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key from a `PetscWeakForm`

1549:   Not Collective

1551:   Input Parameters:
1552: + wf    - The `PetscWeakForm`
1553: . label - The label selecting the mesh region, or `NULL` for the entire domain
1554: . val   - The label value selecting the mesh region
1555: . f     - The test field number
1556: . g     - The trial field number
1557: - part  - The equation part, or 0 if unused

1559:   Output Parameters:
1560: + n0 - The number of `g0` pointwise functions registered for this key
1561: . g0 - The array of `g0` dynamic Jacobian pointwise functions
1562: . n1 - The number of `g1` pointwise functions registered for this key
1563: . g1 - The array of `g1` dynamic Jacobian pointwise functions
1564: . n2 - The number of `g2` pointwise functions registered for this key
1565: . g2 - The array of `g2` dynamic Jacobian pointwise functions
1566: . n3 - The number of `g3` pointwise functions registered for this key
1567: - g3 - The array of `g3` dynamic Jacobian pointwise functions

1569:   Level: intermediate

1571: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormAddDynamicJacobian()`, `PetscWeakFormHasDynamicJacobian()`, `PetscWeakFormGetJacobian()`
1572: @*/
1573: PetscErrorCode PetscWeakFormGetDynamicJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt *n0, void (***g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n1, void (***g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n2, void (***g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt *n3, void (***g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1574: {
1575:   PetscInt find = f * wf->Nf + g;

1577:   PetscFunctionBegin;
1578:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, n0, (void (***)(void))g0));
1579:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, n1, (void (***)(void))g1));
1580:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, n2, (void (***)(void))g2));
1581:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, n3, (void (***)(void))g3));
1582:   PetscFunctionReturn(PETSC_SUCCESS);
1583: }

1585: /*@C
1586:   PetscWeakFormAddDynamicJacobian - Append dynamic Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` to the lists for a given key in a `PetscWeakForm`

1588:   Not Collective

1590:   Input Parameters:
1591: + wf    - The `PetscWeakForm`
1592: . label - The label selecting the mesh region, or `NULL` for the entire domain
1593: . val   - The label value selecting the mesh region
1594: . f     - The test field number
1595: . g     - The trial field number
1596: . part  - The equation part, or 0 if unused
1597: . g0    - The `g0` dynamic Jacobian pointwise function to append; a `NULL` is ignored
1598: . g1    - The `g1` dynamic Jacobian pointwise function to append; a `NULL` is ignored
1599: . g2    - The `g2` dynamic Jacobian pointwise function to append; a `NULL` is ignored
1600: - g3    - The `g3` dynamic Jacobian pointwise function to append; a `NULL` is ignored

1602:   Level: intermediate

1604: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormAddJacobian()`
1605: @*/
1606: PetscErrorCode PetscWeakFormAddDynamicJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1607: {
1608:   PetscInt find = f * wf->Nf + g;

1610:   PetscFunctionBegin;
1611:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, (PetscVoidFn *)g0));
1612:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, (PetscVoidFn *)g1));
1613:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, (PetscVoidFn *)g2));
1614:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, (PetscVoidFn *)g3));
1615:   PetscFunctionReturn(PETSC_SUCCESS);
1616: }

1618: /*@C
1619:   PetscWeakFormSetDynamicJacobian - Set the lists of dynamic Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` for a given key in a `PetscWeakForm`

1621:   Not Collective

1623:   Input Parameters:
1624: + wf    - The `PetscWeakForm`
1625: . label - The label selecting the mesh region, or `NULL` for the entire domain
1626: . val   - The label value selecting the mesh region
1627: . f     - The test field number
1628: . g     - The trial field number
1629: . part  - The equation part, or 0 if unused
1630: . n0    - The number of `g0` pointwise functions to set
1631: . g0    - The array of `g0` dynamic Jacobian pointwise functions, or `NULL` to clear the key
1632: . n1    - The number of `g1` pointwise functions to set
1633: . g1    - The array of `g1` dynamic Jacobian pointwise functions, or `NULL` to clear the key
1634: . n2    - The number of `g2` pointwise functions to set
1635: . g2    - The array of `g2` dynamic Jacobian pointwise functions, or `NULL` to clear the key
1636: . n3    - The number of `g3` pointwise functions to set
1637: - g3    - The array of `g3` dynamic Jacobian pointwise functions, or `NULL` to clear the key

1639:   Level: intermediate

1641: .seealso: `PetscWeakForm`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormAddDynamicJacobian()`, `PetscWeakFormSetJacobian()`
1642: @*/
1643: PetscErrorCode PetscWeakFormSetDynamicJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt n0, void (**g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n1, void (**g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n2, void (**g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt n3, void (**g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1644: {
1645:   PetscInt find = f * wf->Nf + g;

1647:   PetscFunctionBegin;
1648:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, n0, (PetscVoidFn **)g0));
1649:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, n1, (PetscVoidFn **)g1));
1650:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, n2, (PetscVoidFn **)g2));
1651:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, n3, (PetscVoidFn **)g3));
1652:   PetscFunctionReturn(PETSC_SUCCESS);
1653: }

1655: /*@C
1656:   PetscWeakFormSetIndexDynamicJacobian - Set the dynamic Jacobian pointwise functions `g0`, `g1`, `g2`, and `g3` at the given indices for a given key in a `PetscWeakForm`

1658:   Not Collective

1660:   Input Parameters:
1661: + wf    - The `PetscWeakForm`
1662: . label - The label selecting the mesh region, or `NULL` for the entire domain
1663: . val   - The label value selecting the mesh region
1664: . f     - The test field number
1665: . g     - The trial field number
1666: . part  - The equation part, or 0 if unused
1667: . i0    - The index at which to store `g0` in the `g0` list
1668: . g0    - The `g0` dynamic Jacobian pointwise function; a `NULL` is ignored
1669: . i1    - The index at which to store `g1` in the `g1` list
1670: . g1    - The `g1` dynamic Jacobian pointwise function; a `NULL` is ignored
1671: . i2    - The index at which to store `g2` in the `g2` list
1672: . g2    - The `g2` dynamic Jacobian pointwise function; a `NULL` is ignored
1673: . i3    - The index at which to store `g3` in the `g3` list
1674: - g3    - The `g3` dynamic Jacobian pointwise function; a `NULL` is ignored

1676:   Level: intermediate

1678: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormAddDynamicJacobian()`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormClearIndex()`
1679: @*/
1680: PetscErrorCode PetscWeakFormSetIndexDynamicJacobian(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt g, PetscInt part, PetscInt i0, void (*g0)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i1, void (*g1)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i2, void (*g2)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]), PetscInt i3, void (*g3)(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]))
1681: {
1682:   PetscInt find = f * wf->Nf + g;

1684:   PetscFunctionBegin;
1685:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, i0, (PetscVoidFn *)g0));
1686:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, i1, (PetscVoidFn *)g1));
1687:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, i2, (PetscVoidFn *)g2));
1688:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, i3, (PetscVoidFn *)g3));
1689:   PetscFunctionReturn(PETSC_SUCCESS);
1690: }

1692: /*@C
1693:   PetscWeakFormGetRiemannSolver - Retrieve the list of Riemann solver pointwise functions for a given key from a `PetscWeakForm`

1695:   Not Collective

1697:   Input Parameters:
1698: + wf    - The `PetscWeakForm`
1699: . label - The label selecting the mesh region, or `NULL` for the entire domain
1700: . val   - The label value selecting the mesh region
1701: . f     - The field number
1702: - part  - The equation part, or 0 if unused

1704:   Output Parameters:
1705: + n - The number of Riemann solver pointwise functions registered for this key
1706: - r - The array of Riemann solver pointwise functions

1708:   Level: intermediate

1710: .seealso: `PetscWeakForm`, `PetscWeakFormSetRiemannSolver()`, `PetscWeakFormSetIndexRiemannSolver()`
1711: @*/
1712: PetscErrorCode PetscWeakFormGetRiemannSolver(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt *n, void (***r)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *))
1713: {
1714:   PetscFunctionBegin;
1715:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_R], label, val, f, part, n, (void (***)(void))r));
1716:   PetscFunctionReturn(PETSC_SUCCESS);
1717: }

1719: /*@C
1720:   PetscWeakFormSetRiemannSolver - Set the list of Riemann solver pointwise functions for a given key in a `PetscWeakForm`

1722:   Not Collective

1724:   Input Parameters:
1725: + wf    - The `PetscWeakForm`
1726: . label - The label selecting the mesh region, or `NULL` for the entire domain
1727: . val   - The label value selecting the mesh region
1728: . f     - The field number
1729: . part  - The equation part, or 0 if unused
1730: . n     - The number of Riemann solver pointwise functions to set
1731: - r     - The array of Riemann solver pointwise functions, or `NULL` to clear the key

1733:   Level: intermediate

1735: .seealso: `PetscWeakForm`, `PetscWeakFormGetRiemannSolver()`, `PetscWeakFormSetIndexRiemannSolver()`
1736: @*/
1737: PetscErrorCode PetscWeakFormSetRiemannSolver(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt n, void (**r)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *))
1738: {
1739:   PetscFunctionBegin;
1740:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_R], label, val, f, part, n, (PetscVoidFn **)r));
1741:   PetscFunctionReturn(PETSC_SUCCESS);
1742: }

1744: /*@C
1745:   PetscWeakFormSetIndexRiemannSolver - Set a single Riemann solver pointwise function at the given index for a given key in a `PetscWeakForm`

1747:   Not Collective

1749:   Input Parameters:
1750: + wf    - The `PetscWeakForm`
1751: . label - The label selecting the mesh region, or `NULL` for the entire domain
1752: . val   - The label value selecting the mesh region
1753: . f     - The field number
1754: . part  - The equation part, or 0 if unused
1755: . i     - The index into the list of Riemann solver pointwise functions for this key
1756: - r     - The Riemann solver pointwise function to store at position `i`; a `NULL` is ignored

1758:   Level: intermediate

1760: .seealso: `PetscWeakForm`, `PetscWeakFormSetRiemannSolver()`, `PetscWeakFormGetRiemannSolver()`, `PetscWeakFormClearIndex()`
1761: @*/
1762: PetscErrorCode PetscWeakFormSetIndexRiemannSolver(PetscWeakForm wf, DMLabel label, PetscInt val, PetscInt f, PetscInt part, PetscInt i, void (*r)(PetscInt, PetscInt, const PetscReal[], const PetscReal[], const PetscScalar[], const PetscScalar[], PetscInt, const PetscScalar[], PetscScalar[], void *))
1763: {
1764:   PetscFunctionBegin;
1765:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_R], label, val, f, part, i, (PetscVoidFn *)r));
1766:   PetscFunctionReturn(PETSC_SUCCESS);
1767: }

1769: /*@
1770:   PetscWeakFormGetNumFields - Returns the number of fields in a `PetscWeakForm`

1772:   Not Collective

1774:   Input Parameter:
1775: . wf - The `PetscWeakForm` object

1777:   Output Parameter:
1778: . Nf - The number of fields

1780:   Level: beginner

1782: .seealso: `PetscWeakForm`, `PetscWeakFormSetNumFields()`, `PetscWeakFormCreate()`
1783: @*/
1784: PetscErrorCode PetscWeakFormGetNumFields(PetscWeakForm wf, PetscInt *Nf)
1785: {
1786:   PetscFunctionBegin;
1788:   PetscAssertPointer(Nf, 2);
1789:   *Nf = wf->Nf;
1790:   PetscFunctionReturn(PETSC_SUCCESS);
1791: }

1793: /*@
1794:   PetscWeakFormSetNumFields - Sets the number of fields

1796:   Not Collective

1798:   Input Parameters:
1799: + wf - The `PetscWeakForm` object
1800: - Nf - The number of fields

1802:   Level: beginner

1804: .seealso: `PetscWeakForm`, `PetscWeakFormGetNumFields()`, `PetscWeakFormCreate()`
1805: @*/
1806: PetscErrorCode PetscWeakFormSetNumFields(PetscWeakForm wf, PetscInt Nf)
1807: {
1808:   PetscFunctionBegin;
1810:   wf->Nf = Nf;
1811:   PetscFunctionReturn(PETSC_SUCCESS);
1812: }

1814: /*@
1815:   PetscWeakFormDestroy - Destroys a `PetscWeakForm` object

1817:   Collective

1819:   Input Parameter:
1820: . wf - the `PetscWeakForm` object to destroy

1822:   Level: developer

1824: .seealso: `PetscWeakForm`, `PetscWeakFormCreate()`, `PetscWeakFormView()`
1825: @*/
1826: PetscErrorCode PetscWeakFormDestroy(PetscWeakForm *wf)
1827: {
1828:   PetscInt f;

1830:   PetscFunctionBegin;
1831:   if (!*wf) PetscFunctionReturn(PETSC_SUCCESS);

1834:   if (--((PetscObject)*wf)->refct > 0) {
1835:     *wf = NULL;
1836:     PetscFunctionReturn(PETSC_SUCCESS);
1837:   }
1838:   ((PetscObject)*wf)->refct = 0;
1839:   PetscCall(PetscChunkBufferDestroy(&(*wf)->funcs));
1840:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscHMapFormDestroy(&(*wf)->form[f]));
1841:   PetscCall(PetscFree((*wf)->form));
1842:   PetscCall(PetscHeaderDestroy(wf));
1843:   PetscFunctionReturn(PETSC_SUCCESS);
1844: }

1846: static PetscErrorCode PetscWeakFormViewTable_Ascii(PetscWeakForm wf, PetscViewer viewer, PetscBool splitField, const char tableName[], PetscHMapForm map)
1847: {
1848:   PetscInt Nf = wf->Nf, Nk, k;

1850:   PetscFunctionBegin;
1851:   PetscCall(PetscHMapFormGetSize(map, &Nk));
1852:   if (Nk) {
1853:     PetscFormKey *keys;
1854:     PetscVoidFn **funcs = NULL;
1855:     const char  **names;
1856:     PetscInt     *values, *idx1, *idx2, *idx;
1857:     PetscBool     showPart = PETSC_FALSE, showPointer = PETSC_FALSE;
1858:     PetscInt      off = 0;

1860:     PetscCall(PetscMalloc6(Nk, &keys, Nk, &names, Nk, &values, Nk, &idx1, Nk, &idx2, Nk, &idx));
1861:     PetscCall(PetscHMapFormGetKeys(map, &off, keys));
1862:     /* Sort keys by label name and value */
1863:     {
1864:       /* First sort values */
1865:       for (k = 0; k < Nk; ++k) {
1866:         values[k] = keys[k].value;
1867:         idx1[k]   = k;
1868:       }
1869:       PetscCall(PetscSortIntWithPermutation(Nk, values, idx1));
1870:       /* If the string sort is stable, it will be sorted correctly overall */
1871:       for (k = 0; k < Nk; ++k) {
1872:         if (keys[idx1[k]].label) PetscCall(PetscObjectGetName((PetscObject)keys[idx1[k]].label, &names[k]));
1873:         else names[k] = "";
1874:         idx2[k] = k;
1875:       }
1876:       PetscCall(PetscSortStrWithPermutation(Nk, names, idx2));
1877:       for (k = 0; k < Nk; ++k) {
1878:         if (keys[k].label) PetscCall(PetscObjectGetName((PetscObject)keys[k].label, &names[k]));
1879:         else names[k] = "";
1880:         idx[k] = idx1[idx2[k]];
1881:       }
1882:     }
1883:     PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", tableName));
1884:     PetscCall(PetscViewerASCIIPushTab(viewer));
1885:     for (k = 0; k < Nk; ++k) {
1886:       if (keys[k].part != 0) showPart = PETSC_TRUE;
1887:     }
1888:     for (k = 0; k < Nk; ++k) {
1889:       const PetscInt i = idx[k];
1890:       PetscInt       n, f;

1892:       if (keys[i].label) {
1893:         if (showPointer) PetscCall(PetscViewerASCIIPrintf(viewer, "(%s:%p, %" PetscInt_FMT ") ", names[i], (void *)keys[i].label, keys[i].value));
1894:         else PetscCall(PetscViewerASCIIPrintf(viewer, "(%s, %" PetscInt_FMT ") ", names[i], keys[i].value));
1895:       }
1896:       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1897:       if (splitField) PetscCall(PetscViewerASCIIPrintf(viewer, "(%" PetscInt_FMT ", %" PetscInt_FMT ") ", keys[i].field / Nf, keys[i].field % Nf));
1898:       else PetscCall(PetscViewerASCIIPrintf(viewer, "(%" PetscInt_FMT ") ", keys[i].field));
1899:       if (showPart) PetscCall(PetscViewerASCIIPrintf(viewer, "(%" PetscInt_FMT ") ", keys[i].part));
1900:       PetscCall(PetscWeakFormGetFunction_Private(wf, map, keys[i].label, keys[i].value, keys[i].field, keys[i].part, &n, &funcs));
1901:       for (f = 0; f < n; ++f) {
1902:         char  *fname;
1903:         size_t len, l;

1905:         if (f > 0) PetscCall(PetscViewerASCIIPrintf(viewer, ", "));
1906:         PetscCall(PetscDLAddr(funcs[f], &fname));
1907:         if (fname) {
1908:           /* Eliminate argument types */
1909:           PetscCall(PetscStrlen(fname, &len));
1910:           for (l = 0; l < len; ++l)
1911:             if (fname[l] == '(') {
1912:               fname[l] = '\0';
1913:               break;
1914:             }
1915:           PetscCall(PetscViewerASCIIPrintf(viewer, "%s", fname));
1916:         } else if (showPointer) {
1917: #if defined(__clang__)
1918:           PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat-pedantic")
1919: #elif defined(__GNUC__) || defined(__GNUG__)
1920:           PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN("-Wformat")
1921: #endif
1922:           PetscCall(PetscViewerASCIIPrintf(viewer, "%p", funcs[f]));
1923:           PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END()
1924:         }
1925:         PetscCall(PetscFree(fname));
1926:       }
1927:       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1928:       PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1929:     }
1930:     PetscCall(PetscViewerASCIIPopTab(viewer));
1931:     PetscCall(PetscFree6(keys, names, values, idx1, idx2, idx));
1932:   }
1933:   PetscFunctionReturn(PETSC_SUCCESS);
1934: }

1936: static PetscErrorCode PetscWeakFormView_Ascii(PetscWeakForm wf, PetscViewer viewer)
1937: {
1938:   PetscViewerFormat format;
1939:   PetscInt          f;

1941:   PetscFunctionBegin;
1942:   PetscCall(PetscViewerGetFormat(viewer, &format));
1943:   PetscCall(PetscViewerASCIIPrintf(viewer, "Weak Form System with %" PetscInt_FMT " fields\n", wf->Nf));
1944:   PetscCall(PetscViewerASCIIPushTab(viewer));
1945:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscWeakFormViewTable_Ascii(wf, viewer, PETSC_TRUE, PetscWeakFormKinds[f], wf->form[f]));
1946:   PetscCall(PetscViewerASCIIPopTab(viewer));
1947:   PetscFunctionReturn(PETSC_SUCCESS);
1948: }

1950: /*@
1951:   PetscWeakFormView - Views a `PetscWeakForm`

1953:   Collective

1955:   Input Parameters:
1956: + wf - the `PetscWeakForm` object to view
1957: - v  - the viewer

1959:   Level: developer

1961: .seealso: `PetscViewer`, `PetscWeakForm`, `PetscWeakFormDestroy()`, `PetscWeakFormCreate()`
1962: @*/
1963: PetscErrorCode PetscWeakFormView(PetscWeakForm wf, PetscViewer v)
1964: {
1965:   PetscBool isascii;

1967:   PetscFunctionBegin;
1969:   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)wf), &v));
1971:   PetscCall(PetscObjectTypeCompare((PetscObject)v, PETSCVIEWERASCII, &isascii));
1972:   if (isascii) PetscCall(PetscWeakFormView_Ascii(wf, v));
1973:   PetscTryTypeMethod(wf, view, v);
1974:   PetscFunctionReturn(PETSC_SUCCESS);
1975: }

1977: /*@
1978:   PetscWeakFormCreate - Creates an empty `PetscWeakForm` object.

1980:   Collective

1982:   Input Parameter:
1983: . comm - The communicator for the `PetscWeakForm` object

1985:   Output Parameter:
1986: . wf - The `PetscWeakForm` object

1988:   Level: beginner

1990: .seealso: `PetscWeakForm`, `PetscDS`, `PetscWeakFormDestroy()`
1991: @*/
1992: PetscErrorCode PetscWeakFormCreate(MPI_Comm comm, PetscWeakForm *wf)
1993: {
1994:   PetscWeakForm p;
1995:   PetscInt      f;

1997:   PetscFunctionBegin;
1998:   PetscAssertPointer(wf, 2);
1999:   PetscCall(PetscDSInitializePackage());

2001:   PetscCall(PetscHeaderCreate(p, PETSCWEAKFORM_CLASSID, "PetscWeakForm", "Weak Form System", "PetscWeakForm", comm, PetscWeakFormDestroy, PetscWeakFormView));
2002:   p->Nf = 0;
2003:   PetscCall(PetscChunkBufferCreate(sizeof(&PetscWeakFormCreate), 2, &p->funcs));
2004:   PetscCall(PetscMalloc1(PETSC_NUM_WF, &p->form));
2005:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscHMapFormCreate(&p->form[f]));
2006:   *wf = p;
2007:   PetscFunctionReturn(PETSC_SUCCESS);
2008: }