1 #include <petscdm.h> 2 #include <petscdmda.h> 3 #include <petscdmswarm.h> 4 #include <petsc/private/dmswarmimpl.h> 5 #include "../src/dm/impls/swarm/data_bucket.h" 6 7 static PetscErrorCode private_PetscViewerCreate_XDMF(MPI_Comm comm, const char filename[], PetscViewer *v) 8 { 9 long int *bytes; 10 PetscContainer container; 11 PetscViewer viewer; 12 13 PetscFunctionBegin; 14 PetscCall(PetscViewerCreate(comm, &viewer)); 15 PetscCall(PetscViewerSetType(viewer, PETSCVIEWERASCII)); 16 PetscCall(PetscViewerFileSetMode(viewer, FILE_MODE_WRITE)); 17 PetscCall(PetscViewerFileSetName(viewer, filename)); 18 19 PetscCall(PetscMalloc1(1, &bytes)); 20 bytes[0] = 0; 21 PetscCall(PetscContainerCreate(comm, &container)); 22 PetscCall(PetscContainerSetPointer(container, (void *)bytes)); 23 PetscCall(PetscObjectCompose((PetscObject)viewer, "XDMFViewerContext", (PetscObject)container)); 24 25 /* write xdmf header */ 26 PetscCall(PetscViewerASCIIPrintf(viewer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")); 27 PetscCall(PetscViewerASCIIPrintf(viewer, "<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude/\" Version=\"2.99\">\n")); 28 /* write xdmf domain */ 29 PetscCall(PetscViewerASCIIPushTab(viewer)); 30 PetscCall(PetscViewerASCIIPrintf(viewer, "<Domain>\n")); 31 *v = viewer; 32 PetscFunctionReturn(PETSC_SUCCESS); 33 } 34 35 static PetscErrorCode private_PetscViewerDestroy_XDMF(PetscViewer *v) 36 { 37 PetscViewer viewer; 38 DM dm = NULL; 39 long int *bytes; 40 PetscContainer container = NULL; 41 42 PetscFunctionBegin; 43 if (!v) PetscFunctionReturn(PETSC_SUCCESS); 44 viewer = *v; 45 46 PetscCall(PetscObjectQuery((PetscObject)viewer, "DMSwarm", (PetscObject *)&dm)); 47 if (dm) { 48 PetscCall(PetscViewerASCIIPrintf(viewer, "</Grid>\n")); 49 PetscCall(PetscViewerASCIIPopTab(viewer)); 50 } 51 52 /* close xdmf header */ 53 PetscCall(PetscViewerASCIIPrintf(viewer, "</Domain>\n")); 54 PetscCall(PetscViewerASCIIPopTab(viewer)); 55 PetscCall(PetscViewerASCIIPrintf(viewer, "</Xdmf>\n")); 56 57 PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container)); 58 if (container) { 59 PetscCall(PetscContainerGetPointer(container, (void **)&bytes)); 60 PetscCall(PetscFree(bytes)); 61 PetscCall(PetscContainerDestroy(&container)); 62 } 63 PetscCall(PetscViewerDestroy(&viewer)); 64 *v = NULL; 65 PetscFunctionReturn(PETSC_SUCCESS); 66 } 67 68 static PetscErrorCode private_CreateDataFileNameXDMF(const char filename[], char dfilename[]) 69 { 70 const char dot_xmf[] = ".xmf"; 71 size_t len; 72 char viewername_minus_ext[PETSC_MAX_PATH_LEN]; 73 PetscBool flg; 74 75 PetscFunctionBegin; 76 PetscCall(PetscStrendswith(filename, dot_xmf, &flg)); 77 PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "File extension must be %s", dot_xmf); 78 PetscCall(PetscStrncpy(viewername_minus_ext, filename, sizeof(viewername_minus_ext))); 79 PetscCall(PetscStrlen(filename, &len)); 80 len -= sizeof(dot_xmf) - 1; 81 if (sizeof(viewername_minus_ext) > len) viewername_minus_ext[len] = '\0'; 82 PetscCall(PetscSNPrintf(dfilename, PETSC_MAX_PATH_LEN - 1, "%s_swarm_fields.pbin", viewername_minus_ext)); 83 PetscFunctionReturn(PETSC_SUCCESS); 84 } 85 86 static PetscErrorCode private_DMSwarmView_XDMF(DM dm, PetscViewer viewer) 87 { 88 PetscBool isswarm = PETSC_FALSE; 89 const char *viewername; 90 char datafile[PETSC_MAX_PATH_LEN]; 91 char *datafilename; 92 PetscViewer fviewer; 93 PetscInt k, ng, dim; 94 Vec dvec; 95 long int *bytes = NULL; 96 PetscContainer container = NULL; 97 const char *dmname; 98 99 PetscFunctionBegin; 100 PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container)); 101 if (container) { 102 PetscCall(PetscContainerGetPointer(container, (void **)&bytes)); 103 } else SETERRQ(PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Valid to find attached data XDMFViewerContext"); 104 105 PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMSWARM, &isswarm)); 106 PetscCheck(isswarm, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only valid for DMSwarm"); 107 108 PetscCall(PetscObjectCompose((PetscObject)viewer, "DMSwarm", (PetscObject)dm)); 109 110 PetscCall(PetscViewerASCIIPushTab(viewer)); 111 PetscCall(PetscObjectGetName((PetscObject)dm, &dmname)); 112 if (!dmname) PetscCall(DMGetOptionsPrefix(dm, &dmname)); 113 if (!dmname) { 114 PetscCall(PetscViewerASCIIPrintf(viewer, "<Grid Name=\"DMSwarm\" GridType=\"Uniform\">\n")); 115 } else { 116 PetscCall(PetscViewerASCIIPrintf(viewer, "<Grid Name=\"DMSwarm[%s]\" GridType=\"Uniform\">\n", dmname)); 117 } 118 119 /* create a sub-viewer for topology, geometry and all data fields */ 120 /* name is viewer.name + "_swarm_fields.pbin" */ 121 PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer)); 122 PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY)); 123 PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE)); 124 PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE)); 125 PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_WRITE)); 126 127 PetscCall(PetscViewerFileGetName(viewer, &viewername)); 128 PetscCall(private_CreateDataFileNameXDMF(viewername, datafile)); 129 PetscCall(PetscViewerFileSetName(fviewer, datafile)); 130 PetscCall(PetscStrrchr(datafile, '/', &datafilename)); 131 132 PetscCall(DMSwarmGetSize(dm, &ng)); 133 134 /* write topology header */ 135 PetscCall(PetscViewerASCIIPushTab(viewer)); 136 PetscCall(PetscViewerASCIIPrintf(viewer, "<Topology Dimensions=\"%" PetscInt_FMT "\" TopologyType=\"Mixed\">\n", ng)); 137 PetscCall(PetscViewerASCIIPushTab(viewer)); 138 PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", ng * 3, bytes[0])); 139 PetscCall(PetscViewerASCIIPushTab(viewer)); 140 PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename)); 141 PetscCall(PetscViewerASCIIPopTab(viewer)); 142 PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n")); 143 PetscCall(PetscViewerASCIIPopTab(viewer)); 144 PetscCall(PetscViewerASCIIPrintf(viewer, "</Topology>\n")); 145 PetscCall(PetscViewerASCIIPopTab(viewer)); 146 147 /* write topology data */ 148 for (k = 0; k < ng; k++) { 149 PetscInt pvertex[3]; 150 151 pvertex[0] = 1; 152 pvertex[1] = 1; 153 pvertex[2] = k; 154 PetscCall(PetscViewerBinaryWrite(fviewer, pvertex, 3, PETSC_INT)); 155 } 156 bytes[0] += sizeof(PetscInt) * ng * 3; 157 158 /* write geometry header */ 159 PetscCall(PetscViewerASCIIPushTab(viewer)); 160 PetscCall(DMGetDimension(dm, &dim)); 161 switch (dim) { 162 case 1: 163 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for 1D"); 164 case 2: 165 PetscCall(PetscViewerASCIIPrintf(viewer, "<Geometry Type=\"XY\">\n")); 166 break; 167 case 3: 168 PetscCall(PetscViewerASCIIPrintf(viewer, "<Geometry Type=\"XYZ\">\n")); 169 break; 170 } 171 PetscCall(PetscViewerASCIIPushTab(viewer)); 172 PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", ng, dim, bytes[0])); 173 PetscCall(PetscViewerASCIIPushTab(viewer)); 174 PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename)); 175 PetscCall(PetscViewerASCIIPopTab(viewer)); 176 PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n")); 177 PetscCall(PetscViewerASCIIPopTab(viewer)); 178 PetscCall(PetscViewerASCIIPrintf(viewer, "</Geometry>\n")); 179 PetscCall(PetscViewerASCIIPopTab(viewer)); 180 181 /* write geometry data */ 182 PetscCall(DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &dvec)); 183 PetscCall(VecView(dvec, fviewer)); 184 PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &dvec)); 185 bytes[0] += sizeof(PetscReal) * ng * dim; 186 187 PetscCall(PetscViewerDestroy(&fviewer)); 188 PetscFunctionReturn(PETSC_SUCCESS); 189 } 190 191 static PetscErrorCode private_VecView_Swarm_XDMF(Vec x, PetscViewer viewer) 192 { 193 long int *bytes = NULL; 194 PetscContainer container = NULL; 195 const char *viewername; 196 char datafile[PETSC_MAX_PATH_LEN]; 197 char *datafilename; 198 PetscViewer fviewer; 199 PetscInt N, bs; 200 const char *vecname; 201 char fieldname[PETSC_MAX_PATH_LEN]; 202 203 PetscFunctionBegin; 204 PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container)); 205 PetscCheck(container, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unable to find attached data XDMFViewerContext"); 206 PetscCall(PetscContainerGetPointer(container, (void **)&bytes)); 207 PetscCall(PetscViewerFileGetName(viewer, &viewername)); 208 PetscCall(private_CreateDataFileNameXDMF(viewername, datafile)); 209 210 /* re-open a sub-viewer for all data fields */ 211 /* name is viewer.name + "_swarm_fields.pbin" */ 212 PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer)); 213 PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY)); 214 PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE)); 215 PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE)); 216 PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_APPEND)); 217 PetscCall(PetscViewerFileSetName(fviewer, datafile)); 218 PetscCall(PetscStrrchr(datafile, '/', &datafilename)); 219 220 PetscCall(VecGetSize(x, &N)); 221 PetscCall(VecGetBlockSize(x, &bs)); 222 N = N / bs; 223 PetscCall(PetscObjectGetName((PetscObject)x, &vecname)); 224 if (!vecname) { 225 PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "swarmfield_%d", ((PetscObject)x)->tag)); 226 } else { 227 PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "%s", vecname)); 228 } 229 230 /* write data header */ 231 PetscCall(PetscViewerASCIIPushTab(viewer)); 232 PetscCall(PetscViewerASCIIPrintf(viewer, "<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n", fieldname)); 233 PetscCall(PetscViewerASCIIPushTab(viewer)); 234 if (bs == 1) { 235 PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bytes[0])); 236 } else { 237 PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bs, bytes[0])); 238 } 239 PetscCall(PetscViewerASCIIPushTab(viewer)); 240 PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename)); 241 PetscCall(PetscViewerASCIIPopTab(viewer)); 242 PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n")); 243 PetscCall(PetscViewerASCIIPopTab(viewer)); 244 PetscCall(PetscViewerASCIIPrintf(viewer, "</Attribute>\n")); 245 PetscCall(PetscViewerASCIIPopTab(viewer)); 246 247 /* write data */ 248 PetscCall(VecView(x, fviewer)); 249 bytes[0] += sizeof(PetscReal) * N * bs; 250 251 PetscCall(PetscViewerDestroy(&fviewer)); 252 PetscFunctionReturn(PETSC_SUCCESS); 253 } 254 255 static PetscErrorCode private_ISView_Swarm_XDMF(IS is, PetscViewer viewer) 256 { 257 long int *bytes = NULL; 258 PetscContainer container = NULL; 259 const char *viewername; 260 char datafile[PETSC_MAX_PATH_LEN]; 261 char *datafilename; 262 PetscViewer fviewer; 263 PetscInt N, bs; 264 const char *vecname; 265 char fieldname[PETSC_MAX_PATH_LEN]; 266 267 PetscFunctionBegin; 268 PetscCall(PetscObjectQuery((PetscObject)viewer, "XDMFViewerContext", (PetscObject *)&container)); 269 PetscCheck(container, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Unable to find attached data XDMFViewerContext"); 270 PetscCall(PetscContainerGetPointer(container, (void **)&bytes)); 271 PetscCall(PetscViewerFileGetName(viewer, &viewername)); 272 PetscCall(private_CreateDataFileNameXDMF(viewername, datafile)); 273 274 /* re-open a sub-viewer for all data fields */ 275 /* name is viewer.name + "_swarm_fields.pbin" */ 276 PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)viewer), &fviewer)); 277 PetscCall(PetscViewerSetType(fviewer, PETSCVIEWERBINARY)); 278 PetscCall(PetscViewerBinarySetSkipHeader(fviewer, PETSC_TRUE)); 279 PetscCall(PetscViewerBinarySetSkipInfo(fviewer, PETSC_TRUE)); 280 PetscCall(PetscViewerFileSetMode(fviewer, FILE_MODE_APPEND)); 281 PetscCall(PetscViewerFileSetName(fviewer, datafile)); 282 PetscCall(PetscStrrchr(datafile, '/', &datafilename)); 283 284 PetscCall(ISGetSize(is, &N)); 285 PetscCall(ISGetBlockSize(is, &bs)); 286 N = N / bs; 287 PetscCall(PetscObjectGetName((PetscObject)is, &vecname)); 288 if (!vecname) { 289 PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "swarmfield_%d", ((PetscObject)is)->tag)); 290 } else { 291 PetscCall(PetscSNPrintf(fieldname, PETSC_MAX_PATH_LEN - 1, "%s", vecname)); 292 } 293 294 /* write data header */ 295 PetscCall(PetscViewerASCIIPushTab(viewer)); 296 PetscCall(PetscViewerASCIIPrintf(viewer, "<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n", fieldname)); 297 PetscCall(PetscViewerASCIIPushTab(viewer)); 298 if (bs == 1) { 299 PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bytes[0])); 300 } else { 301 PetscCall(PetscViewerASCIIPrintf(viewer, "<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%" PetscInt_FMT " %" PetscInt_FMT "\" Seek=\"%ld\">\n", N, bs, bytes[0])); 302 } 303 PetscCall(PetscViewerASCIIPushTab(viewer)); 304 PetscCall(PetscViewerASCIIPrintf(viewer, "%s\n", datafilename)); 305 PetscCall(PetscViewerASCIIPopTab(viewer)); 306 PetscCall(PetscViewerASCIIPrintf(viewer, "</DataItem>\n")); 307 PetscCall(PetscViewerASCIIPopTab(viewer)); 308 PetscCall(PetscViewerASCIIPrintf(viewer, "</Attribute>\n")); 309 PetscCall(PetscViewerASCIIPopTab(viewer)); 310 311 /* write data */ 312 PetscCall(ISView(is, fviewer)); 313 bytes[0] += sizeof(PetscInt) * N * bs; 314 315 PetscCall(PetscViewerDestroy(&fviewer)); 316 PetscFunctionReturn(PETSC_SUCCESS); 317 } 318 319 /*@C 320 DMSwarmViewFieldsXDMF - Write a selection of DMSwarm fields to an XDMF3 file 321 322 Collective 323 324 Input Parameters: 325 + dm - the `DMSWARM` 326 . filename - the file name of the XDMF file (must have the extension .xmf) 327 . nfields - the number of fields to write into the XDMF file 328 - field_name_list - array of length nfields containing the textual name of fields to write 329 330 Level: beginner 331 332 Note: 333 Only fields registered with data type `PETSC_DOUBLE` or `PETSC_INT` can be written into the file 334 335 .seealso: `DM`, `DMSWARM`, `DMSwarmViewXDMF()` 336 @*/ 337 PETSC_EXTERN PetscErrorCode DMSwarmViewFieldsXDMF(DM dm, const char filename[], PetscInt nfields, const char *field_name_list[]) 338 { 339 Vec dvec; 340 PetscInt f, N; 341 PetscViewer viewer; 342 343 PetscFunctionBegin; 344 PetscCall(private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm), filename, &viewer)); 345 PetscCall(private_DMSwarmView_XDMF(dm, viewer)); 346 PetscCall(DMSwarmGetLocalSize(dm, &N)); 347 for (f = 0; f < nfields; f++) { 348 void *data; 349 PetscDataType type; 350 351 PetscCall(DMSwarmGetField(dm, field_name_list[f], NULL, &type, &data)); 352 PetscCall(DMSwarmRestoreField(dm, field_name_list[f], NULL, &type, &data)); 353 if (type == PETSC_DOUBLE) { 354 PetscCall(DMSwarmCreateGlobalVectorFromField(dm, field_name_list[f], &dvec)); 355 PetscCall(PetscObjectSetName((PetscObject)dvec, field_name_list[f])); 356 PetscCall(private_VecView_Swarm_XDMF(dvec, viewer)); 357 PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, field_name_list[f], &dvec)); 358 } else if (type == PETSC_INT) { 359 IS is; 360 const PetscInt *idx; 361 362 PetscCall(DMSwarmGetField(dm, field_name_list[f], NULL, &type, &data)); 363 idx = (const PetscInt *)data; 364 365 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), N, idx, PETSC_USE_POINTER, &is)); 366 PetscCall(PetscObjectSetName((PetscObject)is, field_name_list[f])); 367 PetscCall(private_ISView_Swarm_XDMF(is, viewer)); 368 PetscCall(ISDestroy(&is)); 369 PetscCall(DMSwarmRestoreField(dm, field_name_list[f], NULL, &type, &data)); 370 } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Can only write PETSC_INT and PETSC_DOUBLE"); 371 } 372 PetscCall(private_PetscViewerDestroy_XDMF(&viewer)); 373 PetscFunctionReturn(PETSC_SUCCESS); 374 } 375 376 /*@C 377 DMSwarmViewXDMF - Write `DMSWARM` fields to an XDMF3 file 378 379 Collective 380 381 Input Parameters: 382 + dm - the `DMSWARM` 383 - filename - the file name of the XDMF file (must have the extension .xmf) 384 385 Level: beginner 386 387 Note: 388 Only fields user registered with data type `PETSC_DOUBLE` or `PETSC_INT` will be written into the file 389 390 Developer Note: 391 This should be removed and replaced with the standard use of `PetscViewer` 392 393 .seealso: `DM`, `DMSWARM`, `DMSwarmViewFieldsXDMF()` 394 @*/ 395 PETSC_EXTERN PetscErrorCode DMSwarmViewXDMF(DM dm, const char filename[]) 396 { 397 DM_Swarm *swarm = (DM_Swarm *)dm->data; 398 Vec dvec; 399 PetscInt f; 400 PetscViewer viewer; 401 402 PetscFunctionBegin; 403 PetscCall(private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm), filename, &viewer)); 404 PetscCall(private_DMSwarmView_XDMF(dm, viewer)); 405 for (f = 4; f < swarm->db->nfields; f++) { /* only examine user defined fields - the first 4 are internally created by DMSwarmPIC */ 406 DMSwarmDataField field; 407 408 /* query field type - accept all those of type PETSC_DOUBLE */ 409 field = swarm->db->field[f]; 410 if (field->petsc_type == PETSC_DOUBLE) { 411 PetscCall(DMSwarmCreateGlobalVectorFromField(dm, field->name, &dvec)); 412 PetscCall(PetscObjectSetName((PetscObject)dvec, field->name)); 413 PetscCall(private_VecView_Swarm_XDMF(dvec, viewer)); 414 PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, field->name, &dvec)); 415 } else if (field->petsc_type == PETSC_INT) { 416 IS is; 417 PetscInt N; 418 const PetscInt *idx; 419 void *data; 420 421 PetscCall(DMSwarmGetLocalSize(dm, &N)); 422 PetscCall(DMSwarmGetField(dm, field->name, NULL, NULL, &data)); 423 idx = (const PetscInt *)data; 424 425 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), N, idx, PETSC_USE_POINTER, &is)); 426 PetscCall(PetscObjectSetName((PetscObject)is, field->name)); 427 PetscCall(private_ISView_Swarm_XDMF(is, viewer)); 428 PetscCall(ISDestroy(&is)); 429 PetscCall(DMSwarmRestoreField(dm, field->name, NULL, NULL, &data)); 430 } 431 } 432 PetscCall(private_PetscViewerDestroy_XDMF(&viewer)); 433 PetscFunctionReturn(PETSC_SUCCESS); 434 } 435