Actual source code: ex5.c

petsc-master 2021-01-19
Report Typos and Errors
  1: static char help[] = "Demonstrate HDF5/XDMF load-save-reload cycle\n\n";

  3: #include <petscdmplex.h>
  4: #include <petscviewerhdf5.h>
  5: #define EX "ex5.c"

  7: typedef struct {
  8:   char              infile[PETSC_MAX_PATH_LEN];  /* Input mesh filename */
  9:   char              outfile[PETSC_MAX_PATH_LEN]; /* Dump/reload mesh filename */
 10:   PetscViewerFormat informat;                    /* Input mesh format */
 11:   PetscViewerFormat outformat;                   /* Dump/reload mesh format */
 12:   PetscBool         redistribute;                /* Redistribute the mesh */
 13:   PetscInt          ntimes;                      /* How many times do the cycle */
 14: } AppCtx;

 16: static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
 17: {
 18:   PetscBool      flg;

 22:   options->infile[0]    = '\0';
 23:   options->outfile[0]   = '\0';
 24:   options->informat     = PETSC_VIEWER_HDF5_XDMF;
 25:   options->outformat    = PETSC_VIEWER_HDF5_XDMF;
 26:   options->redistribute = PETSC_TRUE;
 27:   options->ntimes       = 2;
 28:   PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");
 29:   PetscOptionsString("-infile", "The input mesh file", EX, options->infile, options->infile, sizeof(options->infile), &flg);
 30:   if (!flg) SETERRQ(comm, PETSC_ERR_USER_INPUT, "-infile needs to be specified");
 31:   PetscOptionsString("-outfile", "The output mesh file (by default it's the same as infile)", EX, options->outfile, options->outfile, sizeof(options->outfile), &flg);
 32:   if (!flg) SETERRQ(comm, PETSC_ERR_USER_INPUT, "-outfile needs to be specified");
 33:   PetscOptionsEnum("-informat", "Input mesh format", EX, PetscViewerFormats, (PetscEnum)options->informat, (PetscEnum*)&options->informat, NULL);
 34:   PetscOptionsEnum("-outformat", "Dump/reload mesh format", EX, PetscViewerFormats, (PetscEnum)options->outformat, (PetscEnum*)&options->outformat, NULL);
 35:   PetscOptionsBool("-redistribute", "Redistribute the mesh", EX, options->redistribute, &options->redistribute, NULL);
 36:   PetscOptionsInt("-ntimes", "How many times do the cycle", EX, options->ntimes, &options->ntimes, NULL);
 37:   PetscOptionsEnd();
 38:   return(0);
 39: };

 41: //TODO test DMLabel I/O (not yet working for PETSC_VIEWER_HDF5_XDMF)
 42: int main(int argc, char **argv)
 43: {
 44:   AppCtx            user;
 45:   PetscInt          i;
 46:   PetscBool         flg;
 47:   MPI_Comm          comm;
 48:   PetscMPIInt       size;
 49:   PetscErrorCode    ierr;
 50:   const char        *filename;
 51:   PetscViewerFormat format;

 53:   PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr;
 54:   comm = PETSC_COMM_WORLD;
 55:   MPI_Comm_size(comm, &size);
 56:   ProcessOptions(comm, &user);

 58:   /* Use infile for the initial load */
 59:   filename = user.infile;
 60:   format   = user.informat;

 62:   for (i=0; i<user.ntimes; i++) {
 63:     DM                dm;
 64:     PetscPartitioner  part;
 65:     PetscViewer       v;

 67:     PetscPrintf(comm, "Begin cycle %D\n",i);

 69:     /* Load data from XDMF into dm in parallel */
 70:     /* We could also use
 71:         DMPlexCreateFromFile(PETSC_COMM_WORLD, user.filename, PETSC_TRUE, &dm);
 72:       This currently support a few more formats than DMLoad().
 73:     */
 74:     PetscViewerHDF5Open(comm, filename, FILE_MODE_READ, &v);
 75:     PetscViewerPushFormat(v, format);
 76:     DMCreate(comm, &dm);
 77:     DMSetType(dm, DMPLEX);
 78:     DMSetOptionsPrefix(dm,"loaded_");
 79:     DMLoad(dm, v);
 80:     DMSetFromOptions(dm);
 81:     DMViewFromOptions(dm, NULL, "-dm_view");
 82:     PetscViewerPopFormat(v);
 83:     PetscViewerDestroy(&v);

 85:     /* Use outfile for all I/O except the very initial load */
 86:     filename = user.outfile;
 87:     format   = user.outformat;

 89:     /* We just test/demonstrate DM is indeed distributed - unneeded in the application code */
 90:     DMPlexIsDistributed(dm, &flg);
 91:     PetscPrintf(comm, "Loaded mesh distributed? %s\n", PetscBools[flg]);

 93:     /* Interpolate */
 94:     //TODO we want to be able to do this from options in DMSetFromOptions() probably
 95:     //TODO we want to be able to do this in-place
 96:     {
 97:       DM idm;

 99:       DMPlexInterpolate(dm, &idm);
100:       DMDestroy(&dm);
101:       dm   = idm;
102:         DMSetOptionsPrefix(dm,"interpolated_");
103:         DMSetFromOptions(dm);
104:         DMViewFromOptions(dm, NULL, "-dm_view");
105:     }

107:     /* Redistribute */
108:     //TODO we want to be able to do this from options in DMSetFromOptions() probably
109:     if (user.redistribute) {
110:       DM dmdist;

112:       DMPlexGetPartitioner(dm, &part);
113:       PetscPartitionerSetFromOptions(part);
114:       DMPlexDistribute(dm, 0, NULL, &dmdist);
115:       //TODO we want to be able to do this in-place
116:       if (dmdist) {
117:         DMDestroy(&dm);
118:         dm   = dmdist;
119:         DMSetOptionsPrefix(dm,"redistributed_");
120:         DMSetFromOptions(dm);
121:         DMViewFromOptions(dm, NULL, "-dm_view");
122:       }
123:     }

125:     /* Save redistributed dm to XDMF in parallel and destroy it */
126:     PetscViewerHDF5Open(comm, user.outfile, FILE_MODE_WRITE, &v);
127:     PetscViewerPushFormat(v, format);
128:     DMView(dm, v);
129:     PetscViewerPopFormat(v);
130:     PetscViewerDestroy(&v);
131:     DMDestroy(&dm);

133:     PetscPrintf(comm, "End   cycle %D\n--------\n",i);
134:   }

136:   /* Final clean-up */
137:   PetscFinalize();
138:   return ierr;
139: }

141: /*TEST
142:   build:
143:     requires: hdf5
144:   testset:
145:     suffix: 0
146:     requires: !complex
147:     nsize: {{2 4}}
148:     args: -infile ${wPETSC_DIR}/share/petsc/datafiles/meshes/blockcylinder-50.h5 -informat hdf5_xdmf
149:     args: -outfile ex5_dump.h5 -outformat {{hdf5_xdmf hdf5_petsc}separate output}
150:     args: -ntimes 3
151:     test:
152:       # this partitioner should not shuffle anything, it should yield the same partititioning as the XDMF reader - added just for testing
153:       suffix: simple
154:       args: -petscpartitioner_type simple
155:     test:
156:       suffix: parmetis
157:       requires: parmetis
158:       args: -petscpartitioner_type parmetis
159:     test:
160:       suffix: ptscotch
161:       requires: ptscotch
162:       args: -petscpartitioner_type ptscotch
163: TEST*/