Actual source code: dmmbfield.cxx
1: #include <petsc/private/dmmbimpl.h>
3: #include <petscdmmoab.h>
5: /*@C
6: DMMoabSetFieldVector - Sets the vector reference that represents the solution associated
7: with a particular field component.
9: Not Collective
11: Input Parameters:
12: + dm - the discretization manager object
13: . ifield - the index of the field as set before via DMMoabSetFieldName.
14: - fvec - the Vector solution corresponding to the field (component)
16: Level: intermediate
18: .seealso: `DMMoabGetFieldName()`, `DMMoabSetGlobalFieldVector()`
19: @*/
20: PetscErrorCode DMMoabSetFieldVector(DM dm, PetscInt ifield, Vec fvec)
21: {
22: DM_Moab *dmmoab;
23: moab::Tag vtag, ntag;
24: const PetscScalar *varray;
25: PetscScalar *farray;
26: moab::ErrorCode merr;
27: std::string tag_name;
29: PetscFunctionBegin;
31: dmmoab = (DM_Moab *)dm->data;
33: PetscCheck(!(ifield < 0) && !(ifield >= dmmoab->numFields), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "The field %d should be positive and less than %d.", ifield, dmmoab->numFields);
35: /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
36: merr = dmmoab->mbiface->tag_get_handle(dmmoab->fieldNames[ifield], 1, moab::MB_TYPE_DOUBLE, ntag, moab::MB_TAG_DENSE | moab::MB_TAG_CREAT);
37: MBERRNM(merr);
39: PetscCall(DMMoabGetVecTag(fvec, &vtag));
41: merr = dmmoab->mbiface->tag_get_name(vtag, tag_name);
42: if (!tag_name.length() && merr != moab::MB_SUCCESS) {
43: PetscCall(VecGetArrayRead(fvec, &varray));
44: /* use the entity handle and the Dof index to set the right value */
45: merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void *)varray);
46: MBERRNM(merr);
47: PetscCall(VecRestoreArrayRead(fvec, &varray));
48: } else {
49: PetscCall(PetscMalloc1(dmmoab->nloc, &farray));
50: /* we are using a MOAB Vec - directly copy the tag data to new one */
51: merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void *)farray);
52: MBERRNM(merr);
53: merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void *)farray);
54: MBERRNM(merr);
55: /* make sure the parallel exchange for ghosts are done appropriately */
56: PetscCall(PetscFree(farray));
57: }
58: #ifdef MOAB_HAVE_MPI
59: merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vowned);
60: MBERRNM(merr);
61: #endif
62: PetscFunctionReturn(PETSC_SUCCESS);
63: }
65: /*@C
66: DMMoabSetGlobalFieldVector - Sets the vector reference that represents the global solution associated
67: with all fields (components) managed by DM.
68: A useful utility when updating the DM solution after a solve, to be serialized with the mesh for
69: checkpointing purposes.
71: Not Collective
73: Input Parameters:
74: + dm - the discretization manager object
75: - fvec - the global Vector solution corresponding to all the fields managed by DM
77: Level: intermediate
79: .seealso: `DMMoabGetFieldName()`, `DMMoabSetFieldVector()`
80: @*/
81: PetscErrorCode DMMoabSetGlobalFieldVector(DM dm, Vec fvec)
82: {
83: DM_Moab *dmmoab;
84: moab::Tag vtag, ntag;
85: const PetscScalar *rarray;
86: PetscScalar *varray, *farray;
87: moab::ErrorCode merr;
88: PetscInt i, ifield;
89: std::string tag_name;
90: moab::Range::iterator iter;
92: PetscFunctionBegin;
94: dmmoab = (DM_Moab *)dm->data;
96: /* get the Tag corresponding to the global vector - possible that there is no tag associated.. */
97: PetscCall(DMMoabGetVecTag(fvec, &vtag));
98: merr = dmmoab->mbiface->tag_get_name(vtag, tag_name);
99: PetscCall(PetscMalloc1(dmmoab->nloc, &farray));
100: if (!tag_name.length() && merr != moab::MB_SUCCESS) {
101: /* not a MOAB vector - use VecGetSubVector to get the parts as needed */
102: PetscCall(VecGetArrayRead(fvec, &rarray));
103: for (ifield = 0; ifield < dmmoab->numFields; ++ifield) {
104: /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
105: merr = dmmoab->mbiface->tag_get_handle(dmmoab->fieldNames[ifield], 1, moab::MB_TYPE_DOUBLE, ntag, moab::MB_TAG_DENSE | moab::MB_TAG_CREAT);
106: MBERRNM(merr);
108: for (i = 0; i < dmmoab->nloc; i++) farray[i] = (dmmoab->bs == 1 ? rarray[ifield * dmmoab->nloc + i] : rarray[i * dmmoab->numFields + ifield]);
110: /* use the entity handle and the Dof index to set the right value */
111: merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void *)farray);
112: MBERRNM(merr);
113: }
114: PetscCall(VecRestoreArrayRead(fvec, &rarray));
115: } else {
116: PetscCall(PetscMalloc1(dmmoab->nloc * dmmoab->numFields, &varray));
118: /* we are using a MOAB Vec - directly copy the tag data to new one */
119: merr = dmmoab->mbiface->tag_get_data(vtag, *dmmoab->vowned, (void *)varray);
120: MBERRNM(merr);
121: for (ifield = 0; ifield < dmmoab->numFields; ++ifield) {
122: /* Create a tag in MOAB mesh to index and keep track of number of Petsc vec tags */
123: merr = dmmoab->mbiface->tag_get_handle(dmmoab->fieldNames[ifield], 1, moab::MB_TYPE_DOUBLE, ntag, moab::MB_TAG_DENSE | moab::MB_TAG_CREAT);
124: MBERRNM(merr);
126: /* we are using a MOAB Vec - directly copy the tag data to new one */
127: for (i = 0; i < dmmoab->nloc; i++) farray[i] = (dmmoab->bs == 1 ? varray[ifield * dmmoab->nloc + i] : varray[i * dmmoab->numFields + ifield]);
129: merr = dmmoab->mbiface->tag_set_data(ntag, *dmmoab->vowned, (const void *)farray);
130: MBERRNM(merr);
132: #ifdef MOAB_HAVE_MPI
133: /* make sure the parallel exchange for ghosts are done appropriately */
134: merr = dmmoab->pcomm->exchange_tags(ntag, *dmmoab->vlocal);
135: MBERRNM(merr);
136: #endif
137: }
138: PetscCall(PetscFree(varray));
139: }
140: PetscCall(PetscFree(farray));
141: PetscFunctionReturn(PETSC_SUCCESS);
142: }
144: /*@C
145: DMMoabSetFieldNames - Sets the number of fields and their names to be managed by the DM
147: Not Collective
149: Input Parameters:
150: + dm - the discretization manager object
151: . numFields - the total number of fields
152: - fields - the array containing the names of each field (component); Can be `NULL`.
154: Level: intermediate
156: .seealso: `DMMoabGetFieldName()`, `DMMoabSetFieldName()`
157: @*/
158: PetscErrorCode DMMoabSetFieldNames(DM dm, PetscInt numFields, const char *fields[])
159: {
160: PetscInt i;
161: DM_Moab *dmmoab;
163: PetscFunctionBegin;
165: dmmoab = (DM_Moab *)dm->data;
167: /* first deallocate the existing field structure */
168: if (dmmoab->fieldNames) {
169: for (i = 0; i < dmmoab->numFields; i++) PetscCall(PetscFree(dmmoab->fieldNames[i]));
170: PetscCall(PetscFree(dmmoab->fieldNames));
171: }
173: /* now re-allocate and assign field names */
174: dmmoab->numFields = numFields;
175: PetscCall(PetscMalloc1(numFields, &dmmoab->fieldNames));
176: if (fields) {
177: for (i = 0; i < dmmoab->numFields; i++) PetscCall(PetscStrallocpy(fields[i], (char **)&dmmoab->fieldNames[i]));
178: }
179: PetscCall(DMSetNumFields(dm, numFields));
180: PetscFunctionReturn(PETSC_SUCCESS);
181: }
183: /*@C
184: DMMoabGetFieldName - Gets the names of individual field components in multicomponent
185: vectors associated with a DMDA.
187: Not Collective
189: Input Parameters:
190: + dm - the discretization manager object
191: - field - field number for the DMMoab (0, 1, ... dof-1), where dof indicates the
192: number of degrees of freedom per node within the DMMoab
194: Output Parameter:
195: . fieldName - the name of the field (component)
197: Level: intermediate
199: .seealso: `DMMoabSetFieldName()`, `DMMoabSetFields()`
200: @*/
201: PetscErrorCode DMMoabGetFieldName(DM dm, PetscInt field, const char *fieldName[])
202: {
203: DM_Moab *dmmoab;
205: PetscFunctionBegin;
207: dmmoab = (DM_Moab *)dm->data;
208: PetscCheck(!(field < 0) && !(field >= dmmoab->numFields), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "DM field %d should be in [%d, %d)", field, 0, dmmoab->numFields);
210: *fieldName = dmmoab->fieldNames[field];
211: PetscFunctionReturn(PETSC_SUCCESS);
212: }
214: /*@C
215: DMMoabSetFieldName - Sets the name of a field (component) managed by the DM
217: Not Collective
219: Input Parameters:
220: + dm - the discretization manager object
221: . field - the field number
222: - fieldName - the field (component) name
224: Level: intermediate
226: Notes:
227: Can only be called after DMMoabSetFields supplied with correct numFields
229: .seealso: `DMMoabGetFieldName()`, `DMMoabSetFields()`
230: @*/
231: PetscErrorCode DMMoabSetFieldName(DM dm, PetscInt field, const char *fieldName)
232: {
233: DM_Moab *dmmoab;
235: PetscFunctionBegin;
237: PetscAssertPointer(fieldName, 3);
239: dmmoab = (DM_Moab *)dm->data;
240: PetscCheck(!(field < 0) && !(field >= dmmoab->numFields), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "DM field %d should be in [%d, %d)", field, 0, dmmoab->numFields);
242: if (dmmoab->fieldNames[field]) PetscCall(PetscFree(dmmoab->fieldNames[field]));
243: PetscCall(PetscStrallocpy(fieldName, (char **)&dmmoab->fieldNames[field]));
244: PetscFunctionReturn(PETSC_SUCCESS);
245: }
247: /*@C
248: DMMoabGetFieldDof - Gets the global degree-of-freedom of a field (component) defined on a
249: particular MOAB EntityHandle.
251: Not Collective
253: Input Parameters:
254: + dm - the discretization manager object
255: . point - the MOAB EntityHandle container which holds the field degree-of-freedom values
256: - field - the field (component) index
258: Output Parameter:
259: . dof - the global degree-of-freedom index corresponding to the field in the discrete representation (Vec, Mat)
261: Level: beginner
263: .seealso: `DMMoabGetFieldDofs()`, `DMMoabGetFieldDofsLocal()`
264: @*/
265: PetscErrorCode DMMoabGetFieldDof(DM dm, moab::EntityHandle point, PetscInt field, PetscInt *dof)
266: {
267: DM_Moab *dmmoab;
269: PetscFunctionBegin;
271: dmmoab = (DM_Moab *)dm->data;
273: *dof = (dmmoab->bs == 1 ? dmmoab->gidmap[dmmoab->mbiface->id_from_handle(point) - dmmoab->seqstart] + field * dmmoab->n : dmmoab->gidmap[dmmoab->mbiface->id_from_handle(point) - dmmoab->seqstart] * dmmoab->numFields + field);
274: PetscFunctionReturn(PETSC_SUCCESS);
275: }
277: /*@C
278: DMMoabGetFieldDofs - Gets the global degree-of-freedom of a field (component) defined on an
279: array of MOAB EntityHandles.
281: Not Collective
283: Input Parameters:
284: + dm - the discretization manager object
285: . npoints - the total number of Entities in the points array
286: . points - the MOAB EntityHandle container array which holds the field degree-of-freedom values
287: - field - the field (component) index
289: Output Parameter:
290: . dof - the global degree-of-freedom index array corresponding to the field in the discrete representation (Vec, Mat)
292: Level: intermediate
294: .seealso: `DMMoabGetFieldDof()`, `DMMoabGetFieldDofsLocal()`
295: @*/
296: PetscErrorCode DMMoabGetFieldDofs(DM dm, PetscInt npoints, const moab::EntityHandle *points, PetscInt field, PetscInt *dof)
297: {
298: PetscInt i;
299: DM_Moab *dmmoab;
301: PetscFunctionBegin;
303: PetscAssertPointer(points, 3);
304: dmmoab = (DM_Moab *)dm->data;
306: if (!dof) PetscCall(PetscMalloc1(npoints, &dof));
308: /* compute the DOF based on local blocking in the fields */
309: /* We also assume all fields have equal distribution; i.e., all fields are either defined on vertices or elements and not on a mixture */
310: /* TODO: eliminate the limitation using PetscSection to manage DOFs */
311: for (i = 0; i < npoints; ++i)
312: dof[i] = (dmmoab->bs == 1 ? dmmoab->gidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] + field * dmmoab->n : dmmoab->gidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] * dmmoab->numFields + field);
313: PetscFunctionReturn(PETSC_SUCCESS);
314: }
316: /*@C
317: DMMoabGetFieldDofsLocal - Gets the local degrees-of-freedom of a field (component) defined on an
318: array of MOAB EntityHandles.
320: Not Collective
322: Input Parameters:
323: + dm - the discretization manager object
324: . npoints - the total number of Entities in the points array
325: . points - the MOAB EntityHandle container array which holds the field degree-of-freedom values
326: - field - the field (component) index
328: Output Parameter:
329: . dof - the local degree-of-freedom index array corresponding to the field in the discrete representation (Vec, Mat)
331: Level: intermediate
333: .seealso: `DMMoabGetFieldDof()`, `DMMoabGetFieldDofs()`
334: @*/
335: PetscErrorCode DMMoabGetFieldDofsLocal(DM dm, PetscInt npoints, const moab::EntityHandle *points, PetscInt field, PetscInt *dof)
336: {
337: PetscInt i;
338: DM_Moab *dmmoab;
340: PetscFunctionBegin;
342: PetscAssertPointer(points, 3);
343: dmmoab = (DM_Moab *)dm->data;
345: if (!dof) PetscCall(PetscMalloc1(npoints, &dof));
347: /* compute the DOF based on local blocking in the fields */
348: /* assume all fields have equal distribution; i.e., all fields are either defined on vertices or elements and not on a mixture */
349: /* TODO: eliminate the limitation using PetscSection to manage DOFs */
350: for (i = 0; i < npoints; ++i) {
351: dof[i] = (dmmoab->bs > 1 ? dmmoab->lidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] * dmmoab->numFields + field : dmmoab->lidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] + field * dmmoab->n);
352: }
353: PetscFunctionReturn(PETSC_SUCCESS);
354: }
356: /*@C
357: DMMoabGetDofs - Gets the global degree-of-freedom for all fields (components) defined on an
358: array of MOAB EntityHandles.
360: Not Collective
362: Input Parameters:
363: + dm - the discretization manager object
364: . npoints - the total number of Entities in the points array
365: - points - the MOAB EntityHandle container array which holds the field degree-of-freedom values
367: Output Parameter:
368: . dof - the global degree-of-freedom index array corresponding to the field in the discrete representation (Vec, Mat)
370: Level: intermediate
372: .seealso: `DMMoabGetFieldDofs()`, `DMMoabGetDofsLocal()`, `DMMoabGetDofsBlocked()`
373: @*/
374: PetscErrorCode DMMoabGetDofs(DM dm, PetscInt npoints, const moab::EntityHandle *points, PetscInt *dof)
375: {
376: PetscInt i, field, offset;
377: DM_Moab *dmmoab;
379: PetscFunctionBegin;
381: PetscAssertPointer(points, 3);
382: dmmoab = (DM_Moab *)dm->data;
384: if (!dof) PetscCall(PetscMalloc1(dmmoab->numFields * npoints, &dof));
386: /* compute the DOF based on local blocking in the fields */
387: /* assume all fields have equal distribution; i.e., all fields are either defined on vertices or elements and not on a mixture */
388: /* TODO: eliminate the limitation using PetscSection to manage DOFs */
389: for (field = 0; field < dmmoab->numFields; ++field) {
390: offset = field * dmmoab->n;
391: for (i = 0; i < npoints; ++i)
392: dof[i * dmmoab->numFields + field] = (dmmoab->bs > 1 ? dmmoab->gidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] * dmmoab->numFields + field : dmmoab->gidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] + offset);
393: }
394: PetscFunctionReturn(PETSC_SUCCESS);
395: }
397: /*@C
398: DMMoabGetDofsLocal - Gets the local degree-of-freedom for all fields (components) defined on an
399: array of MOAB EntityHandles.
401: Not Collective
403: Input Parameters:
404: + dm - the discretization manager object
405: . npoints - the total number of Entities in the points array
406: - points - the MOAB EntityHandle container array which holds the field degree-of-freedom values
408: Output Parameter:
409: . dof - the local degree-of-freedom index array corresponding to the field in the discrete representation (Vec, Mat)
411: Level: intermediate
413: .seealso: `DMMoabGetFieldDofs()`, `DMMoabGetDofs()`, `DMMoabGetDofsBlocked()`
414: @*/
415: PetscErrorCode DMMoabGetDofsLocal(DM dm, PetscInt npoints, const moab::EntityHandle *points, PetscInt *dof)
416: {
417: PetscInt i, field, offset;
418: DM_Moab *dmmoab;
420: PetscFunctionBegin;
422: PetscAssertPointer(points, 3);
423: dmmoab = (DM_Moab *)dm->data;
425: if (!dof) PetscCall(PetscMalloc1(dmmoab->numFields * npoints, &dof));
427: /* compute the DOF based on local blocking in the fields */
428: /* assume all fields have equal distribution; i.e., all fields are either defined on vertices or elements and not on a mixture */
429: /* TODO: eliminate the limitation using PetscSection to manage DOFs */
430: for (field = 0; field < dmmoab->numFields; ++field) {
431: offset = field * dmmoab->n;
432: for (i = 0; i < npoints; ++i)
433: dof[i * dmmoab->numFields + field] = (dmmoab->bs > 1 ? dmmoab->lidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] * dmmoab->numFields + field : dmmoab->lidmap[dmmoab->mbiface->id_from_handle(points[i]) - dmmoab->seqstart] + offset);
434: }
435: PetscFunctionReturn(PETSC_SUCCESS);
436: }
438: /*@C
439: DMMoabGetDofsBlocked - Gets the global degree-of-freedom for the first field (component) defined on an
440: array of MOAB EntityHandles. It is useful when performing Blocked(Get/Set) methods in computation
441: of element residuals and assembly of the discrete systems when all fields are co-located.
443: Not Collective
445: Input Parameters:
446: + dm - the discretization manager object
447: . npoints - the total number of Entities in the points array
448: - points - the MOAB EntityHandle container array which holds the field degree-of-freedom values
450: Output Parameter:
451: . dof - the blocked global degree-of-freedom index array in the discrete representation (Vec, Mat)
453: Level: intermediate
455: .seealso: `DMMoabGetDofsLocal()`, `DMMoabGetDofs()`, `DMMoabGetDofsBlockedLocal()`
456: @*/
457: PetscErrorCode DMMoabGetDofsBlocked(DM dm, PetscInt npoints, const moab::EntityHandle *points, PetscInt *dof)
458: {
459: PetscInt i;
460: DM_Moab *dmmoab;
462: PetscFunctionBegin;
464: PetscAssertPointer(points, 3);
465: dmmoab = (DM_Moab *)dm->data;
467: if (!dof) PetscCall(PetscMalloc1(npoints, &dof));
469: for (i = 0; i < npoints; ++i) dof[i] = dmmoab->gidmap[(PetscInt)points[i] - dmmoab->seqstart];
470: PetscFunctionReturn(PETSC_SUCCESS);
471: }
473: /*@C
474: DMMoabGetDofsBlockedLocal - Gets the local degree-of-freedom for the first field (component) defined on an
475: array of MOAB EntityHandles. It is useful when performing local Blocked(Get/Set) methods in computation
476: of element residuals and assembly of the discrete systems when all fields are co-located.
478: Not Collective
480: Input Parameters:
481: + dm - the discretization manager object
482: . npoints - the total number of Entities in the points array
483: - points - the MOAB EntityHandle container array which holds the field degree-of-freedom values
485: Output Parameter:
486: . dof - the blocked local degree-of-freedom index array in the discrete representation (Vec, Mat)
488: Level: intermediate
490: .seealso: `DMMoabGetDofsLocal()`, `DMMoabGetDofs()`
491: @*/
492: PetscErrorCode DMMoabGetDofsBlockedLocal(DM dm, PetscInt npoints, const moab::EntityHandle *points, PetscInt *dof)
493: {
494: PetscInt i;
495: DM_Moab *dmmoab;
497: PetscFunctionBegin;
499: PetscAssertPointer(points, 3);
500: dmmoab = (DM_Moab *)dm->data;
502: if (!dof) PetscCall(PetscMalloc1(npoints, &dof));
504: for (i = 0; i < npoints; ++i) dof[i] = dmmoab->lidmap[(PetscInt)points[i] - dmmoab->seqstart];
505: PetscFunctionReturn(PETSC_SUCCESS);
506: }
508: /*@C
509: DMMoabGetVertexDofsBlocked - Gets the global degree-of-freedom for the first field (component) defined on an
510: array of locally owned MOAB mesh vertices.
512: Not Collective
514: Input Parameters:
515: . dm - the discretization manager object
517: Output Parameter:
518: . dof - the blocked global degree-of-freedom index array in the discrete representation (Vec, Mat) that is vertex-based based on local numbering
520: Level: intermediate
522: Note:
523: It's utility is when performing Finite-Difference type calculations where vertex traversal is
524: faster than element-wise assembly that is typically done in FEM calculations.
526: .seealso: `DMMoabGetVertexDofsBlockedLocal()`, `DMMoabGetDofsBlocked()`, `DMMoabGetDofsBlockedLocal()`
527: @*/
528: PetscErrorCode DMMoabGetVertexDofsBlocked(DM dm, PetscInt **dof)
529: {
530: DM_Moab *dmmoab;
532: PetscFunctionBegin;
534: dmmoab = (DM_Moab *)dm->data;
536: *dof = dmmoab->gidmap;
537: PetscFunctionReturn(PETSC_SUCCESS);
538: }
540: /*@C
541: DMMoabGetVertexDofsBlockedLocal - Gets the local degree-of-freedom for the first field (component) defined on an
542: array of locally owned MOAB mesh vertices.
544: Not Collective
546: Input Parameters:
547: . dm - the discretization manager object
549: Output Parameter:
550: . dof - the blocked local degree-of-freedom index array in the discrete representation (Vec, Mat) that is vertex-based based on local numbering
552: Level: intermediate
554: Note:
555: It's utility is when performing Finite-Difference type calculations where vertex traversal is
556: faster than element-wise assembly that is typically done in FEM calculations.
558: .seealso: `DMMoabGetVertexDofsBlocked()`, `DMMoabGetDofsBlocked()`, `DMMoabGetDofsBlockedLocal()`
559: @*/
560: PetscErrorCode DMMoabGetVertexDofsBlockedLocal(DM dm, PetscInt **dof)
561: {
562: DM_Moab *dmmoab;
564: PetscFunctionBegin;
566: PetscAssertPointer(dof, 2);
567: dmmoab = (DM_Moab *)dm->data;
569: *dof = dmmoab->lidmap;
570: PetscFunctionReturn(PETSC_SUCCESS);
571: }