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;

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

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

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

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

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

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

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

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

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

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

239:   Not Collective

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

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

247:   Level: intermediate

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

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

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

269:   Not Collective

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

274:   Level: intermediate

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

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

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

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

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

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

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

331:   Not Collective

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

339:   Level: intermediate

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

344: .seealso: `PetscWeakForm`, `DMLabel`, `PetscWeakFormReplaceLabel()`, `PetscWeakFormCreate()`, `PetscWeakFormDestroy()`
345: @*/
346: PetscErrorCode PetscWeakFormRewriteKeys(PetscWeakForm wf, DMLabel label, PetscInt Nv, const PetscInt values[])
347: {
348:   PetscFunctionBegin;
349:   for (PetscInt f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscWeakFormRewriteKeys_Internal(wf, wf->form[f], label, Nv, values));
350:   PetscFunctionReturn(PETSC_SUCCESS);
351: }

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

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

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

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

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

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

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

407:   Not Collective

409:   Input Parameters:
410: + wf    - The original `PetscWeakForm`
411: - label - The label to change keys for

413:   Level: intermediate

415:   Note:
416:   This is used internally when meshes are modified

418: .seealso: `PetscWeakForm`, `DMLabel`, `PetscWeakFormRewriteKeys()`, `PetscWeakFormCreate()`, `PetscWeakFormDestroy()`
419: @*/
420: PetscErrorCode PetscWeakFormReplaceLabel(PetscWeakForm wf, DMLabel label)
421: {
422:   PetscFunctionBegin;
423:   for (PetscInt f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscWeakFormReplaceLabel_Internal(wf, wf->form[f], label));
424:   PetscFunctionReturn(PETSC_SUCCESS);
425: }

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

430:   Not Collective

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

441:   Level: intermediate

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

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

455:   Not Collective

457:   Input Parameters:
458: + wf    - The `PetscWeakForm`
459: . label - The label selecting the mesh region, or `NULL` for the entire domain
460: . val   - The label value selecting the mesh region
461: . f     - The field number
462: - part  - The equation part, or 0 if unused

464:   Output Parameters:
465: + n   - The number of objective pointwise functions registered for this key
466: - obj - The array of objective pointwise functions

468:   Level: intermediate

470: .seealso: `PetscWeakForm`, `PetscWeakFormSetObjective()`, `PetscWeakFormAddObjective()`, `PetscWeakFormSetIndexObjective()`, `PetscWeakFormGetIndexObjective()`
471: @*/
472: 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[]))
473: {
474:   PetscFunctionBegin;
475:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, n, (void (***)(void))obj));
476:   PetscFunctionReturn(PETSC_SUCCESS);
477: }

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

482:   Not Collective

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

493:   Level: intermediate

495: .seealso: `PetscWeakForm`, `PetscWeakFormGetObjective()`, `PetscWeakFormAddObjective()`, `PetscWeakFormSetIndexObjective()`
496: @*/
497: 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[]))
498: {
499:   PetscFunctionBegin;
500:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, n, (PetscVoidFn **)obj));
501:   PetscFunctionReturn(PETSC_SUCCESS);
502: }

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

507:   Not Collective

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

517:   Level: intermediate

519: .seealso: `PetscWeakForm`, `PetscWeakFormSetObjective()`, `PetscWeakFormGetObjective()`, `PetscWeakFormSetIndexObjective()`
520: @*/
521: 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[]))
522: {
523:   PetscFunctionBegin;
524:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, (PetscVoidFn *)obj));
525:   PetscFunctionReturn(PETSC_SUCCESS);
526: }

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

531:   Not Collective

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

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

544:   Level: intermediate

546: .seealso: `PetscWeakForm`, `PetscWeakFormSetIndexObjective()`, `PetscWeakFormGetObjective()`, `PetscWeakFormSetObjective()`, `PetscWeakFormAddObjective()`
547: @*/
548: 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[]))
549: {
550:   PetscFunctionBegin;
551:   PetscCall(PetscWeakFormGetIndexFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, ind, (PetscVoidFn **)obj));
552:   PetscFunctionReturn(PETSC_SUCCESS);
553: }

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

558:   Not Collective

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

569:   Level: intermediate

571: .seealso: `PetscWeakForm`, `PetscWeakFormGetIndexObjective()`, `PetscWeakFormSetObjective()`, `PetscWeakFormAddObjective()`, `PetscWeakFormClearIndex()`
572: @*/
573: 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[]))
574: {
575:   PetscFunctionBegin;
576:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_OBJECTIVE], label, val, f, part, ind, (PetscVoidFn *)obj));
577:   PetscFunctionReturn(PETSC_SUCCESS);
578: }

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

583:   Not Collective

585:   Input Parameters:
586: + wf    - The `PetscWeakForm`
587: . label - The label selecting the mesh region, or `NULL` for the entire domain
588: . val   - The label value selecting the mesh region
589: . f     - The field number
590: - part  - The equation part, or 0 if unused

592:   Output Parameters:
593: + n0 - The number of `f0` pointwise functions registered for this key
594: . f0 - The array of `f0` residual pointwise functions
595: . n1 - The number of `f1` pointwise functions registered for this key
596: - f1 - The array of `f1` residual pointwise functions

598:   Level: intermediate

600: .seealso: `PetscWeakForm`, `PetscWeakFormSetResidual()`, `PetscWeakFormAddResidual()`, `PetscWeakFormGetBdResidual()`
601: @*/
602: 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[]))
603: {
604:   PetscFunctionBegin;
605:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, n0, (void (***)(void))f0));
606:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, n1, (void (***)(void))f1));
607:   PetscFunctionReturn(PETSC_SUCCESS);
608: }

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

613:   Not Collective

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

624:   Level: intermediate

626: .seealso: `PetscWeakForm`, `PetscWeakFormSetResidual()`, `PetscWeakFormGetResidual()`, `PetscWeakFormSetIndexResidual()`, `PetscWeakFormAddBdResidual()`
627: @*/
628: 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[]))
629: {
630:   PetscFunctionBegin;
631:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, (PetscVoidFn *)f0));
632:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, (PetscVoidFn *)f1));
633:   PetscFunctionReturn(PETSC_SUCCESS);
634: }

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

639:   Not Collective

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

652:   Level: intermediate

654: .seealso: `PetscWeakForm`, `PetscWeakFormGetResidual()`, `PetscWeakFormAddResidual()`, `PetscWeakFormSetIndexResidual()`
655: @*/
656: 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[]))
657: {
658:   PetscFunctionBegin;
659:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, n0, (PetscVoidFn **)f0));
660:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, n1, (PetscVoidFn **)f1));
661:   PetscFunctionReturn(PETSC_SUCCESS);
662: }

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

667:   Not Collective

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

680:   Level: intermediate

682: .seealso: `PetscWeakForm`, `PetscWeakFormSetResidual()`, `PetscWeakFormAddResidual()`, `PetscWeakFormGetResidual()`, `PetscWeakFormClearIndex()`
683: @*/
684: 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[]))
685: {
686:   PetscFunctionBegin;
687:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_F0], label, val, f, part, i0, (PetscVoidFn *)f0));
688:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_F1], label, val, f, part, i1, (PetscVoidFn *)f1));
689:   PetscFunctionReturn(PETSC_SUCCESS);
690: }

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

695:   Not Collective

697:   Input Parameters:
698: + wf    - The `PetscWeakForm`
699: . label - The label selecting the boundary region, or `NULL` for the entire boundary
700: . val   - The label value selecting the boundary region
701: . f     - The field number
702: - part  - The equation part, or 0 if unused

704:   Output Parameters:
705: + n0 - The number of `f0` boundary pointwise functions registered for this key
706: . f0 - The array of `f0` boundary residual pointwise functions
707: . n1 - The number of `f1` boundary pointwise functions registered for this key
708: - f1 - The array of `f1` boundary residual pointwise functions

710:   Level: intermediate

712: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdResidual()`, `PetscWeakFormAddBdResidual()`, `PetscWeakFormGetResidual()`
713: @*/
714: 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[]))
715: {
716:   PetscFunctionBegin;
717:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, n0, (void (***)(void))f0));
718:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, n1, (void (***)(void))f1));
719:   PetscFunctionReturn(PETSC_SUCCESS);
720: }

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

725:   Not Collective

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

736:   Level: intermediate

738: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdResidual()`, `PetscWeakFormGetBdResidual()`, `PetscWeakFormAddResidual()`
739: @*/
740: 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[]))
741: {
742:   PetscFunctionBegin;
743:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, (PetscVoidFn *)f0));
744:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, (PetscVoidFn *)f1));
745:   PetscFunctionReturn(PETSC_SUCCESS);
746: }

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

751:   Not Collective

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

764:   Level: intermediate

766: .seealso: `PetscWeakForm`, `PetscWeakFormGetBdResidual()`, `PetscWeakFormAddBdResidual()`, `PetscWeakFormSetResidual()`
767: @*/
768: 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[]))
769: {
770:   PetscFunctionBegin;
771:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, n0, (PetscVoidFn **)f0));
772:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, n1, (PetscVoidFn **)f1));
773:   PetscFunctionReturn(PETSC_SUCCESS);
774: }

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

779:   Not Collective

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

792:   Level: intermediate

794: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdResidual()`, `PetscWeakFormAddBdResidual()`, `PetscWeakFormGetBdResidual()`, `PetscWeakFormClearIndex()`
795: @*/
796: 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[]))
797: {
798:   PetscFunctionBegin;
799:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDF0], label, val, f, part, i0, (PetscVoidFn *)f0));
800:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDF1], label, val, f, part, i1, (PetscVoidFn *)f1));
801:   PetscFunctionReturn(PETSC_SUCCESS);
802: }

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

807:   Not Collective

809:   Input Parameter:
810: . wf - The `PetscWeakForm`

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

815:   Level: intermediate

817: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormGetJacobian()`, `PetscWeakFormHasJacobianPreconditioner()`, `PetscWeakFormHasBdJacobian()`
818: @*/
819: PetscErrorCode PetscWeakFormHasJacobian(PetscWeakForm wf, PetscBool *hasJac)
820: {
821:   PetscInt n0, n1, n2, n3;

823:   PetscFunctionBegin;
825:   PetscAssertPointer(hasJac, 2);
826:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G0], &n0));
827:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G1], &n1));
828:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G2], &n2));
829:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_G3], &n3));
830:   *hasJac = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
831:   PetscFunctionReturn(PETSC_SUCCESS);
832: }

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

837:   Not Collective

839:   Input Parameters:
840: + wf    - The `PetscWeakForm`
841: . label - The label selecting the mesh region, or `NULL` for the entire domain
842: . val   - The label value selecting the mesh region
843: . f     - The test field number
844: . g     - The trial field number
845: - part  - The equation part, or 0 if unused

847:   Output Parameters:
848: + n0 - The number of `g0` pointwise functions registered for this key
849: . g0 - The array of `g0` Jacobian pointwise functions
850: . n1 - The number of `g1` pointwise functions registered for this key
851: . g1 - The array of `g1` Jacobian pointwise functions
852: . n2 - The number of `g2` pointwise functions registered for this key
853: . g2 - The array of `g2` Jacobian pointwise functions
854: . n3 - The number of `g3` pointwise functions registered for this key
855: - g3 - The array of `g3` Jacobian pointwise functions

857:   Level: intermediate

859: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormAddJacobian()`, `PetscWeakFormHasJacobian()`, `PetscWeakFormGetJacobianPreconditioner()`
860: @*/
861: 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[]))
862: {
863:   PetscInt find = f * wf->Nf + g;

865:   PetscFunctionBegin;
866:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, n0, (void (***)(void))g0));
867:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, n1, (void (***)(void))g1));
868:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, n2, (void (***)(void))g2));
869:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, n3, (void (***)(void))g3));
870:   PetscFunctionReturn(PETSC_SUCCESS);
871: }

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

876:   Not Collective

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

890:   Level: intermediate

892: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormGetJacobian()`, `PetscWeakFormSetIndexJacobian()`
893: @*/
894: 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[]))
895: {
896:   PetscInt find = f * wf->Nf + g;

898:   PetscFunctionBegin;
899:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, (PetscVoidFn *)g0));
900:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, (PetscVoidFn *)g1));
901:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, (PetscVoidFn *)g2));
902:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, (PetscVoidFn *)g3));
903:   PetscFunctionReturn(PETSC_SUCCESS);
904: }

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

909:   Not Collective

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

927:   Level: intermediate

929: .seealso: `PetscWeakForm`, `PetscWeakFormGetJacobian()`, `PetscWeakFormAddJacobian()`, `PetscWeakFormSetIndexJacobian()`, `PetscWeakFormSetJacobianPreconditioner()`
930: @*/
931: 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[]))
932: {
933:   PetscInt find = f * wf->Nf + g;

935:   PetscFunctionBegin;
936:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, n0, (PetscVoidFn **)g0));
937:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, n1, (PetscVoidFn **)g1));
938:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, n2, (PetscVoidFn **)g2));
939:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, n3, (PetscVoidFn **)g3));
940:   PetscFunctionReturn(PETSC_SUCCESS);
941: }

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

946:   Not Collective

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

964:   Level: intermediate

966: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobian()`, `PetscWeakFormAddJacobian()`, `PetscWeakFormGetJacobian()`, `PetscWeakFormClearIndex()`
967: @*/
968: 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[]))
969: {
970:   PetscInt find = f * wf->Nf + g;

972:   PetscFunctionBegin;
973:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G0], label, val, find, part, i0, (PetscVoidFn *)g0));
974:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G1], label, val, find, part, i1, (PetscVoidFn *)g1));
975:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G2], label, val, find, part, i2, (PetscVoidFn *)g2));
976:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_G3], label, val, find, part, i3, (PetscVoidFn *)g3));
977:   PetscFunctionReturn(PETSC_SUCCESS);
978: }

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

983:   Not Collective

985:   Input Parameter:
986: . wf - The `PetscWeakForm`

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

991:   Level: intermediate

993: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormHasJacobian()`, `PetscWeakFormHasBdJacobianPreconditioner()`
994: @*/
995: PetscErrorCode PetscWeakFormHasJacobianPreconditioner(PetscWeakForm wf, PetscBool *hasJacPre)
996: {
997:   PetscInt n0, n1, n2, n3;

999:   PetscFunctionBegin;
1001:   PetscAssertPointer(hasJacPre, 2);
1002:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP0], &n0));
1003:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP1], &n1));
1004:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP2], &n2));
1005:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GP3], &n3));
1006:   *hasJacPre = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1007:   PetscFunctionReturn(PETSC_SUCCESS);
1008: }

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

1013:   Not Collective

1015:   Input Parameters:
1016: + wf    - The `PetscWeakForm`
1017: . label - The label selecting the mesh region, or `NULL` for the entire domain
1018: . val   - The label value selecting the mesh region
1019: . f     - The test field number
1020: . g     - The trial field number
1021: - part  - The equation part, or 0 if unused

1023:   Output Parameters:
1024: + n0 - The number of `g0` pointwise functions registered for this key
1025: . g0 - The array of `g0` Jacobian preconditioner pointwise functions
1026: . n1 - The number of `g1` pointwise functions registered for this key
1027: . g1 - The array of `g1` Jacobian preconditioner pointwise functions
1028: . n2 - The number of `g2` pointwise functions registered for this key
1029: . g2 - The array of `g2` Jacobian preconditioner pointwise functions
1030: . n3 - The number of `g3` pointwise functions registered for this key
1031: - g3 - The array of `g3` Jacobian preconditioner pointwise functions

1033:   Level: intermediate

1035: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormAddJacobianPreconditioner()`, `PetscWeakFormHasJacobianPreconditioner()`, `PetscWeakFormGetJacobian()`
1036: @*/
1037: 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[]))
1038: {
1039:   PetscInt find = f * wf->Nf + g;

1041:   PetscFunctionBegin;
1042:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, n0, (void (***)(void))g0));
1043:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, n1, (void (***)(void))g1));
1044:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, n2, (void (***)(void))g2));
1045:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, n3, (void (***)(void))g3));
1046:   PetscFunctionReturn(PETSC_SUCCESS);
1047: }

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

1052:   Not Collective

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

1066:   Level: intermediate

1068: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormAddJacobian()`
1069: @*/
1070: 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[]))
1071: {
1072:   PetscInt find = f * wf->Nf + g;

1074:   PetscFunctionBegin;
1075:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, (PetscVoidFn *)g0));
1076:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, (PetscVoidFn *)g1));
1077:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, (PetscVoidFn *)g2));
1078:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, (PetscVoidFn *)g3));
1079:   PetscFunctionReturn(PETSC_SUCCESS);
1080: }

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

1085:   Not Collective

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

1103:   Level: intermediate

1105: .seealso: `PetscWeakForm`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormAddJacobianPreconditioner()`, `PetscWeakFormSetJacobian()`
1106: @*/
1107: 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[]))
1108: {
1109:   PetscInt find = f * wf->Nf + g;

1111:   PetscFunctionBegin;
1112:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, n0, (PetscVoidFn **)g0));
1113:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, n1, (PetscVoidFn **)g1));
1114:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, n2, (PetscVoidFn **)g2));
1115:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, n3, (PetscVoidFn **)g3));
1116:   PetscFunctionReturn(PETSC_SUCCESS);
1117: }

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

1122:   Not Collective

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

1140:   Level: intermediate

1142: .seealso: `PetscWeakForm`, `PetscWeakFormSetJacobianPreconditioner()`, `PetscWeakFormAddJacobianPreconditioner()`, `PetscWeakFormGetJacobianPreconditioner()`, `PetscWeakFormClearIndex()`
1143: @*/
1144: 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[]))
1145: {
1146:   PetscInt find = f * wf->Nf + g;

1148:   PetscFunctionBegin;
1149:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP0], label, val, find, part, i0, (PetscVoidFn *)g0));
1150:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP1], label, val, find, part, i1, (PetscVoidFn *)g1));
1151:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP2], label, val, find, part, i2, (PetscVoidFn *)g2));
1152:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GP3], label, val, find, part, i3, (PetscVoidFn *)g3));
1153:   PetscFunctionReturn(PETSC_SUCCESS);
1154: }

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

1159:   Not Collective

1161:   Input Parameter:
1162: . wf - The `PetscWeakForm`

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

1167:   Level: intermediate

1169: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormHasJacobian()`, `PetscWeakFormHasBdJacobianPreconditioner()`
1170: @*/
1171: PetscErrorCode PetscWeakFormHasBdJacobian(PetscWeakForm wf, PetscBool *hasJac)
1172: {
1173:   PetscInt n0, n1, n2, n3;

1175:   PetscFunctionBegin;
1177:   PetscAssertPointer(hasJac, 2);
1178:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG0], &n0));
1179:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG1], &n1));
1180:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG2], &n2));
1181:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDG3], &n3));
1182:   *hasJac = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1183:   PetscFunctionReturn(PETSC_SUCCESS);
1184: }

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

1189:   Not Collective

1191:   Input Parameters:
1192: + wf    - The `PetscWeakForm`
1193: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1194: . val   - The label value selecting the boundary region
1195: . f     - The test field number
1196: . g     - The trial field number
1197: - part  - The equation part, or 0 if unused

1199:   Output Parameters:
1200: + n0 - The number of `g0` boundary pointwise functions registered for this key
1201: . g0 - The array of `g0` boundary Jacobian pointwise functions
1202: . n1 - The number of `g1` boundary pointwise functions registered for this key
1203: . g1 - The array of `g1` boundary Jacobian pointwise functions
1204: . n2 - The number of `g2` boundary pointwise functions registered for this key
1205: . g2 - The array of `g2` boundary Jacobian pointwise functions
1206: . n3 - The number of `g3` boundary pointwise functions registered for this key
1207: - g3 - The array of `g3` boundary Jacobian pointwise functions

1209:   Level: intermediate

1211: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormAddBdJacobian()`, `PetscWeakFormHasBdJacobian()`, `PetscWeakFormGetJacobian()`
1212: @*/
1213: 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[]))
1214: {
1215:   PetscInt find = f * wf->Nf + g;

1217:   PetscFunctionBegin;
1218:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, n0, (void (***)(void))g0));
1219:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, n1, (void (***)(void))g1));
1220:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, n2, (void (***)(void))g2));
1221:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, n3, (void (***)(void))g3));
1222:   PetscFunctionReturn(PETSC_SUCCESS);
1223: }

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

1228:   Not Collective

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

1242:   Level: intermediate

1244: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormAddJacobian()`
1245: @*/
1246: 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[]))
1247: {
1248:   PetscInt find = f * wf->Nf + g;

1250:   PetscFunctionBegin;
1251:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, (PetscVoidFn *)g0));
1252:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, (PetscVoidFn *)g1));
1253:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, (PetscVoidFn *)g2));
1254:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, (PetscVoidFn *)g3));
1255:   PetscFunctionReturn(PETSC_SUCCESS);
1256: }

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

1261:   Not Collective

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

1279:   Level: intermediate

1281: .seealso: `PetscWeakForm`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormAddBdJacobian()`, `PetscWeakFormSetJacobian()`
1282: @*/
1283: 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[]))
1284: {
1285:   PetscInt find = f * wf->Nf + g;

1287:   PetscFunctionBegin;
1288:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, n0, (PetscVoidFn **)g0));
1289:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, n1, (PetscVoidFn **)g1));
1290:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, n2, (PetscVoidFn **)g2));
1291:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, n3, (PetscVoidFn **)g3));
1292:   PetscFunctionReturn(PETSC_SUCCESS);
1293: }

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

1298:   Not Collective

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

1316:   Level: intermediate

1318: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobian()`, `PetscWeakFormAddBdJacobian()`, `PetscWeakFormGetBdJacobian()`, `PetscWeakFormClearIndex()`
1319: @*/
1320: 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[]))
1321: {
1322:   PetscInt find = f * wf->Nf + g;

1324:   PetscFunctionBegin;
1325:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG0], label, val, find, part, i0, (PetscVoidFn *)g0));
1326:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG1], label, val, find, part, i1, (PetscVoidFn *)g1));
1327:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG2], label, val, find, part, i2, (PetscVoidFn *)g2));
1328:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDG3], label, val, find, part, i3, (PetscVoidFn *)g3));
1329:   PetscFunctionReturn(PETSC_SUCCESS);
1330: }

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

1335:   Not Collective

1337:   Input Parameter:
1338: . wf - The `PetscWeakForm`

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

1343:   Level: intermediate

1345: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormHasBdJacobian()`, `PetscWeakFormHasJacobianPreconditioner()`
1346: @*/
1347: PetscErrorCode PetscWeakFormHasBdJacobianPreconditioner(PetscWeakForm wf, PetscBool *hasJacPre)
1348: {
1349:   PetscInt n0, n1, n2, n3;

1351:   PetscFunctionBegin;
1353:   PetscAssertPointer(hasJacPre, 2);
1354:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP0], &n0));
1355:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP1], &n1));
1356:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP2], &n2));
1357:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_BDGP3], &n3));
1358:   *hasJacPre = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1359:   PetscFunctionReturn(PETSC_SUCCESS);
1360: }

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

1365:   Not Collective

1367:   Input Parameters:
1368: + wf    - The `PetscWeakForm`
1369: . label - The label selecting the boundary region, or `NULL` for the entire boundary
1370: . val   - The label value selecting the boundary region
1371: . f     - The test field number
1372: . g     - The trial field number
1373: - part  - The equation part, or 0 if unused

1375:   Output Parameters:
1376: + n0 - The number of `g0` boundary pointwise functions registered for this key
1377: . g0 - The array of `g0` boundary Jacobian preconditioner pointwise functions
1378: . n1 - The number of `g1` boundary pointwise functions registered for this key
1379: . g1 - The array of `g1` boundary Jacobian preconditioner pointwise functions
1380: . n2 - The number of `g2` boundary pointwise functions registered for this key
1381: . g2 - The array of `g2` boundary Jacobian preconditioner pointwise functions
1382: . n3 - The number of `g3` boundary pointwise functions registered for this key
1383: - g3 - The array of `g3` boundary Jacobian preconditioner pointwise functions

1385:   Level: intermediate

1387: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobianPreconditioner()`, `PetscWeakFormHasBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobian()`
1388: @*/
1389: 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[]))
1390: {
1391:   PetscInt find = f * wf->Nf + g;

1393:   PetscFunctionBegin;
1394:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, n0, (void (***)(void))g0));
1395:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, n1, (void (***)(void))g1));
1396:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, n2, (void (***)(void))g2));
1397:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, n3, (void (***)(void))g3));
1398:   PetscFunctionReturn(PETSC_SUCCESS);
1399: }

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

1404:   Not Collective

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

1418:   Level: intermediate

1420: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobian()`
1421: @*/
1422: 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[]))
1423: {
1424:   PetscInt find = f * wf->Nf + g;

1426:   PetscFunctionBegin;
1427:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, (PetscVoidFn *)g0));
1428:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, (PetscVoidFn *)g1));
1429:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, (PetscVoidFn *)g2));
1430:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, (PetscVoidFn *)g3));
1431:   PetscFunctionReturn(PETSC_SUCCESS);
1432: }

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

1437:   Not Collective

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

1455:   Level: intermediate

1457: .seealso: `PetscWeakForm`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobianPreconditioner()`, `PetscWeakFormSetBdJacobian()`
1458: @*/
1459: 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[]))
1460: {
1461:   PetscInt find = f * wf->Nf + g;

1463:   PetscFunctionBegin;
1464:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, n0, (PetscVoidFn **)g0));
1465:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, n1, (PetscVoidFn **)g1));
1466:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, n2, (PetscVoidFn **)g2));
1467:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, n3, (PetscVoidFn **)g3));
1468:   PetscFunctionReturn(PETSC_SUCCESS);
1469: }

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

1474:   Not Collective

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

1492:   Level: intermediate

1494: .seealso: `PetscWeakForm`, `PetscWeakFormSetBdJacobianPreconditioner()`, `PetscWeakFormAddBdJacobianPreconditioner()`, `PetscWeakFormGetBdJacobianPreconditioner()`, `PetscWeakFormClearIndex()`
1495: @*/
1496: 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[]))
1497: {
1498:   PetscInt find = f * wf->Nf + g;

1500:   PetscFunctionBegin;
1501:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP0], label, val, find, part, i0, (PetscVoidFn *)g0));
1502:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP1], label, val, find, part, i1, (PetscVoidFn *)g1));
1503:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP2], label, val, find, part, i2, (PetscVoidFn *)g2));
1504:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_BDGP3], label, val, find, part, i3, (PetscVoidFn *)g3));
1505:   PetscFunctionReturn(PETSC_SUCCESS);
1506: }

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

1511:   Not Collective

1513:   Input Parameter:
1514: . wf - The `PetscWeakForm`

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

1519:   Level: intermediate

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

1524: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormHasJacobian()`
1525: @*/
1526: PetscErrorCode PetscWeakFormHasDynamicJacobian(PetscWeakForm wf, PetscBool *hasDynJac)
1527: {
1528:   PetscInt n0, n1, n2, n3;

1530:   PetscFunctionBegin;
1532:   PetscAssertPointer(hasDynJac, 2);
1533:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT0], &n0));
1534:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT1], &n1));
1535:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT2], &n2));
1536:   PetscCall(PetscHMapFormGetSize(wf->form[PETSC_WF_GT3], &n3));
1537:   *hasDynJac = n0 + n1 + n2 + n3 ? PETSC_TRUE : PETSC_FALSE;
1538:   PetscFunctionReturn(PETSC_SUCCESS);
1539: }

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

1544:   Not Collective

1546:   Input Parameters:
1547: + wf    - The `PetscWeakForm`
1548: . label - The label selecting the mesh region, or `NULL` for the entire domain
1549: . val   - The label value selecting the mesh region
1550: . f     - The test field number
1551: . g     - The trial field number
1552: - part  - The equation part, or 0 if unused

1554:   Output Parameters:
1555: + n0 - The number of `g0` pointwise functions registered for this key
1556: . g0 - The array of `g0` dynamic Jacobian pointwise functions
1557: . n1 - The number of `g1` pointwise functions registered for this key
1558: . g1 - The array of `g1` dynamic Jacobian pointwise functions
1559: . n2 - The number of `g2` pointwise functions registered for this key
1560: . g2 - The array of `g2` dynamic Jacobian pointwise functions
1561: . n3 - The number of `g3` pointwise functions registered for this key
1562: - g3 - The array of `g3` dynamic Jacobian pointwise functions

1564:   Level: intermediate

1566: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormAddDynamicJacobian()`, `PetscWeakFormHasDynamicJacobian()`, `PetscWeakFormGetJacobian()`
1567: @*/
1568: 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[]))
1569: {
1570:   PetscInt find = f * wf->Nf + g;

1572:   PetscFunctionBegin;
1573:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, n0, (void (***)(void))g0));
1574:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, n1, (void (***)(void))g1));
1575:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, n2, (void (***)(void))g2));
1576:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, n3, (void (***)(void))g3));
1577:   PetscFunctionReturn(PETSC_SUCCESS);
1578: }

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

1583:   Not Collective

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

1597:   Level: intermediate

1599: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormAddJacobian()`
1600: @*/
1601: 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[]))
1602: {
1603:   PetscInt find = f * wf->Nf + g;

1605:   PetscFunctionBegin;
1606:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, (PetscVoidFn *)g0));
1607:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, (PetscVoidFn *)g1));
1608:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, (PetscVoidFn *)g2));
1609:   PetscCall(PetscWeakFormAddFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, (PetscVoidFn *)g3));
1610:   PetscFunctionReturn(PETSC_SUCCESS);
1611: }

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

1616:   Not Collective

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

1634:   Level: intermediate

1636: .seealso: `PetscWeakForm`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormAddDynamicJacobian()`, `PetscWeakFormSetJacobian()`
1637: @*/
1638: 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[]))
1639: {
1640:   PetscInt find = f * wf->Nf + g;

1642:   PetscFunctionBegin;
1643:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, n0, (PetscVoidFn **)g0));
1644:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, n1, (PetscVoidFn **)g1));
1645:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, n2, (PetscVoidFn **)g2));
1646:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, n3, (PetscVoidFn **)g3));
1647:   PetscFunctionReturn(PETSC_SUCCESS);
1648: }

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

1653:   Not Collective

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

1671:   Level: intermediate

1673: .seealso: `PetscWeakForm`, `PetscWeakFormSetDynamicJacobian()`, `PetscWeakFormAddDynamicJacobian()`, `PetscWeakFormGetDynamicJacobian()`, `PetscWeakFormClearIndex()`
1674: @*/
1675: 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[]))
1676: {
1677:   PetscInt find = f * wf->Nf + g;

1679:   PetscFunctionBegin;
1680:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT0], label, val, find, part, i0, (PetscVoidFn *)g0));
1681:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT1], label, val, find, part, i1, (PetscVoidFn *)g1));
1682:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT2], label, val, find, part, i2, (PetscVoidFn *)g2));
1683:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_GT3], label, val, find, part, i3, (PetscVoidFn *)g3));
1684:   PetscFunctionReturn(PETSC_SUCCESS);
1685: }

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

1690:   Not Collective

1692:   Input Parameters:
1693: + wf    - The `PetscWeakForm`
1694: . label - The label selecting the mesh region, or `NULL` for the entire domain
1695: . val   - The label value selecting the mesh region
1696: . f     - The field number
1697: - part  - The equation part, or 0 if unused

1699:   Output Parameters:
1700: + n - The number of Riemann solver pointwise functions registered for this key
1701: - r - The array of Riemann solver pointwise functions

1703:   Level: intermediate

1705: .seealso: `PetscWeakForm`, `PetscWeakFormSetRiemannSolver()`, `PetscWeakFormSetIndexRiemannSolver()`
1706: @*/
1707: 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 *))
1708: {
1709:   PetscFunctionBegin;
1710:   PetscCall(PetscWeakFormGetFunction_Private(wf, wf->form[PETSC_WF_R], label, val, f, part, n, (void (***)(void))r));
1711:   PetscFunctionReturn(PETSC_SUCCESS);
1712: }

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

1717:   Not Collective

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

1728:   Level: intermediate

1730: .seealso: `PetscWeakForm`, `PetscWeakFormGetRiemannSolver()`, `PetscWeakFormSetIndexRiemannSolver()`
1731: @*/
1732: 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 *))
1733: {
1734:   PetscFunctionBegin;
1735:   PetscCall(PetscWeakFormSetFunction_Private(wf, wf->form[PETSC_WF_R], label, val, f, part, n, (PetscVoidFn **)r));
1736:   PetscFunctionReturn(PETSC_SUCCESS);
1737: }

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

1742:   Not Collective

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

1753:   Level: intermediate

1755: .seealso: `PetscWeakForm`, `PetscWeakFormSetRiemannSolver()`, `PetscWeakFormGetRiemannSolver()`, `PetscWeakFormClearIndex()`
1756: @*/
1757: 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 *))
1758: {
1759:   PetscFunctionBegin;
1760:   PetscCall(PetscWeakFormSetIndexFunction_Private(wf, wf->form[PETSC_WF_R], label, val, f, part, i, (PetscVoidFn *)r));
1761:   PetscFunctionReturn(PETSC_SUCCESS);
1762: }

1764: /*@
1765:   PetscWeakFormGetNumFields - Returns the number of fields in a `PetscWeakForm`

1767:   Not Collective

1769:   Input Parameter:
1770: . wf - The `PetscWeakForm` object

1772:   Output Parameter:
1773: . Nf - The number of fields

1775:   Level: beginner

1777: .seealso: `PetscWeakForm`, `PetscWeakFormSetNumFields()`, `PetscWeakFormCreate()`
1778: @*/
1779: PetscErrorCode PetscWeakFormGetNumFields(PetscWeakForm wf, PetscInt *Nf)
1780: {
1781:   PetscFunctionBegin;
1783:   PetscAssertPointer(Nf, 2);
1784:   *Nf = wf->Nf;
1785:   PetscFunctionReturn(PETSC_SUCCESS);
1786: }

1788: /*@
1789:   PetscWeakFormSetNumFields - Sets the number of fields

1791:   Not Collective

1793:   Input Parameters:
1794: + wf - The `PetscWeakForm` object
1795: - Nf - The number of fields

1797:   Level: beginner

1799: .seealso: `PetscWeakForm`, `PetscWeakFormGetNumFields()`, `PetscWeakFormCreate()`
1800: @*/
1801: PetscErrorCode PetscWeakFormSetNumFields(PetscWeakForm wf, PetscInt Nf)
1802: {
1803:   PetscFunctionBegin;
1805:   wf->Nf = Nf;
1806:   PetscFunctionReturn(PETSC_SUCCESS);
1807: }

1809: /*@
1810:   PetscWeakFormDestroy - Destroys a `PetscWeakForm` object

1812:   Collective

1814:   Input Parameter:
1815: . wf - the `PetscWeakForm` object to destroy

1817:   Level: developer

1819: .seealso: `PetscWeakForm`, `PetscWeakFormCreate()`, `PetscWeakFormView()`
1820: @*/
1821: PetscErrorCode PetscWeakFormDestroy(PetscWeakForm *wf)
1822: {
1823:   PetscInt f;

1825:   PetscFunctionBegin;
1826:   if (!*wf) PetscFunctionReturn(PETSC_SUCCESS);

1829:   if (--((PetscObject)*wf)->refct > 0) {
1830:     *wf = NULL;
1831:     PetscFunctionReturn(PETSC_SUCCESS);
1832:   }
1833:   ((PetscObject)*wf)->refct = 0;
1834:   PetscCall(PetscChunkBufferDestroy(&(*wf)->funcs));
1835:   for (f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscHMapFormDestroy(&(*wf)->form[f]));
1836:   PetscCall(PetscFree((*wf)->form));
1837:   PetscCall(PetscHeaderDestroy(wf));
1838:   PetscFunctionReturn(PETSC_SUCCESS);
1839: }

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

1845:   PetscFunctionBegin;
1846:   PetscCall(PetscHMapFormGetSize(map, &Nk));
1847:   if (Nk) {
1848:     PetscFormKey *keys;
1849:     PetscVoidFn **funcs = NULL;
1850:     const char  **names;
1851:     PetscInt     *fields, *values, *idx1, *idx2, *idx3, *idx;
1852:     PetscBool     showPart = PETSC_FALSE, showPointer = PETSC_FALSE;
1853:     PetscInt      off = 0;

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

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

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

1939: static PetscErrorCode PetscWeakFormView_Ascii(PetscWeakForm wf, PetscViewer viewer)
1940: {
1941:   PetscViewerFormat format;

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

1952: /*@
1953:   PetscWeakFormView - Views a `PetscWeakForm`

1955:   Collective

1957:   Input Parameters:
1958: + wf - the `PetscWeakForm` object to view
1959: - v  - the viewer

1961:   Level: developer

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

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

1979: /*@
1980:   PetscWeakFormGetKeys - Return an array of `PetscFormKey` of a certain `PetscWeakFormKind`

1982:   Not Collective

1984:   Input Parameters:
1985: + wf - the `PetscWeakForm` object
1986: - k  - the `PetscWeakFormKind` to get keys for

1988:   Output Parameters:
1989: + Nk   - the number of keys returned
1990: - keys - the array of `PetscFormKey` objects

1992:   Level: developer

1994:   Note:
1995:   The caller must `PetscFree()` the `keys` array when it is no longer needed.

1997: .seealso: `PetscWeakForm`, `PetscWeakFormDestroy()`, `PetscWeakFormCreate()`
1998: @*/
1999: PetscErrorCode PetscWeakFormGetKeys(PetscWeakForm wf, PetscWeakFormKind k, PetscInt *Nk, PetscFormKey *keys[])
2000: {
2001:   PetscHMapForm map;
2002:   PetscInt      off = 0;

2004:   PetscFunctionBegin;
2006:   PetscAssertPointer(Nk, 3);
2007:   PetscAssertPointer(keys, 4);
2008:   map = wf->form[k];
2009:   PetscCall(PetscHMapFormGetSize(map, Nk));
2010:   PetscCall(PetscMalloc1(*Nk, keys));
2011:   PetscCall(PetscHMapFormGetKeys(map, &off, *keys));
2012:   PetscFunctionReturn(PETSC_SUCCESS);
2013: }

2015: /*@
2016:   PetscWeakFormCreate - Creates an empty `PetscWeakForm` object.

2018:   Collective

2020:   Input Parameter:
2021: . comm - The communicator for the `PetscWeakForm` object

2023:   Output Parameter:
2024: . wf - The `PetscWeakForm` object

2026:   Level: beginner

2028: .seealso: `PetscWeakForm`, `PetscDS`, `PetscWeakFormDestroy()`
2029: @*/
2030: PetscErrorCode PetscWeakFormCreate(MPI_Comm comm, PetscWeakForm *wf)
2031: {
2032:   PetscWeakForm p;

2034:   PetscFunctionBegin;
2035:   PetscAssertPointer(wf, 2);
2036:   PetscCall(PetscDSInitializePackage());

2038:   PetscCall(PetscHeaderCreate(p, PETSCWEAKFORM_CLASSID, "PetscWeakForm", "Weak Form System", "PetscWeakForm", comm, PetscWeakFormDestroy, PetscWeakFormView));
2039:   p->Nf = 0;
2040:   PetscCall(PetscChunkBufferCreate(sizeof(&PetscWeakFormCreate), 2, &p->funcs));
2041:   PetscCall(PetscMalloc1(PETSC_NUM_WF, &p->form));
2042:   for (PetscInt f = 0; f < PETSC_NUM_WF; ++f) PetscCall(PetscHMapFormCreate(&p->form[f]));
2043:   *wf = p;
2044:   PetscFunctionReturn(PETSC_SUCCESS);
2045: }