Actual source code: plexhdf5xdmf.c
petsc-3.14.5 2021-03-03
1: #include <petsc/private/dmpleximpl.h>
2: #include <petsc/private/isimpl.h>
3: #include <petsc/private/vecimpl.h>
4: #include <petsclayouthdf5.h>
6: #if defined(PETSC_HAVE_HDF5)
7: static PetscErrorCode SplitPath_Private(char path[], char name[])
8: {
9: char *tmp;
13: PetscStrrchr(path,'/',&tmp);
14: PetscStrcpy(name,tmp);
15: if (tmp != path) {
16: /* '/' found, name is substring of path after last occurence of '/'. */
17: /* Trim the '/name' part from path just by inserting null character. */
18: tmp--;
19: *tmp = '\0';
20: } else {
21: /* '/' not found, name = path, path = "/". */
22: PetscStrcpy(path,"/");
23: }
24: return(0);
25: }
27: /*
28: - invert (involute) cells of some types according to XDMF/VTK numbering of vertices in a cells
29: - cell type is identified using the number of vertices
30: */
31: static PetscErrorCode DMPlexInvertCells_XDMF_Private(DM dm)
32: {
33: PetscInt dim, *cones, cHeight, cStart, cEnd, p;
34: PetscSection cs;
38: DMGetDimension(dm, &dim);
39: if (dim != 3) return(0);
40: DMPlexGetCones(dm, &cones);
41: DMPlexGetConeSection(dm, &cs);
42: DMPlexGetVTKCellHeight(dm, &cHeight);
43: DMPlexGetHeightStratum(dm, cHeight, &cStart, &cEnd);
44: for (p=cStart; p<cEnd; p++) {
45: PetscInt numCorners, o;
47: PetscSectionGetDof(cs, p, &numCorners);
48: PetscSectionGetOffset(cs, p, &o);
49: switch (numCorners) {
50: case 4: DMPlexInvertCell(DM_POLYTOPE_TETRAHEDRON,&cones[o]); break;
51: case 6: DMPlexInvertCell(DM_POLYTOPE_TRI_PRISM,&cones[o]); break;
52: case 8: DMPlexInvertCell(DM_POLYTOPE_HEXAHEDRON,&cones[o]); break;
53: }
54: }
55: return(0);
56: }
58: PetscErrorCode DMPlexLoad_HDF5_Xdmf_Internal(DM dm, PetscViewer viewer)
59: {
60: Vec coordinates;
61: IS cells;
62: PetscInt spatialDim, numCells, numVertices, NVertices, numCorners;
63: PetscMPIInt rank;
64: MPI_Comm comm;
65: PetscErrorCode ierr;
66: char topo_path[PETSC_MAX_PATH_LEN]="/viz/topology/cells", topo_name[PETSC_MAX_PATH_LEN];
67: char geom_path[PETSC_MAX_PATH_LEN]="/geometry/vertices", geom_name[PETSC_MAX_PATH_LEN];
68: PetscBool seq = PETSC_FALSE;
71: PetscObjectGetComm((PetscObject)dm, &comm);
72: MPI_Comm_rank(comm, &rank);
74: PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex HDF5/XDMF Loader Options","PetscViewer");
75: PetscOptionsString("-dm_plex_hdf5_topology_path","HDF5 path of topology dataset",NULL,topo_path,topo_path,sizeof(topo_path),NULL);
76: PetscOptionsString("-dm_plex_hdf5_geometry_path","HDF5 path to geometry dataset",NULL,geom_path,geom_path,sizeof(geom_path),NULL);
77: PetscOptionsBool("-dm_plex_hdf5_force_sequential","force sequential loading",NULL,seq,&seq,NULL);
78: PetscOptionsEnd();
80: SplitPath_Private(topo_path, topo_name);
81: SplitPath_Private(geom_path, geom_name);
82: PetscInfo2(dm, "Topology group %s, name %s\n", topo_path, topo_name);
83: PetscInfo2(dm, "Geometry group %s, name %s\n", geom_path, geom_name);
85: /* Read topology */
86: PetscViewerHDF5PushGroup(viewer, topo_path);
87: ISCreate(comm, &cells);
88: PetscObjectSetName((PetscObject) cells, topo_name);
89: if (seq) {
90: PetscViewerHDF5ReadSizes(viewer, topo_name, NULL, &numCells);
91: PetscLayoutSetSize(cells->map, numCells);
92: numCells = !rank ? numCells : 0;
93: PetscLayoutSetLocalSize(cells->map, numCells);
94: }
95: ISLoad(cells, viewer);
96: ISGetLocalSize(cells, &numCells);
97: ISGetBlockSize(cells, &numCorners);
98: PetscViewerHDF5PopGroup(viewer);
99: numCells /= numCorners;
101: /* Read geometry */
102: PetscViewerHDF5PushGroup(viewer, geom_path);
103: VecCreate(comm, &coordinates);
104: PetscObjectSetName((PetscObject) coordinates, geom_name);
105: if (seq) {
106: PetscViewerHDF5ReadSizes(viewer, geom_name, NULL, &numVertices);
107: PetscLayoutSetSize(coordinates->map, numVertices);
108: numVertices = !rank ? numVertices : 0;
109: PetscLayoutSetLocalSize(coordinates->map, numVertices);
110: }
111: VecLoad(coordinates, viewer);
112: VecGetLocalSize(coordinates, &numVertices);
113: VecGetSize(coordinates, &NVertices);
114: VecGetBlockSize(coordinates, &spatialDim);
115: PetscViewerHDF5PopGroup(viewer);
116: numVertices /= spatialDim;
117: NVertices /= spatialDim;
119: PetscInfo4(NULL, "Loaded mesh dimensions: numCells %D numCorners %D numVertices %D spatialDim %D\n", numCells, numCorners, numVertices, spatialDim);
120: {
121: const PetscScalar *coordinates_arr;
122: PetscReal *coordinates_arr_real;
123: const PetscInt *cells_arr;
124: PetscSF sfVert = NULL;
125: PetscInt i;
127: VecGetArrayRead(coordinates, &coordinates_arr);
128: ISGetIndices(cells, &cells_arr);
130: if (PetscDefined(USE_COMPLEX)) {
131: /* convert to real numbers if PetscScalar is complex */
132: /*TODO More systematic would be to change all the function arguments to PetscScalar */
133: PetscMalloc1(numVertices*spatialDim, &coordinates_arr_real);
134: for (i = 0; i < numVertices*spatialDim; ++i) {
135: coordinates_arr_real[i] = PetscRealPart(coordinates_arr[i]);
136: if (PetscUnlikelyDebug(PetscImaginaryPart(coordinates_arr[i]))) {
137: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Vector of coordinates contains complex numbers but only real vectors are currently supported.");
138: }
139: }
140: } else coordinates_arr_real = (PetscReal*)coordinates_arr;
142: DMSetDimension(dm, spatialDim);
143: DMPlexBuildFromCellListParallel(dm, numCells, numVertices, NVertices, numCorners, cells_arr, &sfVert);
144: DMPlexInvertCells_XDMF_Private(dm);
145: DMPlexBuildCoordinatesFromCellListParallel(dm, spatialDim, sfVert, coordinates_arr_real);
146: VecRestoreArrayRead(coordinates, &coordinates_arr);
147: ISRestoreIndices(cells, &cells_arr);
148: PetscSFDestroy(&sfVert);
149: if (PetscDefined(USE_COMPLEX)) {PetscFree(coordinates_arr_real);}
150: }
151: ISDestroy(&cells);
152: VecDestroy(&coordinates);
154: /* scale coordinates - unlike in DMPlexLoad_HDF5_Internal, this can only be done after DM is populated */
155: {
156: PetscReal lengthScale;
158: DMPlexGetScale(dm, PETSC_UNIT_LENGTH, &lengthScale);
159: DMGetCoordinates(dm, &coordinates);
160: VecScale(coordinates, 1.0/lengthScale);
161: }
163: /* Read Labels */
164: /* TODO: this probably does not work as elements get permuted */
165: /* DMPlexLoadLabels_HDF5_Internal(dm, viewer); */
166: return(0);
167: }
168: #endif