1552f7358SJed Brown #define PETSCDM_DLL 2af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 3552f7358SJed Brown 4519f805aSKarl Rupp #if defined(PETSC_HAVE_EXODUSII) 5552f7358SJed Brown #include <netcdf.h> 6552f7358SJed Brown #include <exodusII.h> 7552f7358SJed Brown #endif 8552f7358SJed Brown 9e0266925SMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 1078569bb4SMatthew G. Knepley /* 1178569bb4SMatthew G. Knepley EXOGetVarIndex - Locate a result in an exodus file based on its name 1278569bb4SMatthew G. Knepley 1378569bb4SMatthew G. Knepley Not collective 1478569bb4SMatthew G. Knepley 1578569bb4SMatthew G. Knepley Input Parameters: 1678569bb4SMatthew G. Knepley + exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 1778569bb4SMatthew G. Knepley . obj_type - the type of entity for instance EX_NODAL, EX_ELEM_BLOCK 1878569bb4SMatthew G. Knepley - name - the name of the result 1978569bb4SMatthew G. Knepley 2078569bb4SMatthew G. Knepley Output Parameters: 2178569bb4SMatthew G. Knepley . varIndex - the location in the exodus file of the result 2278569bb4SMatthew G. Knepley 2378569bb4SMatthew G. Knepley Notes: 2478569bb4SMatthew G. Knepley The exodus variable index is obtained by comparing name and the 2578569bb4SMatthew G. Knepley names of zonal variables declared in the exodus file. For instance if name is "V" 2678569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 2778569bb4SMatthew G. Knepley amongst all variables of type obj_type. 2878569bb4SMatthew G. Knepley 2978569bb4SMatthew G. Knepley Level: beginner 3078569bb4SMatthew G. Knepley 3178569bb4SMatthew G. Knepley .keywords: mesh,ExodusII 3278569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex(),DMView_Exodus(),VecViewPlex_ExodusII_Nodal_Internal(),VecLoadNodal_PlexEXO(),VecLoadZonal_PlexEXO() 3378569bb4SMatthew G. Knepley */ 3478569bb4SMatthew G. Knepley static PetscErrorCode EXOGetVarIndex_Private(int exoid, ex_entity_type obj_type, const char name[], int *varIndex) 3578569bb4SMatthew G. Knepley { 366de834b4SMatthew G. Knepley int num_vars, i, j; 3778569bb4SMatthew G. Knepley char ext_name[MAX_STR_LENGTH+1], var_name[MAX_STR_LENGTH+1]; 3878569bb4SMatthew G. Knepley const int num_suffix = 5; 3978569bb4SMatthew G. Knepley char *suffix[5]; 4078569bb4SMatthew G. Knepley PetscBool flg; 4178569bb4SMatthew G. Knepley PetscErrorCode ierr; 4278569bb4SMatthew G. Knepley 4378569bb4SMatthew G. Knepley PetscFunctionBegin; 4478569bb4SMatthew G. Knepley suffix[0] = (char *) ""; 4578569bb4SMatthew G. Knepley suffix[1] = (char *) "_X"; 4678569bb4SMatthew G. Knepley suffix[2] = (char *) "_XX"; 4778569bb4SMatthew G. Knepley suffix[3] = (char *) "_1"; 4878569bb4SMatthew G. Knepley suffix[4] = (char *) "_11"; 4978569bb4SMatthew G. Knepley 5078569bb4SMatthew G. Knepley *varIndex = 0; 516de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_variable_param,(exoid, obj_type, &num_vars)); 5278569bb4SMatthew G. Knepley for (i = 0; i < num_vars; ++i) { 536de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_variable_name,(exoid, obj_type, i+1, var_name)); 5478569bb4SMatthew G. Knepley for (j = 0; j < num_suffix; ++j){ 5578569bb4SMatthew G. Knepley ierr = PetscStrncpy(ext_name, name, MAX_STR_LENGTH);CHKERRQ(ierr); 5678569bb4SMatthew G. Knepley ierr = PetscStrncat(ext_name, suffix[j], MAX_STR_LENGTH);CHKERRQ(ierr); 5778569bb4SMatthew G. Knepley ierr = PetscStrcasecmp(ext_name, var_name, &flg); 5878569bb4SMatthew G. Knepley if (flg) { 5978569bb4SMatthew G. Knepley *varIndex = i+1; 6078569bb4SMatthew G. Knepley PetscFunctionReturn(0); 6178569bb4SMatthew G. Knepley } 6278569bb4SMatthew G. Knepley } 6378569bb4SMatthew G. Knepley } 6478569bb4SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to locate variable %s in ExodusII file.", name); 6578569bb4SMatthew G. Knepley PetscFunctionReturn(-1); 6678569bb4SMatthew G. Knepley } 6778569bb4SMatthew G. Knepley 6878569bb4SMatthew G. Knepley /* 6978569bb4SMatthew G. Knepley DMPlexView_ExodusII_Internal - Write a DM to disk in exodus format 7078569bb4SMatthew G. Knepley 7178569bb4SMatthew G. Knepley Collective on dm 7278569bb4SMatthew G. Knepley 7378569bb4SMatthew G. Knepley Input Parameters: 7478569bb4SMatthew G. Knepley + dm - The dm to be written 7578569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 7678569bb4SMatthew G. Knepley - degree - the degree of the interpolation space 7778569bb4SMatthew G. Knepley 7878569bb4SMatthew G. Knepley Notes: 7978569bb4SMatthew G. Knepley Not all DM can be written to disk this way. For instance, exodus assume that element blocks (mapped to "Cell sets" labels) 8078569bb4SMatthew G. Knepley consists of sequentially numbered cells. If this is not the case, the exodus file will be corrupted. 8178569bb4SMatthew G. Knepley 8278569bb4SMatthew G. Knepley If the dm has been distributed and exoid points to different files on each MPI rank, only the "local" part of the DM 8378569bb4SMatthew G. Knepley (including "ghost" cells and vertices) will be written. If all exoid points to the same file, the resulting file will 8478569bb4SMatthew G. Knepley probably be corrupted. 8578569bb4SMatthew G. Knepley 8678569bb4SMatthew G. Knepley DMPlex only represents geometry while most post-processing software expect that a mesh also provides information 8778569bb4SMatthew G. Knepley on the discretization space. This function assumes that the file represents Lagrange finite elements of order 1 or 2. 8878569bb4SMatthew G. Knepley It should be extended to use PetscFE objects. 8978569bb4SMatthew G. Knepley 9078569bb4SMatthew G. Knepley This function will only handle TRI, TET, QUAD and HEX cells. 9178569bb4SMatthew G. Knepley Level: beginner 9278569bb4SMatthew G. Knepley 9378569bb4SMatthew G. Knepley .keywords: mesh, ExodusII 9478569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(), VecViewPlex_ExodusII_Nodal_Internal(), VecLoadNodal_PlexEXO(), VecViewZonal_PlexEXO(), VecLoadZonal_PlexEXO() 9578569bb4SMatthew G. Knepley */ 9678569bb4SMatthew G. Knepley PetscErrorCode DMPlexView_ExodusII_Internal(DM dm, int exoid, PetscInt degree) 9778569bb4SMatthew G. Knepley { 9878569bb4SMatthew G. Knepley enum ElemType {TRI, QUAD, TET, HEX}; 9978569bb4SMatthew G. Knepley MPI_Comm comm; 10078569bb4SMatthew G. Knepley /* Connectivity Variables */ 10178569bb4SMatthew G. Knepley PetscInt cellsNotInConnectivity; 10278569bb4SMatthew G. Knepley /* Cell Sets */ 10378569bb4SMatthew G. Knepley DMLabel csLabel; 10478569bb4SMatthew G. Knepley IS csIS; 10578569bb4SMatthew G. Knepley const PetscInt *csIdx; 10678569bb4SMatthew G. Knepley PetscInt num_cs, cs; 10778569bb4SMatthew G. Knepley enum ElemType *type; 108*fe209ef9SBlaise Bourdin PetscBool hasLabel; 10978569bb4SMatthew G. Knepley /* Coordinate Variables */ 11078569bb4SMatthew G. Knepley DM cdm; 11178569bb4SMatthew G. Knepley PetscSection section; 11278569bb4SMatthew G. Knepley Vec coord; 11378569bb4SMatthew G. Knepley PetscInt **nodes; 114eae8a387SMatthew G. Knepley PetscInt depth, d, dim, skipCells = 0; 11578569bb4SMatthew G. Knepley PetscInt pStart, pEnd, p, cStart, cEnd, numCells, vStart, vEnd, numVertices, eStart, eEnd, numEdges, fStart, fEnd, numFaces, numNodes; 11678569bb4SMatthew G. Knepley PetscInt num_vs, num_fs; 11778569bb4SMatthew G. Knepley PetscMPIInt rank, size; 11878569bb4SMatthew G. Knepley const char *dmName; 119*fe209ef9SBlaise Bourdin PetscInt nodesTriP1[4] = {3,0,0,0}; 120*fe209ef9SBlaise Bourdin PetscInt nodesTriP2[4] = {3,3,0,0}; 121*fe209ef9SBlaise Bourdin PetscInt nodesQuadP1[4] = {4,0,0,0}; 122*fe209ef9SBlaise Bourdin PetscInt nodesQuadP2[4] = {4,4,0,1}; 123*fe209ef9SBlaise Bourdin PetscInt nodesTetP1[4] = {4,0,0,0}; 124*fe209ef9SBlaise Bourdin PetscInt nodesTetP2[4] = {4,6,0,0}; 125*fe209ef9SBlaise Bourdin PetscInt nodesHexP1[4] = {8,0,0,0}; 126*fe209ef9SBlaise Bourdin PetscInt nodesHexP2[4] = {8,12,6,1}; 12778569bb4SMatthew G. Knepley PetscErrorCode ierr; 12878569bb4SMatthew G. Knepley 12978569bb4SMatthew G. Knepley PetscFunctionBegin; 13078569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr); 13178569bb4SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 13278569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 13378569bb4SMatthew G. Knepley /* --- Get DM info --- */ 13478569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &dmName);CHKERRQ(ierr); 13578569bb4SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 13678569bb4SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 13778569bb4SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 13878569bb4SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 13978569bb4SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 14078569bb4SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 14178569bb4SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 14278569bb4SMatthew G. Knepley numCells = cEnd - cStart; 14378569bb4SMatthew G. Knepley numEdges = eEnd - eStart; 14478569bb4SMatthew G. Knepley numVertices = vEnd - vStart; 14578569bb4SMatthew G. Knepley if (depth == 3) {numFaces = fEnd - fStart;} 14678569bb4SMatthew G. Knepley else {numFaces = 0;} 14778569bb4SMatthew G. Knepley ierr = DMGetLabelSize(dm, "Cell Sets", &num_cs);CHKERRQ(ierr); 14878569bb4SMatthew G. Knepley ierr = DMGetLabelSize(dm, "Vertex Sets", &num_vs);CHKERRQ(ierr); 14978569bb4SMatthew G. Knepley ierr = DMGetLabelSize(dm, "Face Sets", &num_fs);CHKERRQ(ierr); 15078569bb4SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coord);CHKERRQ(ierr); 15178569bb4SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 15278569bb4SMatthew G. Knepley if (num_cs > 0) { 15378569bb4SMatthew G. Knepley ierr = DMGetLabel(dm, "Cell Sets", &csLabel);CHKERRQ(ierr); 15478569bb4SMatthew G. Knepley ierr = DMLabelGetValueIS(csLabel, &csIS);CHKERRQ(ierr); 15578569bb4SMatthew G. Knepley ierr = ISGetIndices(csIS, &csIdx);CHKERRQ(ierr); 15678569bb4SMatthew G. Knepley } 15778569bb4SMatthew G. Knepley ierr = PetscMalloc1(num_cs, &nodes);CHKERRQ(ierr); 15878569bb4SMatthew G. Knepley /* Set element type for each block and compute total number of nodes */ 15978569bb4SMatthew G. Knepley ierr = PetscMalloc1(num_cs, &type);CHKERRQ(ierr); 16078569bb4SMatthew G. Knepley numNodes = numVertices; 16178569bb4SMatthew G. Knepley if (degree == 2) {numNodes += numEdges;} 16278569bb4SMatthew G. Knepley cellsNotInConnectivity = numCells; 16378569bb4SMatthew G. Knepley for (cs = 0; cs < num_cs; ++cs) { 16478569bb4SMatthew G. Knepley IS stratumIS; 16578569bb4SMatthew G. Knepley const PetscInt *cells; 16678569bb4SMatthew G. Knepley PetscScalar *xyz = NULL; 16778569bb4SMatthew G. Knepley PetscInt csSize, closureSize; 16878569bb4SMatthew G. Knepley 16978569bb4SMatthew G. Knepley ierr = DMLabelGetStratumIS(csLabel, csIdx[cs], &stratumIS);CHKERRQ(ierr); 17078569bb4SMatthew G. Knepley ierr = ISGetIndices(stratumIS, &cells);CHKERRQ(ierr); 17178569bb4SMatthew G. Knepley ierr = ISGetSize(stratumIS, &csSize);CHKERRQ(ierr); 17278569bb4SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, NULL, coord, cells[0], &closureSize, &xyz);CHKERRQ(ierr); 17378569bb4SMatthew G. Knepley switch (dim) { 17478569bb4SMatthew G. Knepley case 2: 17578569bb4SMatthew G. Knepley if (closureSize == 3*dim) {type[cs] = TRI;} 17678569bb4SMatthew G. Knepley else if (closureSize == 4*dim) {type[cs] = QUAD;} 17778569bb4SMatthew G. Knepley else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vertices %D in dimension %D has no ExodusII type", closureSize/dim, dim); 17878569bb4SMatthew G. Knepley break; 17978569bb4SMatthew G. Knepley case 3: 18078569bb4SMatthew G. Knepley if (closureSize == 4*dim) {type[cs] = TET;} 18178569bb4SMatthew G. Knepley else if (closureSize == 8*dim) {type[cs] = HEX;} 18278569bb4SMatthew G. Knepley else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vertices %D in dimension %D has no ExodusII type", closureSize/dim, dim); 18378569bb4SMatthew G. Knepley break; 18478569bb4SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D not handled by ExodusII viewer", dim); 18578569bb4SMatthew G. Knepley } 18678569bb4SMatthew G. Knepley if ((degree == 2) && (type[cs] == QUAD)) {numNodes += csSize;} 18778569bb4SMatthew G. Knepley if ((degree == 2) && (type[cs] == HEX)) {numNodes += csSize; numNodes += numFaces;} 18878569bb4SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, NULL, coord, cells[0], &closureSize, &xyz);CHKERRQ(ierr); 18978569bb4SMatthew G. Knepley /* Set nodes and Element type */ 19078569bb4SMatthew G. Knepley if (type[cs] == TRI) { 19178569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesTriP1; 19278569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesTriP2; 19378569bb4SMatthew G. Knepley } else if (type[cs] == QUAD) { 19478569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesQuadP1; 19578569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesQuadP2; 19678569bb4SMatthew G. Knepley } else if (type[cs] == TET) { 19778569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesTetP1; 19878569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesTetP2; 19978569bb4SMatthew G. Knepley } else if (type[cs] == HEX) { 20078569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesHexP1; 20178569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesHexP2; 20278569bb4SMatthew G. Knepley } 20378569bb4SMatthew G. Knepley /* Compute the number of cells not in the connectivity table */ 20478569bb4SMatthew G. Knepley cellsNotInConnectivity -= nodes[cs][3]*csSize; 20578569bb4SMatthew G. Knepley 20678569bb4SMatthew G. Knepley ierr = ISRestoreIndices(stratumIS, &cells);CHKERRQ(ierr); 20778569bb4SMatthew G. Knepley ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 20878569bb4SMatthew G. Knepley } 2096de834b4SMatthew G. Knepley if (num_cs > 0) {PetscStackCallStandard(ex_put_init,(exoid, dmName, dim, numNodes, numCells, num_cs, num_vs, num_fs));} 21078569bb4SMatthew G. Knepley /* --- Connectivity --- */ 21178569bb4SMatthew G. Knepley for (cs = 0; cs < num_cs; ++cs) { 21278569bb4SMatthew G. Knepley IS stratumIS; 21378569bb4SMatthew G. Knepley const PetscInt *cells; 214*fe209ef9SBlaise Bourdin PetscInt *connect, off = 0; 215eae8a387SMatthew G. Knepley PetscInt edgesInClosure = 0, facesInClosure = 0, verticesInClosure = 0; 21678569bb4SMatthew G. Knepley PetscInt csSize, c, connectSize, closureSize; 21778569bb4SMatthew G. Knepley char *elem_type = NULL; 21878569bb4SMatthew G. Knepley char elem_type_tri3[] = "TRI3", elem_type_quad4[] = "QUAD4"; 21978569bb4SMatthew G. Knepley char elem_type_tri6[] = "TRI6", elem_type_quad9[] = "QUAD9"; 22078569bb4SMatthew G. Knepley char elem_type_tet4[] = "TET4", elem_type_hex8[] = "HEX8"; 22178569bb4SMatthew G. Knepley char elem_type_tet10[] = "TET10", elem_type_hex27[] = "HEX27"; 22278569bb4SMatthew G. Knepley 22378569bb4SMatthew G. Knepley ierr = DMLabelGetStratumIS(csLabel, csIdx[cs], &stratumIS);CHKERRQ(ierr); 22478569bb4SMatthew G. Knepley ierr = ISGetIndices(stratumIS, &cells);CHKERRQ(ierr); 22578569bb4SMatthew G. Knepley ierr = ISGetSize(stratumIS, &csSize);CHKERRQ(ierr); 22678569bb4SMatthew G. Knepley /* Set Element type */ 22778569bb4SMatthew G. Knepley if (type[cs] == TRI) { 22878569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_tri3; 22978569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_tri6; 23078569bb4SMatthew G. Knepley } else if (type[cs] == QUAD) { 23178569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_quad4; 23278569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_quad9; 23378569bb4SMatthew G. Knepley } else if (type[cs] == TET) { 23478569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_tet4; 23578569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_tet10; 23678569bb4SMatthew G. Knepley } else if (type[cs] == HEX) { 23778569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_hex8; 23878569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_hex27; 23978569bb4SMatthew G. Knepley } 24078569bb4SMatthew G. Knepley connectSize = nodes[cs][0] + nodes[cs][1] + nodes[cs][2] + nodes[cs][3]; 241*fe209ef9SBlaise Bourdin ierr = PetscMalloc1(PetscMax(27,connectSize)*csSize, &connect);CHKERRQ(ierr); 242*fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_block,(exoid, EX_ELEM_BLOCK, csIdx[cs], elem_type, csSize, connectSize, 0, 0, 1)); 24378569bb4SMatthew G. Knepley /* Find number of vertices, edges, and faces in the closure */ 24478569bb4SMatthew G. Knepley verticesInClosure = nodes[cs][0]; 24578569bb4SMatthew G. Knepley if (depth > 1) { 24678569bb4SMatthew G. Knepley if (dim == 2) { 24778569bb4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cells[0], &edgesInClosure);CHKERRQ(ierr); 24878569bb4SMatthew G. Knepley } else if (dim == 3) { 24978569bb4SMatthew G. Knepley PetscInt *closure = NULL; 25078569bb4SMatthew G. Knepley 25178569bb4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cells[0], &facesInClosure);CHKERRQ(ierr); 25278569bb4SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, cells[0], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 25378569bb4SMatthew G. Knepley edgesInClosure = closureSize - facesInClosure - 1 - verticesInClosure; 25478569bb4SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cells[0], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 25578569bb4SMatthew G. Knepley } 25678569bb4SMatthew G. Knepley } 25778569bb4SMatthew G. Knepley /* Get connectivity for each cell */ 25878569bb4SMatthew G. Knepley for (c = 0; c < csSize; ++c) { 25978569bb4SMatthew G. Knepley PetscInt *closure = NULL; 26078569bb4SMatthew G. Knepley PetscInt temp, i; 26178569bb4SMatthew G. Knepley 26278569bb4SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, cells[c], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 26378569bb4SMatthew G. Knepley for (i = 0; i < connectSize; ++i) { 26478569bb4SMatthew G. Knepley if (i < nodes[cs][0]) {/* Vertices */ 265*fe209ef9SBlaise Bourdin connect[i+off] = closure[(i+edgesInClosure+facesInClosure+1)*2] + 1; 266*fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 26778569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]) { /* Edges */ 268*fe209ef9SBlaise Bourdin connect[i+off] = closure[(i-verticesInClosure+facesInClosure+1)*2] + 1; 269*fe209ef9SBlaise Bourdin if (nodes[cs][2] == 0) connect[i+off] -= numFaces; 270*fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 27178569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]+nodes[cs][3]){ /* Cells */ 272*fe209ef9SBlaise Bourdin connect[i+off] = closure[0] + 1; 273*fe209ef9SBlaise Bourdin connect[i+off] -= skipCells; 27478569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]+nodes[cs][3]+nodes[cs][2]){ /* Faces */ 275*fe209ef9SBlaise Bourdin connect[i+off] = closure[(i-edgesInClosure-verticesInClosure)*2] + 1; 276*fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 27778569bb4SMatthew G. Knepley } else { 278*fe209ef9SBlaise Bourdin connect[i+off] = -1; 27978569bb4SMatthew G. Knepley } 28078569bb4SMatthew G. Knepley } 28178569bb4SMatthew G. Knepley /* Tetrahedra are inverted */ 28278569bb4SMatthew G. Knepley if (type[cs] == TET) { 283*fe209ef9SBlaise Bourdin temp = connect[0+off]; connect[0+off] = connect[1+off]; connect[1+off] = temp; 28478569bb4SMatthew G. Knepley if (degree == 2) { 285*fe209ef9SBlaise Bourdin temp = connect[5+off]; connect[5] = connect[6+off]; connect[6] = temp; 286*fe209ef9SBlaise Bourdin temp = connect[7+off]; connect[7] = connect[8+off]; connect[8] = temp; 28778569bb4SMatthew G. Knepley } 28878569bb4SMatthew G. Knepley } 28978569bb4SMatthew G. Knepley /* Hexahedra are inverted */ 29078569bb4SMatthew G. Knepley if (type[cs] == HEX) { 291*fe209ef9SBlaise Bourdin temp = connect[1+off]; connect[1+off] = connect[3+off]; connect[3+off] = temp; 29278569bb4SMatthew G. Knepley if (degree == 2) { 293*fe209ef9SBlaise Bourdin temp = connect[8+off]; connect[8+off] = connect[11+off]; connect[11+off] = temp; 294*fe209ef9SBlaise Bourdin temp = connect[9+off]; connect[9+off] = connect[10+off]; connect[10+off] = temp; 295*fe209ef9SBlaise Bourdin temp = connect[16+off]; connect[16+off] = connect[17+off]; connect[17+off] = temp; 296*fe209ef9SBlaise Bourdin temp = connect[18+off]; connect[18+off] = connect[19+off]; connect[19+off] = temp; 29778569bb4SMatthew G. Knepley 298*fe209ef9SBlaise Bourdin temp = connect[12+off]; connect[12+off] = connect[16+off]; connect[16+off] = temp; 299*fe209ef9SBlaise Bourdin temp = connect[13+off]; connect[13+off] = connect[17+off]; connect[17+off] = temp; 300*fe209ef9SBlaise Bourdin temp = connect[14+off]; connect[14+off] = connect[18+off]; connect[18+off] = temp; 301*fe209ef9SBlaise Bourdin temp = connect[15+off]; connect[15+off] = connect[19+off]; connect[19+off] = temp; 30278569bb4SMatthew G. Knepley 303*fe209ef9SBlaise Bourdin temp = connect[23+off]; connect[23+off] = connect[26+off]; connect[26+off] = temp; 304*fe209ef9SBlaise Bourdin temp = connect[24+off]; connect[24+off] = connect[25+off]; connect[25+off] = temp; 305*fe209ef9SBlaise Bourdin temp = connect[25+off]; connect[25+off] = connect[26+off]; connect[26+off] = temp; 30678569bb4SMatthew G. Knepley } 30778569bb4SMatthew G. Knepley } 308*fe209ef9SBlaise Bourdin off += connectSize; 30978569bb4SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cells[c], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 31078569bb4SMatthew G. Knepley } 311*fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_conn,(exoid, EX_ELEM_BLOCK, csIdx[cs], connect, 0, 0)); 31278569bb4SMatthew G. Knepley skipCells += (nodes[cs][3] == 0)*csSize; 31378569bb4SMatthew G. Knepley ierr = PetscFree(connect);CHKERRQ(ierr); 31478569bb4SMatthew G. Knepley ierr = ISRestoreIndices(stratumIS, &cells);CHKERRQ(ierr); 31578569bb4SMatthew G. Knepley ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 31678569bb4SMatthew G. Knepley } 31778569bb4SMatthew G. Knepley ierr = PetscFree(type);CHKERRQ(ierr); 31878569bb4SMatthew G. Knepley /* --- Coordinates --- */ 31978569bb4SMatthew G. Knepley ierr = PetscSectionCreate(comm, §ion);CHKERRQ(ierr); 32078569bb4SMatthew G. Knepley ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 32178569bb4SMatthew G. Knepley for (d = 0; d < depth; ++d) { 32278569bb4SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 32378569bb4SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 32478569bb4SMatthew G. Knepley ierr = PetscSectionSetDof(section, p, nodes[0][d] > 0);CHKERRQ(ierr); 32578569bb4SMatthew G. Knepley } 32678569bb4SMatthew G. Knepley } 32778569bb4SMatthew G. Knepley for (cs = 0; cs < num_cs; ++cs) { 32878569bb4SMatthew G. Knepley IS stratumIS; 32978569bb4SMatthew G. Knepley const PetscInt *cells; 33078569bb4SMatthew G. Knepley PetscInt csSize, c; 33178569bb4SMatthew G. Knepley 33278569bb4SMatthew G. Knepley ierr = DMLabelGetStratumIS(csLabel, csIdx[cs], &stratumIS);CHKERRQ(ierr); 33378569bb4SMatthew G. Knepley ierr = ISGetIndices(stratumIS, &cells);CHKERRQ(ierr); 33478569bb4SMatthew G. Knepley ierr = ISGetSize(stratumIS, &csSize);CHKERRQ(ierr); 33578569bb4SMatthew G. Knepley for (c = 0; c < csSize; ++c) { 33678569bb4SMatthew G. Knepley ierr = PetscSectionSetDof(section, cells[c], nodes[cs][3] > 0);CHKERRQ(ierr); 33778569bb4SMatthew G. Knepley } 33878569bb4SMatthew G. Knepley ierr = ISRestoreIndices(stratumIS, &cells);CHKERRQ(ierr); 33978569bb4SMatthew G. Knepley ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 34078569bb4SMatthew G. Knepley } 34178569bb4SMatthew G. Knepley if (num_cs > 0) { 34278569bb4SMatthew G. Knepley ierr = ISRestoreIndices(csIS, &csIdx);CHKERRQ(ierr); 34378569bb4SMatthew G. Knepley ierr = ISDestroy(&csIS);CHKERRQ(ierr); 34478569bb4SMatthew G. Knepley } 34578569bb4SMatthew G. Knepley ierr = PetscFree(nodes);CHKERRQ(ierr); 34678569bb4SMatthew G. Knepley ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 34778569bb4SMatthew G. Knepley if (numNodes > 0) { 34878569bb4SMatthew G. Knepley const char *coordNames[3] = {"x", "y", "z"}; 34978569bb4SMatthew G. Knepley PetscScalar *coords, *closure; 35078569bb4SMatthew G. Knepley PetscReal *cval; 35178569bb4SMatthew G. Knepley PetscInt hasDof, n = 0; 35278569bb4SMatthew G. Knepley 35378569bb4SMatthew G. Knepley /* There can't be more than 24 values in the closure of a point for the coord section */ 3546de834b4SMatthew G. Knepley ierr = PetscCalloc3(numNodes*3, &coords, dim, &cval, 24, &closure);CHKERRQ(ierr); 35578569bb4SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coord);CHKERRQ(ierr); 35678569bb4SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 35778569bb4SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 35878569bb4SMatthew G. Knepley ierr = PetscSectionGetDof(section, p, &hasDof); 35978569bb4SMatthew G. Knepley if (hasDof) { 36078569bb4SMatthew G. Knepley PetscInt closureSize = 24, j; 36178569bb4SMatthew G. Knepley 36278569bb4SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, NULL, coord, p, &closureSize, &closure);CHKERRQ(ierr); 36378569bb4SMatthew G. Knepley for (d = 0; d < dim; ++d) { 36478569bb4SMatthew G. Knepley cval[d] = 0.0; 36578569bb4SMatthew G. Knepley for (j = 0; j < closureSize/dim; j++) cval[d] += closure[j*dim+d]; 36678569bb4SMatthew G. Knepley coords[d*numNodes+n] = cval[d] * dim / closureSize; 36778569bb4SMatthew G. Knepley } 36878569bb4SMatthew G. Knepley ++n; 36978569bb4SMatthew G. Knepley } 37078569bb4SMatthew G. Knepley } 3716de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_coord,(exoid, &coords[0*numNodes], &coords[1*numNodes], &coords[2*numNodes])); 37278569bb4SMatthew G. Knepley ierr = PetscFree3(coords, cval, closure);CHKERRQ(ierr); 3736de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_coord_names,(exoid, (char **) coordNames)); 37478569bb4SMatthew G. Knepley } 37578569bb4SMatthew G. Knepley ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 376*fe209ef9SBlaise Bourdin /* --- Node Sets/Vertex Sets --- */ 377*fe209ef9SBlaise Bourdin DMHasLabel(dm, "Vertex Sets", &hasLabel); 378*fe209ef9SBlaise Bourdin if (hasLabel) { 379*fe209ef9SBlaise Bourdin PetscInt i, vs, vsSize; 380*fe209ef9SBlaise Bourdin const PetscInt *vsIdx, *vertices; 381*fe209ef9SBlaise Bourdin PetscInt *nodeList; 382*fe209ef9SBlaise Bourdin IS vsIS, stratumIS; 383*fe209ef9SBlaise Bourdin DMLabel vsLabel; 384*fe209ef9SBlaise Bourdin ierr = DMGetLabel(dm, "Vertex Sets", &vsLabel);CHKERRQ(ierr); 385*fe209ef9SBlaise Bourdin ierr = DMLabelGetValueIS(vsLabel, &vsIS);CHKERRQ(ierr); 386*fe209ef9SBlaise Bourdin ierr = ISGetIndices(vsIS, &vsIdx);CHKERRQ(ierr); 387*fe209ef9SBlaise Bourdin for (vs=0; vs<num_vs; ++vs) { 388*fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(vsLabel, vsIdx[vs], &stratumIS);CHKERRQ(ierr); 389*fe209ef9SBlaise Bourdin ierr = ISGetIndices(stratumIS, &vertices);CHKERRQ(ierr); 390*fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &vsSize);CHKERRQ(ierr); 391*fe209ef9SBlaise Bourdin ierr = PetscMalloc1(vsSize, &nodeList); 392*fe209ef9SBlaise Bourdin for (i=0; i<vsSize; ++i) { 393*fe209ef9SBlaise Bourdin nodeList[i] = vertices[i] - skipCells + 1; 394*fe209ef9SBlaise Bourdin } 395*fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set_param,(exoid, EX_NODE_SET, vsIdx[vs], vsSize, 0)); 396*fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set,(exoid, EX_NODE_SET, vsIdx[vs], nodeList, NULL)); 397*fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(stratumIS, &vertices);CHKERRQ(ierr); 398*fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 399*fe209ef9SBlaise Bourdin ierr = PetscFree(nodeList);CHKERRQ(ierr); 400*fe209ef9SBlaise Bourdin } 401*fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(vsIS, &vsIdx);CHKERRQ(ierr); 402*fe209ef9SBlaise Bourdin ierr = ISDestroy(&vsIS);CHKERRQ(ierr); 403*fe209ef9SBlaise Bourdin } 404*fe209ef9SBlaise Bourdin /* --- Side Sets/Face Sets --- */ 405*fe209ef9SBlaise Bourdin ierr = DMHasLabel(dm, "Face Sets", &hasLabel);CHKERRQ(ierr); 406*fe209ef9SBlaise Bourdin if (hasLabel) { 407*fe209ef9SBlaise Bourdin PetscInt i, j, fs, fsSize; 408*fe209ef9SBlaise Bourdin const PetscInt *fsIdx, *faces; 409*fe209ef9SBlaise Bourdin IS fsIS, stratumIS; 410*fe209ef9SBlaise Bourdin DMLabel fsLabel; 411*fe209ef9SBlaise Bourdin PetscInt numPoints, *points; 412*fe209ef9SBlaise Bourdin PetscInt elem_list_size = 0; 413*fe209ef9SBlaise Bourdin PetscInt *elem_list, *elem_ind, *side_list; 414*fe209ef9SBlaise Bourdin 415*fe209ef9SBlaise Bourdin ierr = DMGetLabel(dm, "Face Sets", &fsLabel);CHKERRQ(ierr); 416*fe209ef9SBlaise Bourdin /* Compute size of Node List and Element List */ 417*fe209ef9SBlaise Bourdin ierr = DMLabelGetValueIS(fsLabel, &fsIS);CHKERRQ(ierr); 418*fe209ef9SBlaise Bourdin ierr = ISGetIndices(fsIS, &fsIdx);CHKERRQ(ierr); 419*fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 420*fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(fsLabel, fsIdx[fs], &stratumIS);CHKERRQ(ierr);; 421*fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &fsSize);CHKERRQ(ierr); 422*fe209ef9SBlaise Bourdin elem_list_size += fsSize; 423*fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 424*fe209ef9SBlaise Bourdin } 425*fe209ef9SBlaise Bourdin ierr = PetscMalloc3(num_fs, &elem_ind, 426*fe209ef9SBlaise Bourdin elem_list_size, &elem_list, 427*fe209ef9SBlaise Bourdin elem_list_size, &side_list);CHKERRQ(ierr); 428*fe209ef9SBlaise Bourdin elem_ind[0] = 0; 429*fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 430*fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(fsLabel, fsIdx[fs], &stratumIS);CHKERRQ(ierr); 431*fe209ef9SBlaise Bourdin ierr = ISGetIndices(stratumIS, &faces);CHKERRQ(ierr); 432*fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &fsSize);CHKERRQ(ierr); 433*fe209ef9SBlaise Bourdin /* Set Parameters */ 434*fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set_param,(exoid, EX_SIDE_SET, fsIdx[fs], fsSize, 0)); 435*fe209ef9SBlaise Bourdin /* Indices */ 436*fe209ef9SBlaise Bourdin if (fs<num_fs-1) { 437*fe209ef9SBlaise Bourdin elem_ind[fs+1] = elem_ind[fs] + fsSize; 438*fe209ef9SBlaise Bourdin } 439*fe209ef9SBlaise Bourdin 440*fe209ef9SBlaise Bourdin for (i=0; i<fsSize; ++i) { 441*fe209ef9SBlaise Bourdin /* Element List */ 442*fe209ef9SBlaise Bourdin points = NULL; 443*fe209ef9SBlaise Bourdin ierr = DMPlexGetTransitiveClosure(dm, faces[i], PETSC_FALSE, &numPoints, &points);CHKERRQ(ierr); 444*fe209ef9SBlaise Bourdin elem_list[elem_ind[fs] + i] = points[2] +1; 445*fe209ef9SBlaise Bourdin ierr = DMPlexRestoreTransitiveClosure(dm, faces[i], PETSC_FALSE, &numPoints, &points);CHKERRQ(ierr); 446*fe209ef9SBlaise Bourdin 447*fe209ef9SBlaise Bourdin /* Side List */ 448*fe209ef9SBlaise Bourdin points = NULL; 449*fe209ef9SBlaise Bourdin ierr = DMPlexGetTransitiveClosure(dm, elem_list[elem_ind[fs] + i]-1, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 450*fe209ef9SBlaise Bourdin for (j=1; j<numPoints; ++j) { 451*fe209ef9SBlaise Bourdin if (points[j*2]==faces[i]) {break;} 452*fe209ef9SBlaise Bourdin } 453*fe209ef9SBlaise Bourdin /* Convert HEX sides */ 454*fe209ef9SBlaise Bourdin if (numPoints == 27) { 455*fe209ef9SBlaise Bourdin if (j == 1) {j = 5;} 456*fe209ef9SBlaise Bourdin else if (j == 2) {j = 6;} 457*fe209ef9SBlaise Bourdin else if (j == 3) {j = 1;} 458*fe209ef9SBlaise Bourdin else if (j == 4) {j = 3;} 459*fe209ef9SBlaise Bourdin else if (j == 5) {j = 2;} 460*fe209ef9SBlaise Bourdin else if (j == 6) {j = 4;} 461*fe209ef9SBlaise Bourdin } 462*fe209ef9SBlaise Bourdin /* Convert TET sides */ 463*fe209ef9SBlaise Bourdin if (numPoints == 15) { 464*fe209ef9SBlaise Bourdin --j; 465*fe209ef9SBlaise Bourdin if (j == 0) {j = 4;} 466*fe209ef9SBlaise Bourdin } 467*fe209ef9SBlaise Bourdin side_list[elem_ind[fs] + i] = j; 468*fe209ef9SBlaise Bourdin ierr = DMPlexRestoreTransitiveClosure(dm, elem_list[elem_ind[fs] + i]-1, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 469*fe209ef9SBlaise Bourdin 470*fe209ef9SBlaise Bourdin } 471*fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(stratumIS, &faces);CHKERRQ(ierr); 472*fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 473*fe209ef9SBlaise Bourdin } 474*fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(fsIS, &fsIdx);CHKERRQ(ierr); 475*fe209ef9SBlaise Bourdin ierr = ISDestroy(&fsIS);CHKERRQ(ierr); 476*fe209ef9SBlaise Bourdin 477*fe209ef9SBlaise Bourdin /* Put side sets */ 478*fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 479*fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set,(exoid, EX_SIDE_SET, fsIdx[fs], &elem_list[elem_ind[fs]], &side_list[elem_ind[fs]])); 480*fe209ef9SBlaise Bourdin } 481*fe209ef9SBlaise Bourdin ierr = PetscFree3(elem_ind,elem_list,side_list);CHKERRQ(ierr); 482*fe209ef9SBlaise Bourdin } 48378569bb4SMatthew G. Knepley PetscFunctionReturn(0); 48478569bb4SMatthew G. Knepley } 48578569bb4SMatthew G. Knepley 48678569bb4SMatthew G. Knepley /* 48778569bb4SMatthew G. Knepley VecViewPlex_ExodusII_Nodal_Internal - Write a Vec corresponding to a nodal field to an exodus file 48878569bb4SMatthew G. Knepley 48978569bb4SMatthew G. Knepley Collective on v 49078569bb4SMatthew G. Knepley 49178569bb4SMatthew G. Knepley Input Parameters: 49278569bb4SMatthew G. Knepley + v - The vector to be written 49378569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 49478569bb4SMatthew G. Knepley - step - the time step to write at (exodus steps are numbered starting from 1) 49578569bb4SMatthew G. Knepley 49678569bb4SMatthew G. Knepley Notes: 49778569bb4SMatthew G. Knepley The exodus result nodal variable index is obtained by comparing the Vec name and the 49878569bb4SMatthew G. Knepley names of nodal variables declared in the exodus file. For instance for a Vec named "V" 49978569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 50078569bb4SMatthew G. Knepley amongst all nodal variables. 50178569bb4SMatthew G. Knepley 50278569bb4SMatthew G. Knepley Level: beginner 50378569bb4SMatthew G. Knepley 50478569bb4SMatthew G. Knepley .keywords: mesh,ExodusII 50578569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(),DMPlexView_ExodusII_Internal(),VecLoadNodal_PlexEXO(),VecViewZonal_PlexEXO(),VecLoadZonal_PlexEXO() 50678569bb4SMatthew G. Knepley @*/ 50778569bb4SMatthew G. Knepley PetscErrorCode VecViewPlex_ExodusII_Nodal_Internal(Vec v, int exoid, int step) 50878569bb4SMatthew G. Knepley { 50978569bb4SMatthew G. Knepley MPI_Comm comm; 51078569bb4SMatthew G. Knepley PetscMPIInt size; 51178569bb4SMatthew G. Knepley DM dm; 51278569bb4SMatthew G. Knepley Vec vNatural, vComp; 51378569bb4SMatthew G. Knepley const PetscReal *varray; 51478569bb4SMatthew G. Knepley const char *vecname; 51578569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 51678569bb4SMatthew G. Knepley PetscBool useNatural; 51778569bb4SMatthew G. Knepley int offset; 51878569bb4SMatthew G. Knepley PetscErrorCode ierr; 51978569bb4SMatthew G. Knepley 52078569bb4SMatthew G. Knepley PetscFunctionBegin; 52178569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) v, &comm);CHKERRQ(ierr); 52278569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 52378569bb4SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 52478569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 52578569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 52678569bb4SMatthew G. Knepley if (useNatural) { 52778569bb4SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &vNatural);CHKERRQ(ierr); 52878569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, v, vNatural);CHKERRQ(ierr); 52978569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, v, vNatural);CHKERRQ(ierr); 53078569bb4SMatthew G. Knepley } else { 53178569bb4SMatthew G. Knepley vNatural = v; 53278569bb4SMatthew G. Knepley } 53378569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 53478569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 53578569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_NODAL, vecname, &offset);CHKERRQ(ierr); 53678569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate nodal variable %s in exodus file\n", vecname); 53778569bb4SMatthew G. Knepley /* Write local chunk of the result in the exodus file 53878569bb4SMatthew G. Knepley exodus stores each component of a vector-valued field as a separate variable. 53978569bb4SMatthew G. Knepley We assume that they are stored sequentially */ 54078569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 54178569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 54278569bb4SMatthew G. Knepley if (bs == 1) { 54378569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vNatural, &varray);CHKERRQ(ierr); 5446de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_partial_var,(exoid, step, EX_NODAL, offset, 1, xs+1, xe-xs, varray)); 54578569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vNatural, &varray);CHKERRQ(ierr); 54678569bb4SMatthew G. Knepley } else { 54778569bb4SMatthew G. Knepley IS compIS; 54878569bb4SMatthew G. Knepley PetscInt c; 54978569bb4SMatthew G. Knepley 55078569bb4SMatthew G. Knepley ierr = ISCreateStride(PETSC_COMM_SELF, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr); 55178569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 55278569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 55378569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 55478569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vComp, &varray);CHKERRQ(ierr); 5556de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_partial_var,(exoid, step, EX_NODAL, offset+c, 1, xs/bs+1, (xe-xs)/bs, varray)); 55678569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vComp, &varray);CHKERRQ(ierr); 55778569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 55878569bb4SMatthew G. Knepley } 55978569bb4SMatthew G. Knepley ierr = ISDestroy(&compIS);CHKERRQ(ierr); 56078569bb4SMatthew G. Knepley } 56178569bb4SMatthew G. Knepley if (useNatural) {ierr = DMRestoreGlobalVector(dm, &vNatural);CHKERRQ(ierr);} 56278569bb4SMatthew G. Knepley PetscFunctionReturn(0); 56378569bb4SMatthew G. Knepley } 56478569bb4SMatthew G. Knepley 56578569bb4SMatthew G. Knepley /* 56678569bb4SMatthew G. Knepley VecLoadPlex_ExodusII_Nodal_Internal - Read a Vec corresponding to a nodal field from an exodus file 56778569bb4SMatthew G. Knepley 56878569bb4SMatthew G. Knepley Collective on v 56978569bb4SMatthew G. Knepley 57078569bb4SMatthew G. Knepley Input Parameters: 57178569bb4SMatthew G. Knepley + v - The vector to be written 57278569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 57378569bb4SMatthew G. Knepley - step - the time step to read at (exodus steps are numbered starting from 1) 57478569bb4SMatthew G. Knepley 57578569bb4SMatthew G. Knepley Notes: 57678569bb4SMatthew G. Knepley The exodus result nodal variable index is obtained by comparing the Vec name and the 57778569bb4SMatthew G. Knepley names of nodal variables declared in the exodus file. For instance for a Vec named "V" 57878569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 57978569bb4SMatthew G. Knepley amongst all nodal variables. 58078569bb4SMatthew G. Knepley 58178569bb4SMatthew G. Knepley Level: beginner 58278569bb4SMatthew G. Knepley 58378569bb4SMatthew G. Knepley .keywords: mesh, ExodusII 58478569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(), DMPlexView_ExodusII_Internal(), VecViewPlex_ExodusII_Nodal_Internal(), VecViewZonal_PlexEXO(), VecLoadZonal_PlexEXO() 58578569bb4SMatthew G. Knepley */ 58678569bb4SMatthew G. Knepley PetscErrorCode VecLoadPlex_ExodusII_Nodal_Internal(Vec v, int exoid, int step) 58778569bb4SMatthew G. Knepley { 58878569bb4SMatthew G. Knepley MPI_Comm comm; 58978569bb4SMatthew G. Knepley PetscMPIInt size; 59078569bb4SMatthew G. Knepley DM dm; 59178569bb4SMatthew G. Knepley Vec vNatural, vComp; 59278569bb4SMatthew G. Knepley PetscReal *varray; 59378569bb4SMatthew G. Knepley const char *vecname; 59478569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 59578569bb4SMatthew G. Knepley PetscBool useNatural; 59678569bb4SMatthew G. Knepley int offset; 59778569bb4SMatthew G. Knepley PetscErrorCode ierr; 59878569bb4SMatthew G. Knepley 59978569bb4SMatthew G. Knepley PetscFunctionBegin; 60078569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) v, &comm);CHKERRQ(ierr); 60178569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 60278569bb4SMatthew G. Knepley ierr = VecGetDM(v,&dm);CHKERRQ(ierr); 60378569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 60478569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 60578569bb4SMatthew G. Knepley if (useNatural) {ierr = DMGetGlobalVector(dm,&vNatural);CHKERRQ(ierr);} 60678569bb4SMatthew G. Knepley else {vNatural = v;} 60778569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 60878569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 60978569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_NODAL, vecname, &offset);CHKERRQ(ierr); 61078569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate nodal variable %s in exodus file", vecname); 61178569bb4SMatthew G. Knepley /* Read local chunk from the file */ 61278569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 61378569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 61478569bb4SMatthew G. Knepley if (bs == 1) { 61578569bb4SMatthew G. Knepley ierr = VecGetArray(vNatural, &varray);CHKERRQ(ierr); 6166de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_partial_var,(exoid, step, EX_NODAL, offset, 1, xs+1, xe-xs, varray)); 61778569bb4SMatthew G. Knepley ierr = VecRestoreArray(vNatural, &varray);CHKERRQ(ierr); 61878569bb4SMatthew G. Knepley } else { 61978569bb4SMatthew G. Knepley IS compIS; 62078569bb4SMatthew G. Knepley PetscInt c; 62178569bb4SMatthew G. Knepley 62278569bb4SMatthew G. Knepley ierr = ISCreateStride(PETSC_COMM_SELF, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr); 62378569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 62478569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 62578569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 62678569bb4SMatthew G. Knepley ierr = VecGetArray(vComp, &varray);CHKERRQ(ierr); 6276de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_partial_var,(exoid, step, EX_NODAL, offset+c, 1, xs/bs+1, (xe-xs)/bs, varray)); 62878569bb4SMatthew G. Knepley ierr = VecRestoreArray(vComp, &varray);CHKERRQ(ierr); 62978569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 63078569bb4SMatthew G. Knepley } 63178569bb4SMatthew G. Knepley ierr = ISDestroy(&compIS);CHKERRQ(ierr); 63278569bb4SMatthew G. Knepley } 63378569bb4SMatthew G. Knepley if (useNatural) { 63478569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, vNatural, v);CHKERRQ(ierr); 63578569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, vNatural, v);CHKERRQ(ierr); 63678569bb4SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &vNatural);CHKERRQ(ierr); 63778569bb4SMatthew G. Knepley } 63878569bb4SMatthew G. Knepley PetscFunctionReturn(0); 63978569bb4SMatthew G. Knepley } 64078569bb4SMatthew G. Knepley 64178569bb4SMatthew G. Knepley /* 64278569bb4SMatthew G. Knepley VecViewPlex_ExodusII_Zonal_Internal - Write a Vec corresponding to a zonal (cell based) field to an exodus file 64378569bb4SMatthew G. Knepley 64478569bb4SMatthew G. Knepley Collective on v 64578569bb4SMatthew G. Knepley 64678569bb4SMatthew G. Knepley Input Parameters: 64778569bb4SMatthew G. Knepley + v - The vector to be written 64878569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 64978569bb4SMatthew G. Knepley - step - the time step to write at (exodus steps are numbered starting from 1) 65078569bb4SMatthew G. Knepley 65178569bb4SMatthew G. Knepley Notes: 65278569bb4SMatthew G. Knepley The exodus result zonal variable index is obtained by comparing the Vec name and the 65378569bb4SMatthew G. Knepley names of zonal variables declared in the exodus file. For instance for a Vec named "V" 65478569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 65578569bb4SMatthew G. Knepley amongst all zonal variables. 65678569bb4SMatthew G. Knepley 65778569bb4SMatthew G. Knepley Level: beginner 65878569bb4SMatthew G. Knepley 65978569bb4SMatthew G. Knepley .keywords: mesh,ExodusII 66078569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(),DMPlexView_ExodusII_Internal(),VecViewPlex_ExodusII_Nodal_Internal(),VecLoadPlex_ExodusII_Nodal_Internal(),VecLoadPlex_ExodusII_Zonal_Internal() 66178569bb4SMatthew G. Knepley */ 66278569bb4SMatthew G. Knepley PetscErrorCode VecViewPlex_ExodusII_Zonal_Internal(Vec v, int exoid, int step) 66378569bb4SMatthew G. Knepley { 66478569bb4SMatthew G. Knepley MPI_Comm comm; 66578569bb4SMatthew G. Knepley PetscMPIInt size; 66678569bb4SMatthew G. Knepley DM dm; 66778569bb4SMatthew G. Knepley Vec vNatural, vComp; 66878569bb4SMatthew G. Knepley const PetscReal *varray; 66978569bb4SMatthew G. Knepley const char *vecname; 67078569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 67178569bb4SMatthew G. Knepley PetscBool useNatural; 67278569bb4SMatthew G. Knepley int offset; 67378569bb4SMatthew G. Knepley IS compIS; 67478569bb4SMatthew G. Knepley PetscInt *csSize, *csID; 67578569bb4SMatthew G. Knepley PetscInt numCS, set, csxs = 0; 67678569bb4SMatthew G. Knepley PetscErrorCode ierr; 67778569bb4SMatthew G. Knepley 67878569bb4SMatthew G. Knepley PetscFunctionBegin; 67978569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)v, &comm);CHKERRQ(ierr); 68078569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 68178569bb4SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 68278569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 68378569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 68478569bb4SMatthew G. Knepley if (useNatural) { 68578569bb4SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &vNatural);CHKERRQ(ierr); 68678569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, v, vNatural);CHKERRQ(ierr); 68778569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, v, vNatural);CHKERRQ(ierr); 68878569bb4SMatthew G. Knepley } else { 68978569bb4SMatthew G. Knepley vNatural = v; 69078569bb4SMatthew G. Knepley } 69178569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 69278569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 69378569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_ELEM_BLOCK, vecname, &offset);CHKERRQ(ierr); 69478569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate zonal variable %s in exodus file\n", vecname); 69578569bb4SMatthew G. Knepley /* Write local chunk of the result in the exodus file 69678569bb4SMatthew G. Knepley exodus stores each component of a vector-valued field as a separate variable. 69778569bb4SMatthew G. Knepley We assume that they are stored sequentially 69878569bb4SMatthew G. Knepley Zonal variables are accessed one element block at a time, so we loop through the cell sets, 69978569bb4SMatthew G. Knepley but once the vector has been reordered to natural size, we cannot use the label informations 70078569bb4SMatthew G. Knepley to figure out what to save where. */ 70178569bb4SMatthew G. Knepley numCS = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); 70278569bb4SMatthew G. Knepley ierr = PetscMalloc2(numCS, &csID, numCS, &csSize);CHKERRQ(ierr); 7036de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_ELEM_BLOCK, csID)); 70478569bb4SMatthew G. Knepley for (set = 0; set < numCS; ++set) { 70578569bb4SMatthew G. Knepley ex_block block; 70678569bb4SMatthew G. Knepley 70778569bb4SMatthew G. Knepley block.id = csID[set]; 70878569bb4SMatthew G. Knepley block.type = EX_ELEM_BLOCK; 7096de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_block_param,(exoid, &block)); 71078569bb4SMatthew G. Knepley csSize[set] = block.num_entry; 71178569bb4SMatthew G. Knepley } 71278569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 71378569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 71478569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISCreateStride(comm, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr);} 71578569bb4SMatthew G. Knepley for (set = 0; set < numCS; set++) { 71678569bb4SMatthew G. Knepley PetscInt csLocalSize, c; 71778569bb4SMatthew G. Knepley 71878569bb4SMatthew G. Knepley /* range of indices for set setID[set]: csxs:csxs + csSize[set]-1 71978569bb4SMatthew G. Knepley local slice of zonal values: xs/bs,xm/bs-1 72078569bb4SMatthew G. Knepley intersection: max(xs/bs,csxs),min(xm/bs-1,csxs + csSize[set]-1) */ 72178569bb4SMatthew G. Knepley csLocalSize = PetscMax(0, PetscMin(xe/bs, csxs+csSize[set]) - PetscMax(xs/bs, csxs)); 72278569bb4SMatthew G. Knepley if (bs == 1) { 72378569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vNatural, &varray);CHKERRQ(ierr); 7246de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_partial_var,(exoid, step, EX_ELEM_BLOCK, offset, csID[set], PetscMax(xs-csxs, 0)+1, csLocalSize, &varray[PetscMax(0, csxs-xs)])); 72578569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vNatural, &varray);CHKERRQ(ierr); 72678569bb4SMatthew G. Knepley } else { 72778569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 72878569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 72978569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 73078569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vComp, &varray);CHKERRQ(ierr); 7316de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_partial_var,(exoid, step, EX_ELEM_BLOCK, offset+c, csID[set], PetscMax(xs/bs-csxs, 0)+1, csLocalSize, &varray[PetscMax(0, csxs-xs/bs)])); 73278569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vComp, &varray);CHKERRQ(ierr); 73378569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 73478569bb4SMatthew G. Knepley } 73578569bb4SMatthew G. Knepley } 73678569bb4SMatthew G. Knepley csxs += csSize[set]; 73778569bb4SMatthew G. Knepley } 73878569bb4SMatthew G. Knepley ierr = PetscFree2(csID, csSize);CHKERRQ(ierr); 73978569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISDestroy(&compIS);CHKERRQ(ierr);} 74078569bb4SMatthew G. Knepley if (useNatural) {ierr = DMRestoreGlobalVector(dm,&vNatural);CHKERRQ(ierr);} 74178569bb4SMatthew G. Knepley PetscFunctionReturn(0); 74278569bb4SMatthew G. Knepley } 74378569bb4SMatthew G. Knepley 74478569bb4SMatthew G. Knepley /* 74578569bb4SMatthew G. Knepley VecLoadPlex_ExodusII_Zonal_Internal - Read a Vec corresponding to a zonal (cell based) field from an exodus file 74678569bb4SMatthew G. Knepley 74778569bb4SMatthew G. Knepley Collective on v 74878569bb4SMatthew G. Knepley 74978569bb4SMatthew G. Knepley Input Parameters: 75078569bb4SMatthew G. Knepley + v - The vector to be written 75178569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 75278569bb4SMatthew G. Knepley - step - the time step to read at (exodus steps are numbered starting from 1) 75378569bb4SMatthew G. Knepley 75478569bb4SMatthew G. Knepley Notes: 75578569bb4SMatthew G. Knepley The exodus result zonal variable index is obtained by comparing the Vec name and the 75678569bb4SMatthew G. Knepley names of zonal variables declared in the exodus file. For instance for a Vec named "V" 75778569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 75878569bb4SMatthew G. Knepley amongst all zonal variables. 75978569bb4SMatthew G. Knepley 76078569bb4SMatthew G. Knepley Level: beginner 76178569bb4SMatthew G. Knepley 76278569bb4SMatthew G. Knepley .keywords: mesh,ExodusII 76378569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(), DMPlexView_ExodusII_Internal(), VecViewPlex_ExodusII_Nodal_Internal(), VecLoadPlex_ExodusII_Nodal_Internal(), VecLoadPlex_ExodusII_Zonal_Internal() 76478569bb4SMatthew G. Knepley */ 76578569bb4SMatthew G. Knepley PetscErrorCode VecLoadPlex_ExodusII_Zonal_Internal(Vec v, int exoid, int step) 76678569bb4SMatthew G. Knepley { 76778569bb4SMatthew G. Knepley MPI_Comm comm; 76878569bb4SMatthew G. Knepley PetscMPIInt size; 76978569bb4SMatthew G. Knepley DM dm; 77078569bb4SMatthew G. Knepley Vec vNatural, vComp; 77178569bb4SMatthew G. Knepley PetscReal *varray; 77278569bb4SMatthew G. Knepley const char *vecname; 77378569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 77478569bb4SMatthew G. Knepley PetscBool useNatural; 77578569bb4SMatthew G. Knepley int offset; 77678569bb4SMatthew G. Knepley IS compIS; 77778569bb4SMatthew G. Knepley PetscInt *csSize, *csID; 77878569bb4SMatthew G. Knepley PetscInt numCS, set, csxs = 0; 77978569bb4SMatthew G. Knepley PetscErrorCode ierr; 78078569bb4SMatthew G. Knepley 78178569bb4SMatthew G. Knepley PetscFunctionBegin; 78278569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 78378569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 78478569bb4SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 78578569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 78678569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 78778569bb4SMatthew G. Knepley if (useNatural) {ierr = DMGetGlobalVector(dm,&vNatural);CHKERRQ(ierr);} 78878569bb4SMatthew G. Knepley else {vNatural = v;} 78978569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 79078569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 79178569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_ELEM_BLOCK, vecname, &offset);CHKERRQ(ierr); 79278569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate zonal variable %s in exodus file\n", vecname); 79378569bb4SMatthew G. Knepley /* Read local chunk of the result in the exodus file 79478569bb4SMatthew G. Knepley exodus stores each component of a vector-valued field as a separate variable. 79578569bb4SMatthew G. Knepley We assume that they are stored sequentially 79678569bb4SMatthew G. Knepley Zonal variables are accessed one element block at a time, so we loop through the cell sets, 79778569bb4SMatthew G. Knepley but once the vector has been reordered to natural size, we cannot use the label informations 79878569bb4SMatthew G. Knepley to figure out what to save where. */ 79978569bb4SMatthew G. Knepley numCS = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); 80078569bb4SMatthew G. Knepley ierr = PetscMalloc2(numCS, &csID, numCS, &csSize);CHKERRQ(ierr); 8016de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_ELEM_BLOCK, csID)); 80278569bb4SMatthew G. Knepley for (set = 0; set < numCS; ++set) { 80378569bb4SMatthew G. Knepley ex_block block; 80478569bb4SMatthew G. Knepley 80578569bb4SMatthew G. Knepley block.id = csID[set]; 80678569bb4SMatthew G. Knepley block.type = EX_ELEM_BLOCK; 8076de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_block_param,(exoid, &block)); 80878569bb4SMatthew G. Knepley csSize[set] = block.num_entry; 80978569bb4SMatthew G. Knepley } 81078569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 81178569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 81278569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISCreateStride(comm, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr);} 81378569bb4SMatthew G. Knepley for (set = 0; set < numCS; ++set) { 81478569bb4SMatthew G. Knepley PetscInt csLocalSize, c; 81578569bb4SMatthew G. Knepley 81678569bb4SMatthew G. Knepley /* range of indices for set setID[set]: csxs:csxs + csSize[set]-1 81778569bb4SMatthew G. Knepley local slice of zonal values: xs/bs,xm/bs-1 81878569bb4SMatthew G. Knepley intersection: max(xs/bs,csxs),min(xm/bs-1,csxs + csSize[set]-1) */ 81978569bb4SMatthew G. Knepley csLocalSize = PetscMax(0, PetscMin(xe/bs, csxs+csSize[set]) - PetscMax(xs/bs, csxs)); 82078569bb4SMatthew G. Knepley if (bs == 1) { 82178569bb4SMatthew G. Knepley ierr = VecGetArray(vNatural, &varray);CHKERRQ(ierr); 8226de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_partial_var,(exoid, step, EX_ELEM_BLOCK, offset, csID[set], PetscMax(xs-csxs, 0)+1, csLocalSize, &varray[PetscMax(0, csxs-xs)])); 82378569bb4SMatthew G. Knepley ierr = VecRestoreArray(vNatural, &varray);CHKERRQ(ierr); 82478569bb4SMatthew G. Knepley } else { 82578569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 82678569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 82778569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 82878569bb4SMatthew G. Knepley ierr = VecGetArray(vComp, &varray);CHKERRQ(ierr); 8296de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_partial_var,(exoid, step, EX_ELEM_BLOCK, offset+c, csID[set], PetscMax(xs/bs-csxs, 0)+1, csLocalSize, &varray[PetscMax(0, csxs-xs/bs)])); 83078569bb4SMatthew G. Knepley ierr = VecRestoreArray(vComp, &varray);CHKERRQ(ierr); 83178569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 83278569bb4SMatthew G. Knepley } 83378569bb4SMatthew G. Knepley } 83478569bb4SMatthew G. Knepley csxs += csSize[set]; 83578569bb4SMatthew G. Knepley } 83678569bb4SMatthew G. Knepley ierr = PetscFree2(csID, csSize);CHKERRQ(ierr); 83778569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISDestroy(&compIS);CHKERRQ(ierr);} 83878569bb4SMatthew G. Knepley if (useNatural) { 83978569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, vNatural, v);CHKERRQ(ierr); 84078569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, vNatural, v);CHKERRQ(ierr); 84178569bb4SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &vNatural);CHKERRQ(ierr); 84278569bb4SMatthew G. Knepley } 84378569bb4SMatthew G. Knepley PetscFunctionReturn(0); 84478569bb4SMatthew G. Knepley } 845b53c8456SSatish Balay #endif 84678569bb4SMatthew G. Knepley 84733751fbdSMichael Lange /*@C 848eaf898f9SPatrick Sanan DMPlexCreateExodusFromFile - Create a DMPlex mesh from an ExodusII file. 84933751fbdSMichael Lange 85033751fbdSMichael Lange Collective on comm 85133751fbdSMichael Lange 85233751fbdSMichael Lange Input Parameters: 85333751fbdSMichael Lange + comm - The MPI communicator 85433751fbdSMichael Lange . filename - The name of the ExodusII file 85533751fbdSMichael Lange - interpolate - Create faces and edges in the mesh 85633751fbdSMichael Lange 85733751fbdSMichael Lange Output Parameter: 85833751fbdSMichael Lange . dm - The DM object representing the mesh 85933751fbdSMichael Lange 86033751fbdSMichael Lange Level: beginner 86133751fbdSMichael Lange 86233751fbdSMichael Lange .keywords: mesh,ExodusII 86333751fbdSMichael Lange .seealso: DMPLEX, DMCreate(), DMPlexCreateExodus() 86433751fbdSMichael Lange @*/ 86533751fbdSMichael Lange PetscErrorCode DMPlexCreateExodusFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 86633751fbdSMichael Lange { 86733751fbdSMichael Lange PetscMPIInt rank; 86833751fbdSMichael Lange PetscErrorCode ierr; 86933751fbdSMichael Lange #if defined(PETSC_HAVE_EXODUSII) 870e84f7031SBlaise Bourdin int CPU_word_size = sizeof(PetscReal), IO_word_size = 0, exoid = -1; 87133751fbdSMichael Lange float version; 87233751fbdSMichael Lange #endif 87333751fbdSMichael Lange 87433751fbdSMichael Lange PetscFunctionBegin; 87533751fbdSMichael Lange PetscValidCharPointer(filename, 2); 87633751fbdSMichael Lange ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 87733751fbdSMichael Lange #if defined(PETSC_HAVE_EXODUSII) 87833751fbdSMichael Lange if (!rank) { 87933751fbdSMichael Lange exoid = ex_open(filename, EX_READ, &CPU_word_size, &IO_word_size, &version); 88033751fbdSMichael Lange if (exoid <= 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "ex_open(\"%s\",...) did not return a valid file ID", filename); 88133751fbdSMichael Lange } 88233751fbdSMichael Lange ierr = DMPlexCreateExodus(comm, exoid, interpolate, dm);CHKERRQ(ierr); 8836de834b4SMatthew G. Knepley if (!rank) {PetscStackCallStandard(ex_close,(exoid));} 88433751fbdSMichael Lange #else 88533751fbdSMichael Lange SETERRQ(comm, PETSC_ERR_SUP, "This method requires ExodusII support. Reconfigure using --download-exodusii"); 88633751fbdSMichael Lange #endif 88733751fbdSMichael Lange PetscFunctionReturn(0); 88833751fbdSMichael Lange } 88933751fbdSMichael Lange 890552f7358SJed Brown /*@ 89133751fbdSMichael Lange DMPlexCreateExodus - Create a DMPlex mesh from an ExodusII file ID. 892552f7358SJed Brown 893552f7358SJed Brown Collective on comm 894552f7358SJed Brown 895552f7358SJed Brown Input Parameters: 896552f7358SJed Brown + comm - The MPI communicator 897552f7358SJed Brown . exoid - The ExodusII id associated with a exodus file and obtained using ex_open 898552f7358SJed Brown - interpolate - Create faces and edges in the mesh 899552f7358SJed Brown 900552f7358SJed Brown Output Parameter: 901552f7358SJed Brown . dm - The DM object representing the mesh 902552f7358SJed Brown 903552f7358SJed Brown Level: beginner 904552f7358SJed Brown 905552f7358SJed Brown .keywords: mesh,ExodusII 906e84e7769SJed Brown .seealso: DMPLEX, DMCreate() 907552f7358SJed Brown @*/ 908552f7358SJed Brown PetscErrorCode DMPlexCreateExodus(MPI_Comm comm, PetscInt exoid, PetscBool interpolate, DM *dm) 909552f7358SJed Brown { 910552f7358SJed Brown #if defined(PETSC_HAVE_EXODUSII) 911552f7358SJed Brown PetscMPIInt num_proc, rank; 912552f7358SJed Brown PetscSection coordSection; 913552f7358SJed Brown Vec coordinates; 914552f7358SJed Brown PetscScalar *coords; 915552f7358SJed Brown PetscInt coordSize, v; 916552f7358SJed Brown PetscErrorCode ierr; 917552f7358SJed Brown /* Read from ex_get_init() */ 918552f7358SJed Brown char title[PETSC_MAX_PATH_LEN+1]; 919552f7358SJed Brown int dim = 0, numVertices = 0, numCells = 0; 920552f7358SJed Brown int num_cs = 0, num_vs = 0, num_fs = 0; 921552f7358SJed Brown #endif 922552f7358SJed Brown 923552f7358SJed Brown PetscFunctionBegin; 924552f7358SJed Brown #if defined(PETSC_HAVE_EXODUSII) 925552f7358SJed Brown ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 926552f7358SJed Brown ierr = MPI_Comm_size(comm, &num_proc);CHKERRQ(ierr); 927552f7358SJed Brown ierr = DMCreate(comm, dm);CHKERRQ(ierr); 928552f7358SJed Brown ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 929552f7358SJed Brown /* Open EXODUS II file and read basic informations on rank 0, then broadcast to all processors */ 930552f7358SJed Brown if (!rank) { 93139bba695SBarry Smith ierr = PetscMemzero(title,(PETSC_MAX_PATH_LEN+1)*sizeof(char));CHKERRQ(ierr); 9326de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_init,(exoid, title, &dim, &numVertices, &numCells, &num_cs, &num_vs, &num_fs)); 933552f7358SJed Brown if (!num_cs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Exodus file does not contain any cell set\n"); 934552f7358SJed Brown } 935552f7358SJed Brown ierr = MPI_Bcast(title, PETSC_MAX_PATH_LEN+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 936552f7358SJed Brown ierr = MPI_Bcast(&dim, 1, MPI_INT, 0, comm);CHKERRQ(ierr); 937552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) *dm, title);CHKERRQ(ierr); 938c73cfb54SMatthew G. Knepley ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); 939552f7358SJed Brown ierr = DMPlexSetChart(*dm, 0, numCells+numVertices);CHKERRQ(ierr); 940552f7358SJed Brown 941552f7358SJed Brown /* Read cell sets information */ 942552f7358SJed Brown if (!rank) { 943552f7358SJed Brown PetscInt *cone; 944552f7358SJed Brown int c, cs, c_loc, v, v_loc; 945552f7358SJed Brown /* Read from ex_get_elem_blk_ids() */ 946552f7358SJed Brown int *cs_id; 947552f7358SJed Brown /* Read from ex_get_elem_block() */ 948552f7358SJed Brown char buffer[PETSC_MAX_PATH_LEN+1]; 949552f7358SJed Brown int num_cell_in_set, num_vertex_per_cell, num_attr; 950552f7358SJed Brown /* Read from ex_get_elem_conn() */ 951552f7358SJed Brown int *cs_connect; 952552f7358SJed Brown 953552f7358SJed Brown /* Get cell sets IDs */ 954785e854fSJed Brown ierr = PetscMalloc1(num_cs, &cs_id);CHKERRQ(ierr); 9556de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_ELEM_BLOCK, cs_id)); 956552f7358SJed Brown /* Read the cell set connectivity table and build mesh topology 957552f7358SJed Brown EXO standard requires that cells in cell sets be numbered sequentially and be pairwise disjoint. */ 958552f7358SJed Brown /* First set sizes */ 959552f7358SJed Brown for (cs = 0, c = 0; cs < num_cs; cs++) { 9606de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_block,(exoid, EX_ELEM_BLOCK, cs_id[cs], buffer, &num_cell_in_set,&num_vertex_per_cell, 0, 0, &num_attr)); 961552f7358SJed Brown for (c_loc = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { 962552f7358SJed Brown ierr = DMPlexSetConeSize(*dm, c, num_vertex_per_cell);CHKERRQ(ierr); 963552f7358SJed Brown } 964552f7358SJed Brown } 965552f7358SJed Brown ierr = DMSetUp(*dm);CHKERRQ(ierr); 966552f7358SJed Brown for (cs = 0, c = 0; cs < num_cs; cs++) { 9676de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_block,(exoid, EX_ELEM_BLOCK, cs_id[cs], buffer, &num_cell_in_set, &num_vertex_per_cell, 0, 0, &num_attr)); 968dcca6d9dSJed Brown ierr = PetscMalloc2(num_vertex_per_cell*num_cell_in_set,&cs_connect,num_vertex_per_cell,&cone);CHKERRQ(ierr); 9696de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_conn,(exoid, EX_ELEM_BLOCK, cs_id[cs], cs_connect,NULL,NULL)); 970eaf898f9SPatrick Sanan /* EXO uses Fortran-based indexing, DMPlex uses C-style and numbers cell first then vertices. */ 971552f7358SJed Brown for (c_loc = 0, v = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { 972552f7358SJed Brown for (v_loc = 0; v_loc < num_vertex_per_cell; ++v_loc, ++v) { 973552f7358SJed Brown cone[v_loc] = cs_connect[v]+numCells-1; 974552f7358SJed Brown } 975731dcdf4SMatthew G. Knepley if (dim == 3) { 9762e1b13c2SMatthew G. Knepley /* Tetrahedra are inverted */ 9772e1b13c2SMatthew G. Knepley if (num_vertex_per_cell == 4) { 9782e1b13c2SMatthew G. Knepley PetscInt tmp = cone[0]; 9792e1b13c2SMatthew G. Knepley cone[0] = cone[1]; 9802e1b13c2SMatthew G. Knepley cone[1] = tmp; 9812e1b13c2SMatthew G. Knepley } 9822e1b13c2SMatthew G. Knepley /* Hexahedra are inverted */ 9832e1b13c2SMatthew G. Knepley if (num_vertex_per_cell == 8) { 9842e1b13c2SMatthew G. Knepley PetscInt tmp = cone[1]; 9852e1b13c2SMatthew G. Knepley cone[1] = cone[3]; 9862e1b13c2SMatthew G. Knepley cone[3] = tmp; 9872e1b13c2SMatthew G. Knepley } 988731dcdf4SMatthew G. Knepley } 989552f7358SJed Brown ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 990c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Cell Sets", c, cs_id[cs]);CHKERRQ(ierr); 991552f7358SJed Brown } 992552f7358SJed Brown ierr = PetscFree2(cs_connect,cone);CHKERRQ(ierr); 993552f7358SJed Brown } 994552f7358SJed Brown ierr = PetscFree(cs_id);CHKERRQ(ierr); 995552f7358SJed Brown } 996552f7358SJed Brown ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 997552f7358SJed Brown ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 998552f7358SJed Brown if (interpolate) { 9995fd9971aSMatthew G. Knepley DM idm; 1000552f7358SJed Brown 10019f074e33SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 1002552f7358SJed Brown ierr = DMDestroy(dm);CHKERRQ(ierr); 1003552f7358SJed Brown *dm = idm; 1004552f7358SJed Brown } 1005552f7358SJed Brown 1006552f7358SJed Brown /* Create vertex set label */ 1007552f7358SJed Brown if (!rank && (num_vs > 0)) { 1008552f7358SJed Brown int vs, v; 1009552f7358SJed Brown /* Read from ex_get_node_set_ids() */ 1010552f7358SJed Brown int *vs_id; 1011552f7358SJed Brown /* Read from ex_get_node_set_param() */ 1012f958083aSBlaise Bourdin int num_vertex_in_set; 1013552f7358SJed Brown /* Read from ex_get_node_set() */ 1014552f7358SJed Brown int *vs_vertex_list; 1015552f7358SJed Brown 1016552f7358SJed Brown /* Get vertex set ids */ 1017785e854fSJed Brown ierr = PetscMalloc1(num_vs, &vs_id);CHKERRQ(ierr); 10186de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_NODE_SET, vs_id)); 1019552f7358SJed Brown for (vs = 0; vs < num_vs; ++vs) { 10206de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_set_param,(exoid, EX_NODE_SET, vs_id[vs], &num_vertex_in_set, NULL)); 1021785e854fSJed Brown ierr = PetscMalloc1(num_vertex_in_set, &vs_vertex_list);CHKERRQ(ierr); 10226de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_set,(exoid, EX_NODE_SET, vs_id[vs], vs_vertex_list, NULL)); 1023552f7358SJed Brown for (v = 0; v < num_vertex_in_set; ++v) { 1024c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Vertex Sets", vs_vertex_list[v]+numCells-1, vs_id[vs]);CHKERRQ(ierr); 1025552f7358SJed Brown } 1026552f7358SJed Brown ierr = PetscFree(vs_vertex_list);CHKERRQ(ierr); 1027552f7358SJed Brown } 1028552f7358SJed Brown ierr = PetscFree(vs_id);CHKERRQ(ierr); 1029552f7358SJed Brown } 1030552f7358SJed Brown /* Read coordinates */ 103169d8a9ceSMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 1032552f7358SJed Brown ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 1033552f7358SJed Brown ierr = PetscSectionSetFieldComponents(coordSection, 0, dim);CHKERRQ(ierr); 1034552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numCells, numCells + numVertices);CHKERRQ(ierr); 1035552f7358SJed Brown for (v = numCells; v < numCells+numVertices; ++v) { 1036552f7358SJed Brown ierr = PetscSectionSetDof(coordSection, v, dim);CHKERRQ(ierr); 1037552f7358SJed Brown ierr = PetscSectionSetFieldDof(coordSection, v, 0, dim);CHKERRQ(ierr); 1038552f7358SJed Brown } 1039552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 1040552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 10418b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1042552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 1043552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 10444e90ef8eSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dim);CHKERRQ(ierr); 10452eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 1046552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 10470aba08f6SKarl Rupp if (!rank) { 1048e84f7031SBlaise Bourdin PetscReal *x, *y, *z; 1049552f7358SJed Brown 1050dcca6d9dSJed Brown ierr = PetscMalloc3(numVertices,&x,numVertices,&y,numVertices,&z);CHKERRQ(ierr); 10516de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_coord,(exoid, x, y, z)); 10520d644c17SKarl Rupp if (dim > 0) { 10530d644c17SKarl Rupp for (v = 0; v < numVertices; ++v) coords[v*dim+0] = x[v]; 10540d644c17SKarl Rupp } 10550d644c17SKarl Rupp if (dim > 1) { 10560d644c17SKarl Rupp for (v = 0; v < numVertices; ++v) coords[v*dim+1] = y[v]; 10570d644c17SKarl Rupp } 10580d644c17SKarl Rupp if (dim > 2) { 10590d644c17SKarl Rupp for (v = 0; v < numVertices; ++v) coords[v*dim+2] = z[v]; 10600d644c17SKarl Rupp } 1061552f7358SJed Brown ierr = PetscFree3(x,y,z);CHKERRQ(ierr); 1062552f7358SJed Brown } 1063552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 1064552f7358SJed Brown ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 1065552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 1066552f7358SJed Brown 1067552f7358SJed Brown /* Create side set label */ 1068552f7358SJed Brown if (!rank && interpolate && (num_fs > 0)) { 1069552f7358SJed Brown int fs, f, voff; 1070552f7358SJed Brown /* Read from ex_get_side_set_ids() */ 1071552f7358SJed Brown int *fs_id; 1072552f7358SJed Brown /* Read from ex_get_side_set_param() */ 1073f958083aSBlaise Bourdin int num_side_in_set; 1074552f7358SJed Brown /* Read from ex_get_side_set_node_list() */ 1075552f7358SJed Brown int *fs_vertex_count_list, *fs_vertex_list; 1076ef073283Smichael_afanasiev /* Read side set labels */ 1077ef073283Smichael_afanasiev char fs_name[MAX_STR_LENGTH+1]; 1078552f7358SJed Brown 1079552f7358SJed Brown /* Get side set ids */ 1080785e854fSJed Brown ierr = PetscMalloc1(num_fs, &fs_id);CHKERRQ(ierr); 10816de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_SIDE_SET, fs_id)); 1082552f7358SJed Brown for (fs = 0; fs < num_fs; ++fs) { 10836de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_set_param,(exoid, EX_SIDE_SET, fs_id[fs], &num_side_in_set, NULL)); 1084dcca6d9dSJed Brown ierr = PetscMalloc2(num_side_in_set,&fs_vertex_count_list,num_side_in_set*4,&fs_vertex_list);CHKERRQ(ierr); 10856de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_side_set_node_list,(exoid, fs_id[fs], fs_vertex_count_list, fs_vertex_list)); 1086ef073283Smichael_afanasiev /* Get the specific name associated with this side set ID. */ 1087ef073283Smichael_afanasiev int fs_name_err = ex_get_name(exoid, EX_SIDE_SET, fs_id[fs], fs_name); 1088552f7358SJed Brown for (f = 0, voff = 0; f < num_side_in_set; ++f) { 10890298fd71SBarry Smith const PetscInt *faces = NULL; 1090552f7358SJed Brown PetscInt faceSize = fs_vertex_count_list[f], numFaces; 1091552f7358SJed Brown PetscInt faceVertices[4], v; 1092552f7358SJed Brown 1093552f7358SJed Brown if (faceSize > 4) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "ExodusII side cannot have %d > 4 vertices", faceSize); 1094552f7358SJed Brown for (v = 0; v < faceSize; ++v, ++voff) { 1095552f7358SJed Brown faceVertices[v] = fs_vertex_list[voff]+numCells-1; 1096552f7358SJed Brown } 1097552f7358SJed Brown ierr = DMPlexGetFullJoin(*dm, faceSize, faceVertices, &numFaces, &faces);CHKERRQ(ierr); 1098552f7358SJed Brown if (numFaces != 1) SETERRQ3(comm, PETSC_ERR_ARG_WRONG, "Invalid ExodusII side %d in set %d maps to %d faces", f, fs, numFaces); 1099c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Face Sets", faces[0], fs_id[fs]);CHKERRQ(ierr); 1100ef073283Smichael_afanasiev /* Only add the label if one has been detected for this side set. */ 1101ef073283Smichael_afanasiev if (!fs_name_err) { 1102ef073283Smichael_afanasiev ierr = DMSetLabelValue(*dm, fs_name, faces[0], fs_id[fs]);CHKERRQ(ierr); 1103ef073283Smichael_afanasiev } 1104552f7358SJed Brown ierr = DMPlexRestoreJoin(*dm, faceSize, faceVertices, &numFaces, &faces);CHKERRQ(ierr); 1105552f7358SJed Brown } 1106552f7358SJed Brown ierr = PetscFree2(fs_vertex_count_list,fs_vertex_list);CHKERRQ(ierr); 1107552f7358SJed Brown } 1108552f7358SJed Brown ierr = PetscFree(fs_id);CHKERRQ(ierr); 1109552f7358SJed Brown } 1110552f7358SJed Brown #else 1111552f7358SJed Brown SETERRQ(comm, PETSC_ERR_SUP, "This method requires ExodusII support. Reconfigure using --download-exodusii"); 1112552f7358SJed Brown #endif 1113552f7358SJed Brown PetscFunctionReturn(0); 1114552f7358SJed Brown } 1115