Date: 2022-03-31T04:47:39+00:00

Actual source code: swarmpic_view.c

      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"

      7: PetscErrorCode private_PetscViewerCreate_XDMF(MPI_Comm comm,const char filename[],PetscViewer *v)
      8: {
      9:   long int       *bytes;
     10:   PetscContainer container;
     11:   PetscViewer    viewer;

     13:   PetscViewerCreate(comm,&viewer);
     14:   PetscViewerSetType(viewer,PETSCVIEWERASCII);
     15:   PetscViewerFileSetMode(viewer,FILE_MODE_WRITE);
     16:   PetscViewerFileSetName(viewer,filename);

     18:   PetscMalloc1(1,&bytes);
     19:   bytes[0] = 0;
     20:   PetscContainerCreate(comm,&container);
     21:   PetscContainerSetPointer(container,(void*)bytes);
     22:   PetscObjectCompose((PetscObject)viewer,"XDMFViewerContext",(PetscObject)container);

     24:   /* write xdmf header */
     25:   PetscViewerASCIIPrintf(viewer,"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
     26:   PetscViewerASCIIPrintf(viewer,"<Xdmf xmlns:xi=\"http://www.w3.org/2001/XInclude/\" Version=\"2.99\">\n");
     27:   /* write xdmf domain */
     28:   PetscViewerASCIIPushTab(viewer);
     29:   PetscViewerASCIIPrintf(viewer,"<Domain>\n");
     30:   *v = viewer;
     31:   return 0;
     32: }

     34: PetscErrorCode private_PetscViewerDestroy_XDMF(PetscViewer *v)
     35: {
     36:   PetscViewer    viewer;
     37:   DM             dm = NULL;
     38:   long int       *bytes;
     39:   PetscContainer container = NULL;

     41:   if (!v) return 0;
     42:   viewer = *v;

     44:   PetscObjectQuery((PetscObject)viewer,"DMSwarm",(PetscObject*)&dm);
     45:   if (dm) {
     46:     PetscViewerASCIIPrintf(viewer,"</Grid>\n");
     47:     PetscViewerASCIIPopTab(viewer);
     48:   }

     50:   /* close xdmf header */
     51:   PetscViewerASCIIPrintf(viewer,"</Domain>\n");
     52:   PetscViewerASCIIPopTab(viewer);
     53:   PetscViewerASCIIPrintf(viewer,"</Xdmf>\n");

     55:   PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);
     56:   if (container) {
     57:     PetscContainerGetPointer(container,(void**)&bytes);
     58:     PetscFree(bytes);
     59:     PetscContainerDestroy(&container);
     60:   }
     61:   PetscViewerDestroy(&viewer);
     62:   *v = NULL;
     63:   return 0;
     64: }

     66: PetscErrorCode private_CreateDataFileNameXDMF(const char filename[],char dfilename[])
     67: {
     68:   char           *ext;
     69:   PetscBool      flg;

     71:   PetscStrrchr(filename,'.',&ext);
     72:   PetscStrcmp("xmf",ext,&flg);
     73:   if (flg) {
     74:     size_t len;
     75:     char    viewername_minus_ext[PETSC_MAX_PATH_LEN];

     77:     PetscStrlen(filename,&len);
     78:     PetscStrncpy(viewername_minus_ext,filename,len-2);
     79:     PetscSNPrintf(dfilename,PETSC_MAX_PATH_LEN-1,"%s_swarm_fields.pbin",viewername_minus_ext);
     80:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"File extension must by .xmf");
     81:   return 0;
     82: }

     84: PetscErrorCode private_DMSwarmView_XDMF(DM dm,PetscViewer viewer)
     85: {
     86:   PetscBool      isswarm = PETSC_FALSE;
     87:   const char     *viewername;
     88:   char           datafile[PETSC_MAX_PATH_LEN];
     89:   char           *datafilename;
     90:   PetscViewer    fviewer;
     91:   PetscInt       k,ng,dim;
     92:   Vec            dvec;
     93:   long int       *bytes = NULL;
     94:   PetscContainer container = NULL;
     95:   const char     *dmname;

     97:   PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);
     98:   if (container) {
     99:     PetscContainerGetPointer(container,(void**)&bytes);
    100:   } else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Valid to find attached data XDMFViewerContext");

    102:   PetscObjectTypeCompare((PetscObject)dm,DMSWARM,&isswarm);

    105:   PetscObjectCompose((PetscObject)viewer,"DMSwarm",(PetscObject)dm);

    107:   PetscViewerASCIIPushTab(viewer);
    108:   PetscObjectGetName((PetscObject)dm,&dmname);
    109:   if (!dmname) {
    110:     DMGetOptionsPrefix(dm,&dmname);
    111:   }
    112:   if (!dmname) {
    113:     PetscViewerASCIIPrintf(viewer,"<Grid Name=\"DMSwarm\" GridType=\"Uniform\">\n");
    114:   } else {
    115:     PetscViewerASCIIPrintf(viewer,"<Grid Name=\"DMSwarm[%s]\" GridType=\"Uniform\">\n",dmname);
    116:   }

    118:   /* create a sub-viewer for topology, geometry and all data fields */
    119:   /* name is viewer.name + "_swarm_fields.pbin" */
    120:   PetscViewerCreate(PetscObjectComm((PetscObject)viewer),&fviewer);
    121:   PetscViewerSetType(fviewer,PETSCVIEWERBINARY);
    122:   PetscViewerBinarySetSkipHeader(fviewer,PETSC_TRUE);
    123:   PetscViewerBinarySetSkipInfo(fviewer,PETSC_TRUE);
    124:   PetscViewerFileSetMode(fviewer,FILE_MODE_WRITE);

    126:   PetscViewerFileGetName(viewer,&viewername);
    127:   private_CreateDataFileNameXDMF(viewername,datafile);
    128:   PetscViewerFileSetName(fviewer,datafile);
    129:   PetscStrrchr(datafile,'/',&datafilename);

    131:   DMSwarmGetSize(dm,&ng);

    133:   /* write topology header */
    134:   PetscViewerASCIIPushTab(viewer);
    135:   PetscViewerASCIIPrintf(viewer,"<Topology Dimensions=\"%D\" TopologyType=\"Mixed\">\n",ng);
    136:   PetscViewerASCIIPushTab(viewer);
    137:   PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Dimensions=\"%D\" Seek=\"%D\">\n",ng*3,bytes[0]);
    138:   PetscViewerASCIIPushTab(viewer);
    139:   PetscViewerASCIIPrintf(viewer,"%s\n",datafilename);
    140:   PetscViewerASCIIPopTab(viewer);
    141:   PetscViewerASCIIPrintf(viewer,"</DataItem>\n");
    142:   PetscViewerASCIIPopTab(viewer);
    143:   PetscViewerASCIIPrintf(viewer,"</Topology>\n");
    144:   PetscViewerASCIIPopTab(viewer);

    146:   /* write topology data */
    147:   for (k=0; k<ng; k++) {
    148:     PetscInt pvertex[3];

    150:     pvertex[0] = 1;
    151:     pvertex[1] = 1;
    152:     pvertex[2] = k;
    153:     PetscViewerBinaryWrite(fviewer,pvertex,3,PETSC_INT);
    154:   }
    155:   bytes[0] += sizeof(PetscInt) * ng * 3;

    157:   /* write geometry header */
    158:   PetscViewerASCIIPushTab(viewer);
    159:   DMGetDimension(dm,&dim);
    160:   switch (dim) {
    161:     case 1:
    162:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for 1D");
    163:     case 2:
    164:       PetscViewerASCIIPrintf(viewer,"<Geometry Type=\"XY\">\n");
    165:       break;
    166:     case 3:
    167:       PetscViewerASCIIPrintf(viewer,"<Geometry Type=\"XYZ\">\n");
    168:       break;
    169:   }
    170:   PetscViewerASCIIPushTab(viewer);
    171:   PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%D %D\" Seek=\"%D\">\n",ng,dim,bytes[0]);
    172:   PetscViewerASCIIPushTab(viewer);
    173:   PetscViewerASCIIPrintf(viewer,"%s\n",datafilename);
    174:   PetscViewerASCIIPopTab(viewer);
    175:   PetscViewerASCIIPrintf(viewer,"</DataItem>\n");
    176:   PetscViewerASCIIPopTab(viewer);
    177:   PetscViewerASCIIPrintf(viewer,"</Geometry>\n");
    178:   PetscViewerASCIIPopTab(viewer);

    180:   /* write geometry data */
    181:   DMSwarmCreateGlobalVectorFromField(dm,DMSwarmPICField_coor,&dvec);
    182:   VecView(dvec,fviewer);
    183:   DMSwarmDestroyGlobalVectorFromField(dm,DMSwarmPICField_coor,&dvec);
    184:   bytes[0] += sizeof(PetscReal) * ng * dim;

    186:   PetscViewerDestroy(&fviewer);
    187:   return 0;
    188: }

    190: PetscErrorCode private_VecView_Swarm_XDMF(Vec x,PetscViewer viewer)
    191: {
    192:   long int       *bytes = NULL;
    193:   PetscContainer container = NULL;
    194:   const char     *viewername;
    195:   char           datafile[PETSC_MAX_PATH_LEN];
    196:   char           *datafilename;
    197:   PetscViewer    fviewer;
    198:   PetscInt       N,bs;
    199:   const char     *vecname;
    200:   char           fieldname[PETSC_MAX_PATH_LEN];

    202:   PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);
    204:   PetscContainerGetPointer(container,(void**)&bytes);
    205:   PetscViewerFileGetName(viewer,&viewername);
    206:   private_CreateDataFileNameXDMF(viewername,datafile);

    208:   /* re-open a sub-viewer for all data fields */
    209:   /* name is viewer.name + "_swarm_fields.pbin" */
    210:   PetscViewerCreate(PetscObjectComm((PetscObject)viewer),&fviewer);
    211:   PetscViewerSetType(fviewer,PETSCVIEWERBINARY);
    212:   PetscViewerBinarySetSkipHeader(fviewer,PETSC_TRUE);
    213:   PetscViewerBinarySetSkipInfo(fviewer,PETSC_TRUE);
    214:   PetscViewerFileSetMode(fviewer,FILE_MODE_APPEND);
    215:   PetscViewerFileSetName(fviewer,datafile);
    216:   PetscStrrchr(datafile,'/',&datafilename);

    218:   VecGetSize(x,&N);
    219:   VecGetBlockSize(x,&bs);
    220:   N = N/bs;
    221:   PetscObjectGetName((PetscObject)x,&vecname);
    222:   if (!vecname) {
    223:     PetscSNPrintf(fieldname,PETSC_MAX_PATH_LEN-1,"swarmfield_%D",((PetscObject)x)->tag);
    224:   } else {
    225:     PetscSNPrintf(fieldname,PETSC_MAX_PATH_LEN-1,"%s",vecname);
    226:   }

    228:   /* write data header */
    229:   PetscViewerASCIIPushTab(viewer);
    230:   PetscViewerASCIIPrintf(viewer,"<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n",fieldname);
    231:   PetscViewerASCIIPushTab(viewer);
    232:   if (bs == 1) {
    233:     PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%D\" Seek=\"%D\">\n",N,bytes[0]);
    234:   } else {
    235:     PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%D %D\" Seek=\"%D\">\n",N,bs,bytes[0]);
    236:   }
    237:   PetscViewerASCIIPushTab(viewer);
    238:   PetscViewerASCIIPrintf(viewer,"%s\n",datafilename);
    239:   PetscViewerASCIIPopTab(viewer);
    240:   PetscViewerASCIIPrintf(viewer,"</DataItem>\n");
    241:   PetscViewerASCIIPopTab(viewer);
    242:   PetscViewerASCIIPrintf(viewer,"</Attribute>\n");
    243:   PetscViewerASCIIPopTab(viewer);

    245:   /* write data */
    246:   VecView(x,fviewer);
    247:   bytes[0] += sizeof(PetscReal) * N * bs;

    249:   PetscViewerDestroy(&fviewer);
    250:   return 0;
    251: }

    253: PetscErrorCode private_ISView_Swarm_XDMF(IS is,PetscViewer viewer)
    254: {
    255:   long int       *bytes = NULL;
    256:   PetscContainer container = NULL;
    257:   const char     *viewername;
    258:   char           datafile[PETSC_MAX_PATH_LEN];
    259:   char           *datafilename;
    260:   PetscViewer    fviewer;
    261:   PetscInt       N,bs;
    262:   const char     *vecname;
    263:   char           fieldname[PETSC_MAX_PATH_LEN];

    265:   PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);
    267:   PetscContainerGetPointer(container,(void**)&bytes);
    268:   PetscViewerFileGetName(viewer,&viewername);
    269:   private_CreateDataFileNameXDMF(viewername,datafile);

    271:   /* re-open a sub-viewer for all data fields */
    272:   /* name is viewer.name + "_swarm_fields.pbin" */
    273:   PetscViewerCreate(PetscObjectComm((PetscObject)viewer),&fviewer);
    274:   PetscViewerSetType(fviewer,PETSCVIEWERBINARY);
    275:   PetscViewerBinarySetSkipHeader(fviewer,PETSC_TRUE);
    276:   PetscViewerBinarySetSkipInfo(fviewer,PETSC_TRUE);
    277:   PetscViewerFileSetMode(fviewer,FILE_MODE_APPEND);
    278:   PetscViewerFileSetName(fviewer,datafile);
    279:   PetscStrrchr(datafile,'/',&datafilename);

    281:   ISGetSize(is,&N);
    282:   ISGetBlockSize(is,&bs);
    283:   N = N/bs;
    284:   PetscObjectGetName((PetscObject)is,&vecname);
    285:   if (!vecname) {
    286:     PetscSNPrintf(fieldname,PETSC_MAX_PATH_LEN-1,"swarmfield_%D",((PetscObject)is)->tag);
    287:   } else {
    288:     PetscSNPrintf(fieldname,PETSC_MAX_PATH_LEN-1,"%s",vecname);
    289:   }

    291:   /* write data header */
    292:   PetscViewerASCIIPushTab(viewer);
    293:   PetscViewerASCIIPrintf(viewer,"<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n",fieldname);
    294:   PetscViewerASCIIPushTab(viewer);
    295:   if (bs == 1) {
    296:     PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%D\" Seek=\"%D\">\n",N,bytes[0]);
    297:   } else {
    298:     PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%D %D\" Seek=\"%D\">\n",N,bs,bytes[0]);
    299:   }
    300:   PetscViewerASCIIPushTab(viewer);
    301:   PetscViewerASCIIPrintf(viewer,"%s\n",datafilename);
    302:   PetscViewerASCIIPopTab(viewer);
    303:   PetscViewerASCIIPrintf(viewer,"</DataItem>\n");
    304:   PetscViewerASCIIPopTab(viewer);
    305:   PetscViewerASCIIPrintf(viewer,"</Attribute>\n");
    306:   PetscViewerASCIIPopTab(viewer);

    308:   /* write data */
    309:   ISView(is,fviewer);
    310:   bytes[0] += sizeof(PetscInt) * N * bs;

    312:   PetscViewerDestroy(&fviewer);
    313:   return 0;
    314: }

    316: /*@C
    317:    DMSwarmViewFieldsXDMF - Write a selection of DMSwarm fields to an XDMF3 file

    319:    Collective on dm

    321:    Input parameters:
    322: +  dm - the DMSwarm
    323: .  filename - the file name of the XDMF file (must have the extension .xmf)
    324: .  nfields - the number of fields to write into the XDMF file
    325: -  field_name_list - array of length nfields containing the textual name of fields to write

    327:    Level: beginner

    329:    Notes:
    330:    Only fields registered with data type PETSC_DOUBLE or PETSC_INT can be written into the file

    332: .seealso: DMSwarmViewXDMF()
    333: @*/
    334: PETSC_EXTERN PetscErrorCode DMSwarmViewFieldsXDMF(DM dm,const char filename[],PetscInt nfields,const char *field_name_list[])
    335: {
    336:   Vec            dvec;
    337:   PetscInt       f,N;
    338:   PetscViewer    viewer;

    340:   private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm),filename,&viewer);
    341:   private_DMSwarmView_XDMF(dm,viewer);
    342:   DMSwarmGetLocalSize(dm,&N);
    343:   for (f=0; f<nfields; f++) {
    344:     void          *data;
    345:     PetscDataType type;

    347:     DMSwarmGetField(dm,field_name_list[f],NULL,&type,&data);
    348:     DMSwarmRestoreField(dm,field_name_list[f],NULL,&type,&data);
    349:     if (type == PETSC_DOUBLE) {
    350:       DMSwarmCreateGlobalVectorFromField(dm,field_name_list[f],&dvec);
    351:       PetscObjectSetName((PetscObject)dvec,field_name_list[f]);
    352:       private_VecView_Swarm_XDMF(dvec,viewer);
    353:       DMSwarmDestroyGlobalVectorFromField(dm,field_name_list[f],&dvec);
    354:     } else if (type == PETSC_INT) {
    355:       IS is;
    356:       const PetscInt *idx;

    358:       DMSwarmGetField(dm,field_name_list[f],NULL,&type,&data);
    359:       idx = (const PetscInt*)data;

    361:       ISCreateGeneral(PetscObjectComm((PetscObject)dm),N,idx,PETSC_USE_POINTER,&is);
    362:       PetscObjectSetName((PetscObject)is,field_name_list[f]);
    363:       private_ISView_Swarm_XDMF(is,viewer);
    364:       ISDestroy(&is);
    365:       DMSwarmRestoreField(dm,field_name_list[f],NULL,&type,&data);
    366:     } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Can only write PETSC_INT and PETSC_DOUBLE");

    368:   }
    369:   private_PetscViewerDestroy_XDMF(&viewer);
    370:   return 0;
    371: }

    373: /*@C
    374:    DMSwarmViewXDMF - Write DMSwarm fields to an XDMF3 file

    376:    Collective on dm

    378:    Input parameters:
    379: +  dm - the DMSwarm
    380: -  filename - the file name of the XDMF file (must have the extension .xmf)

    382:    Level: beginner

    384:    Notes:
    385:      Only fields user registered with data type PETSC_DOUBLE or PETSC_INT will be written into the file

    387:    Developer Notes:
    388:      This should be removed and replaced with the standard use of PetscViewer

    390: .seealso: DMSwarmViewFieldsXDMF()
    391: @*/
    392: PETSC_EXTERN PetscErrorCode DMSwarmViewXDMF(DM dm,const char filename[])
    393: {
    394:   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
    395:   Vec            dvec;
    396:   PetscInt       f;
    397:   PetscViewer    viewer;

    399:   private_PetscViewerCreate_XDMF(PetscObjectComm((PetscObject)dm),filename,&viewer);
    400:   private_DMSwarmView_XDMF(dm,viewer);
    401:   for (f=4; f<swarm->db->nfields; f++) { /* only examine user defined fields - the first 4 are internally created by DMSwarmPIC */
    402:     DMSwarmDataField field;

    404:     /* query field type - accept all those of type PETSC_DOUBLE */
    405:     field = swarm->db->field[f];
    406:     if (field->petsc_type == PETSC_DOUBLE) {
    407:       DMSwarmCreateGlobalVectorFromField(dm,field->name,&dvec);
    408:       PetscObjectSetName((PetscObject)dvec,field->name);
    409:       private_VecView_Swarm_XDMF(dvec,viewer);
    410:       DMSwarmDestroyGlobalVectorFromField(dm,field->name,&dvec);
    411:     } else if (field->petsc_type == PETSC_INT) {
    412:       IS             is;
    413:       PetscInt       N;
    414:       const PetscInt *idx;
    415:       void           *data;

    417:       DMSwarmGetLocalSize(dm,&N);
    418:       DMSwarmGetField(dm,field->name,NULL,NULL,&data);
    419:       idx = (const PetscInt*)data;

    421:       ISCreateGeneral(PetscObjectComm((PetscObject)dm),N,idx,PETSC_USE_POINTER,&is);
    422:       PetscObjectSetName((PetscObject)is,field->name);
    423:       private_ISView_Swarm_XDMF(is,viewer);
    424:       ISDestroy(&is);
    425:       DMSwarmRestoreField(dm,field->name,NULL,NULL,&data);
    426:     }
    427:   }
    428:   private_PetscViewerDestroy_XDMF(&viewer);
    429:   return 0;
    430: }