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 32cd921712SStefano Zampini .seealso: EXOGetVarIndex(),DMPlexView_ExodusII_Internal(),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); 56a126751eSBarry Smith ierr = PetscStrlcat(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; 108fe209ef9SBlaise 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; 119fe209ef9SBlaise Bourdin PetscInt nodesTriP1[4] = {3,0,0,0}; 120fe209ef9SBlaise Bourdin PetscInt nodesTriP2[4] = {3,3,0,0}; 121fe209ef9SBlaise Bourdin PetscInt nodesQuadP1[4] = {4,0,0,0}; 122fe209ef9SBlaise Bourdin PetscInt nodesQuadP2[4] = {4,4,0,1}; 123fe209ef9SBlaise Bourdin PetscInt nodesTetP1[4] = {4,0,0,0}; 124fe209ef9SBlaise Bourdin PetscInt nodesTetP2[4] = {4,6,0,0}; 125fe209ef9SBlaise Bourdin PetscInt nodesHexP1[4] = {8,0,0,0}; 126fe209ef9SBlaise 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; 214fe209ef9SBlaise 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]; 241fe209ef9SBlaise Bourdin ierr = PetscMalloc1(PetscMax(27,connectSize)*csSize, &connect);CHKERRQ(ierr); 242fe209ef9SBlaise 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 */ 265fe209ef9SBlaise Bourdin connect[i+off] = closure[(i+edgesInClosure+facesInClosure+1)*2] + 1; 266fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 26778569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]) { /* Edges */ 268fe209ef9SBlaise Bourdin connect[i+off] = closure[(i-verticesInClosure+facesInClosure+1)*2] + 1; 269fe209ef9SBlaise Bourdin if (nodes[cs][2] == 0) connect[i+off] -= numFaces; 270fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 27178569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]+nodes[cs][3]){ /* Cells */ 272fe209ef9SBlaise Bourdin connect[i+off] = closure[0] + 1; 273fe209ef9SBlaise Bourdin connect[i+off] -= skipCells; 27478569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]+nodes[cs][3]+nodes[cs][2]){ /* Faces */ 275fe209ef9SBlaise Bourdin connect[i+off] = closure[(i-edgesInClosure-verticesInClosure)*2] + 1; 276fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 27778569bb4SMatthew G. Knepley } else { 278fe209ef9SBlaise Bourdin connect[i+off] = -1; 27978569bb4SMatthew G. Knepley } 28078569bb4SMatthew G. Knepley } 28178569bb4SMatthew G. Knepley /* Tetrahedra are inverted */ 28278569bb4SMatthew G. Knepley if (type[cs] == TET) { 283fe209ef9SBlaise Bourdin temp = connect[0+off]; connect[0+off] = connect[1+off]; connect[1+off] = temp; 28478569bb4SMatthew G. Knepley if (degree == 2) { 285e2c9586dSBlaise Bourdin temp = connect[5+off]; connect[5+off] = connect[6+off]; connect[6+off] = temp; 286e2c9586dSBlaise Bourdin temp = connect[7+off]; connect[7+off] = connect[8+off]; connect[8+off] = temp; 28778569bb4SMatthew G. Knepley } 28878569bb4SMatthew G. Knepley } 28978569bb4SMatthew G. Knepley /* Hexahedra are inverted */ 29078569bb4SMatthew G. Knepley if (type[cs] == HEX) { 291fe209ef9SBlaise Bourdin temp = connect[1+off]; connect[1+off] = connect[3+off]; connect[3+off] = temp; 29278569bb4SMatthew G. Knepley if (degree == 2) { 293fe209ef9SBlaise Bourdin temp = connect[8+off]; connect[8+off] = connect[11+off]; connect[11+off] = temp; 294fe209ef9SBlaise Bourdin temp = connect[9+off]; connect[9+off] = connect[10+off]; connect[10+off] = temp; 295fe209ef9SBlaise Bourdin temp = connect[16+off]; connect[16+off] = connect[17+off]; connect[17+off] = temp; 296fe209ef9SBlaise Bourdin temp = connect[18+off]; connect[18+off] = connect[19+off]; connect[19+off] = temp; 29778569bb4SMatthew G. Knepley 298fe209ef9SBlaise Bourdin temp = connect[12+off]; connect[12+off] = connect[16+off]; connect[16+off] = temp; 299fe209ef9SBlaise Bourdin temp = connect[13+off]; connect[13+off] = connect[17+off]; connect[17+off] = temp; 300fe209ef9SBlaise Bourdin temp = connect[14+off]; connect[14+off] = connect[18+off]; connect[18+off] = temp; 301fe209ef9SBlaise Bourdin temp = connect[15+off]; connect[15+off] = connect[19+off]; connect[19+off] = temp; 30278569bb4SMatthew G. Knepley 303fe209ef9SBlaise Bourdin temp = connect[23+off]; connect[23+off] = connect[26+off]; connect[26+off] = temp; 304fe209ef9SBlaise Bourdin temp = connect[24+off]; connect[24+off] = connect[25+off]; connect[25+off] = temp; 305fe209ef9SBlaise Bourdin temp = connect[25+off]; connect[25+off] = connect[26+off]; connect[26+off] = temp; 30678569bb4SMatthew G. Knepley } 30778569bb4SMatthew G. Knepley } 308fe209ef9SBlaise Bourdin off += connectSize; 30978569bb4SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cells[c], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 31078569bb4SMatthew G. Knepley } 311fe209ef9SBlaise 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); 376fe209ef9SBlaise Bourdin /* --- Node Sets/Vertex Sets --- */ 377fe209ef9SBlaise Bourdin DMHasLabel(dm, "Vertex Sets", &hasLabel); 378fe209ef9SBlaise Bourdin if (hasLabel) { 379fe209ef9SBlaise Bourdin PetscInt i, vs, vsSize; 380fe209ef9SBlaise Bourdin const PetscInt *vsIdx, *vertices; 381fe209ef9SBlaise Bourdin PetscInt *nodeList; 382fe209ef9SBlaise Bourdin IS vsIS, stratumIS; 383fe209ef9SBlaise Bourdin DMLabel vsLabel; 384fe209ef9SBlaise Bourdin ierr = DMGetLabel(dm, "Vertex Sets", &vsLabel);CHKERRQ(ierr); 385fe209ef9SBlaise Bourdin ierr = DMLabelGetValueIS(vsLabel, &vsIS);CHKERRQ(ierr); 386fe209ef9SBlaise Bourdin ierr = ISGetIndices(vsIS, &vsIdx);CHKERRQ(ierr); 387fe209ef9SBlaise Bourdin for (vs=0; vs<num_vs; ++vs) { 388fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(vsLabel, vsIdx[vs], &stratumIS);CHKERRQ(ierr); 389fe209ef9SBlaise Bourdin ierr = ISGetIndices(stratumIS, &vertices);CHKERRQ(ierr); 390fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &vsSize);CHKERRQ(ierr); 391fe209ef9SBlaise Bourdin ierr = PetscMalloc1(vsSize, &nodeList); 392fe209ef9SBlaise Bourdin for (i=0; i<vsSize; ++i) { 393fe209ef9SBlaise Bourdin nodeList[i] = vertices[i] - skipCells + 1; 394fe209ef9SBlaise Bourdin } 395fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set_param,(exoid, EX_NODE_SET, vsIdx[vs], vsSize, 0)); 396fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set,(exoid, EX_NODE_SET, vsIdx[vs], nodeList, NULL)); 397fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(stratumIS, &vertices);CHKERRQ(ierr); 398fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 399fe209ef9SBlaise Bourdin ierr = PetscFree(nodeList);CHKERRQ(ierr); 400fe209ef9SBlaise Bourdin } 401fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(vsIS, &vsIdx);CHKERRQ(ierr); 402fe209ef9SBlaise Bourdin ierr = ISDestroy(&vsIS);CHKERRQ(ierr); 403fe209ef9SBlaise Bourdin } 404fe209ef9SBlaise Bourdin /* --- Side Sets/Face Sets --- */ 405fe209ef9SBlaise Bourdin ierr = DMHasLabel(dm, "Face Sets", &hasLabel);CHKERRQ(ierr); 406fe209ef9SBlaise Bourdin if (hasLabel) { 407fe209ef9SBlaise Bourdin PetscInt i, j, fs, fsSize; 408fe209ef9SBlaise Bourdin const PetscInt *fsIdx, *faces; 409fe209ef9SBlaise Bourdin IS fsIS, stratumIS; 410fe209ef9SBlaise Bourdin DMLabel fsLabel; 411fe209ef9SBlaise Bourdin PetscInt numPoints, *points; 412fe209ef9SBlaise Bourdin PetscInt elem_list_size = 0; 413fe209ef9SBlaise Bourdin PetscInt *elem_list, *elem_ind, *side_list; 414fe209ef9SBlaise Bourdin 415fe209ef9SBlaise Bourdin ierr = DMGetLabel(dm, "Face Sets", &fsLabel);CHKERRQ(ierr); 416fe209ef9SBlaise Bourdin /* Compute size of Node List and Element List */ 417fe209ef9SBlaise Bourdin ierr = DMLabelGetValueIS(fsLabel, &fsIS);CHKERRQ(ierr); 418fe209ef9SBlaise Bourdin ierr = ISGetIndices(fsIS, &fsIdx);CHKERRQ(ierr); 419fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 420fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(fsLabel, fsIdx[fs], &stratumIS);CHKERRQ(ierr);; 421fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &fsSize);CHKERRQ(ierr); 422fe209ef9SBlaise Bourdin elem_list_size += fsSize; 423fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 424fe209ef9SBlaise Bourdin } 425fe209ef9SBlaise Bourdin ierr = PetscMalloc3(num_fs, &elem_ind, 426fe209ef9SBlaise Bourdin elem_list_size, &elem_list, 427fe209ef9SBlaise Bourdin elem_list_size, &side_list);CHKERRQ(ierr); 428fe209ef9SBlaise Bourdin elem_ind[0] = 0; 429fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 430fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(fsLabel, fsIdx[fs], &stratumIS);CHKERRQ(ierr); 431fe209ef9SBlaise Bourdin ierr = ISGetIndices(stratumIS, &faces);CHKERRQ(ierr); 432fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &fsSize);CHKERRQ(ierr); 433fe209ef9SBlaise Bourdin /* Set Parameters */ 434fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set_param,(exoid, EX_SIDE_SET, fsIdx[fs], fsSize, 0)); 435fe209ef9SBlaise Bourdin /* Indices */ 436fe209ef9SBlaise Bourdin if (fs<num_fs-1) { 437fe209ef9SBlaise Bourdin elem_ind[fs+1] = elem_ind[fs] + fsSize; 438fe209ef9SBlaise Bourdin } 439fe209ef9SBlaise Bourdin 440fe209ef9SBlaise Bourdin for (i=0; i<fsSize; ++i) { 441fe209ef9SBlaise Bourdin /* Element List */ 442fe209ef9SBlaise Bourdin points = NULL; 443fe209ef9SBlaise Bourdin ierr = DMPlexGetTransitiveClosure(dm, faces[i], PETSC_FALSE, &numPoints, &points);CHKERRQ(ierr); 444fe209ef9SBlaise Bourdin elem_list[elem_ind[fs] + i] = points[2] +1; 445fe209ef9SBlaise Bourdin ierr = DMPlexRestoreTransitiveClosure(dm, faces[i], PETSC_FALSE, &numPoints, &points);CHKERRQ(ierr); 446fe209ef9SBlaise Bourdin 447fe209ef9SBlaise Bourdin /* Side List */ 448fe209ef9SBlaise Bourdin points = NULL; 449fe209ef9SBlaise Bourdin ierr = DMPlexGetTransitiveClosure(dm, elem_list[elem_ind[fs] + i]-1, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 450fe209ef9SBlaise Bourdin for (j=1; j<numPoints; ++j) { 451fe209ef9SBlaise Bourdin if (points[j*2]==faces[i]) {break;} 452fe209ef9SBlaise Bourdin } 453fe209ef9SBlaise Bourdin /* Convert HEX sides */ 454fe209ef9SBlaise Bourdin if (numPoints == 27) { 455fe209ef9SBlaise Bourdin if (j == 1) {j = 5;} 456fe209ef9SBlaise Bourdin else if (j == 2) {j = 6;} 457fe209ef9SBlaise Bourdin else if (j == 3) {j = 1;} 458fe209ef9SBlaise Bourdin else if (j == 4) {j = 3;} 459fe209ef9SBlaise Bourdin else if (j == 5) {j = 2;} 460fe209ef9SBlaise Bourdin else if (j == 6) {j = 4;} 461fe209ef9SBlaise Bourdin } 462fe209ef9SBlaise Bourdin /* Convert TET sides */ 463fe209ef9SBlaise Bourdin if (numPoints == 15) { 464fe209ef9SBlaise Bourdin --j; 465fe209ef9SBlaise Bourdin if (j == 0) {j = 4;} 466fe209ef9SBlaise Bourdin } 467fe209ef9SBlaise Bourdin side_list[elem_ind[fs] + i] = j; 468fe209ef9SBlaise Bourdin ierr = DMPlexRestoreTransitiveClosure(dm, elem_list[elem_ind[fs] + i]-1, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 469fe209ef9SBlaise Bourdin 470fe209ef9SBlaise Bourdin } 471fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(stratumIS, &faces);CHKERRQ(ierr); 472fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 473fe209ef9SBlaise Bourdin } 474fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(fsIS, &fsIdx);CHKERRQ(ierr); 475fe209ef9SBlaise Bourdin ierr = ISDestroy(&fsIS);CHKERRQ(ierr); 476fe209ef9SBlaise Bourdin 477fe209ef9SBlaise Bourdin /* Put side sets */ 478fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 479fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set,(exoid, EX_SIDE_SET, fsIdx[fs], &elem_list[elem_ind[fs]], &side_list[elem_ind[fs]])); 480fe209ef9SBlaise Bourdin } 481fe209ef9SBlaise Bourdin ierr = PetscFree3(elem_ind,elem_list,side_list);CHKERRQ(ierr); 482fe209ef9SBlaise 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; 513*22a7544eSVaclav Hapla const PetscScalar *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; 592*22a7544eSVaclav Hapla PetscScalar *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; 668*22a7544eSVaclav Hapla const PetscScalar *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; 771*22a7544eSVaclav Hapla PetscScalar *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