Actual source code: plexhdf5xdmf.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      1:  #include <petsc/private/dmpleximpl.h>
      2:  #include <petsc/private/isimpl.h>
      3:  #include <petsc/private/vecimpl.h>
      4: #include <petscviewerhdf5.h>

      6: #if defined(PETSC_HAVE_HDF5)
      7: PetscErrorCode DMPlexLoad_HDF5_Xdmf_Internal(DM dm, PetscViewer viewer)
      8: {
      9:   Vec             coordinates;
     10:   IS              cells;
     11:   PetscInt        dim, spatialDim, N, numCells, numVertices, numCorners, bs;
     12:   PetscMPIInt     rank;
     13:   MPI_Comm        comm;
     14:   PetscErrorCode  ierr;

     17:   PetscObjectGetComm((PetscObject)dm, &comm);
     18:   MPI_Comm_rank(comm, &rank);

     20:   /* Read topology */
     21:   PetscViewerHDF5ReadAttribute(viewer, "/viz/topology/cells", "cell_dim", PETSC_INT, (void *) &dim);
     22:   PetscViewerHDF5ReadAttribute(viewer, "/viz/topology/cells", "cell_corners", PETSC_INT, (void *) &numCorners);
     23:   PetscViewerHDF5PushGroup(viewer, "/viz/topology");
     24:   ISCreate(comm, &cells);
     25:   PetscObjectSetName((PetscObject) cells, "cells");
     26:   ISLoad(cells, viewer);
     27:   ISGetLocalSize(cells, &numCells);
     28:   ISGetBlockSize(cells, &bs);
     29:   if (bs != numCorners) SETERRQ(comm, PETSC_ERR_FILE_UNEXPECTED, "cell_corners and 2-dimension of cells not equal");
     30:   PetscViewerHDF5PopGroup(viewer);
     31:   numCells /= numCorners;

     33:   /* Read geometry */
     34:   PetscViewerHDF5PushGroup(viewer, "/geometry");
     35:   VecCreate(comm, &coordinates);
     36:   PetscObjectSetName((PetscObject) coordinates, "vertices");
     37:   PetscViewerHDF5ReadSizes(viewer, "vertices", &spatialDim, &N);
     38:   VecSetSizes(coordinates, PETSC_DECIDE, N);
     39:   VecSetBlockSize(coordinates, spatialDim);
     40:   VecLoad(coordinates, viewer);
     41:   VecGetLocalSize(coordinates, &numVertices);
     42:   VecGetBlockSize(coordinates, &spatialDim);
     43:   PetscViewerHDF5PopGroup(viewer);
     44:   numVertices /= spatialDim;

     46: #if defined(PETSC_USE_DEBUG)
     47:   /* Check that maximum index referred in cells is in line with global number of vertices */
     48:   {
     49:     PetscInt max1, max2;
     50:     ISGetMinMax(cells, NULL, &max1);
     51:     VecGetSize(coordinates, &max2);
     52:     max2 /= spatialDim; max2--;
     53:     if (max1 > max2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "maximum index in cells = %d > %d = total number of vertices - 1", max1, max2);
     54:   }
     55: #endif

     57:   {
     58:     const PetscScalar *coordinates_arr;
     59:     PetscReal *coordinates_arr_real;
     60:     const PetscInt *cells_arr;
     61:     int *cells_arr_int;
     62:     PetscSF sfVert=NULL;
     63: #if defined(PETSC_USE_64BIT_INDICES) || defined(PETSC_USE_COMPLEX)
     64:     PetscInt i;
     65: #endif

     67:     VecGetArrayRead(coordinates, &coordinates_arr);
     68:     ISGetIndices(cells, &cells_arr);

     70: #if defined(PETSC_USE_64BIT_INDICES)
     71:     /* convert to 32-bit integers if PetscInt is 64-bit */
     72:     /*TODO More systematic would be to change all the function arguments to PetscInt */
     73:     PetscMalloc1(numCells*numCorners, &cells_arr_int);
     74:     for (i = 0; i < numCells*numCorners; ++i) {
     75:       PetscMPIIntCast(cells_arr[i], &cells_arr_int[i]);
     76:     }
     77: #else
     78:     cells_arr_int = (int*)cells_arr;
     79: #endif

     81: #if defined(PETSC_USE_COMPLEX)
     82:     /* convert to real numbers if PetscScalar is complex */
     83:     /*TODO More systematic would be to change all the function arguments to PetscScalar */
     84:     PetscMalloc1(numVertices*spatialDim, &coordinates_arr_real);
     85:     for (i = 0; i < numVertices*spatialDim; ++i) {
     86:       coordinates_arr_real[i] = PetscRealPart(coordinates_arr[i]);
     87: #if defined(PETSC_USE_DEBUG)
     88:       if (PetscImaginaryPart(coordinates_arr[i])) {
     89:         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Vector of coordinates contains complex numbers but only real vectors are currently supported.");
     90:       }
     91: #endif  /* defined(PETSC_USE_DEBUG) */
     92:     }
     93: #else
     94:     coordinates_arr_real = (PetscReal*)coordinates_arr;
     95: #endif

     97:     DMSetDimension(dm, dim);
     98:     DMPlexBuildFromCellList_Parallel_Internal(dm, spatialDim, numCells, numVertices, numCorners, cells_arr_int, PETSC_TRUE, &sfVert);
     99:     DMPlexBuildCoordinates_Parallel_Internal( dm, spatialDim, numCells, numVertices, sfVert, coordinates_arr_real);
    100:     VecRestoreArrayRead(coordinates, &coordinates_arr);
    101:     ISRestoreIndices(cells, &cells_arr);
    102:     PetscSFDestroy(&sfVert);
    103: #if defined(PETSC_USE_64BIT_INDICES)
    104:     PetscFree(cells_arr_int);
    105: #endif
    106: #if defined(PETSC_USE_COMPLEX)
    107:     PetscFree(coordinates_arr_real);
    108: #endif
    109:   }
    110:   ISDestroy(&cells);
    111:   VecDestroy(&coordinates);

    113:   /* scale coordinates - unlike in DMPlexLoad_HDF5_Internal, this can only be done after DM is populated */
    114:   {
    115:     PetscReal lengthScale;

    117:     DMPlexGetScale(dm, PETSC_UNIT_LENGTH, &lengthScale);
    118:     DMGetCoordinates(dm, &coordinates);
    119:     VecScale(coordinates, 1.0/lengthScale);
    120:   }

    122:   /* Read Labels */
    123:   /* TODO: this probably does not work as elements get permuted */
    124:   /* DMPlexLoadLabels_HDF5_Internal(dm, viewer); */
    125:   return(0);
    126: }
    127: #endif