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 91e50132fSMatthew G. Knepley #include <petsc/private/viewerimpl.h> 101e50132fSMatthew G. Knepley #include <petsc/private/viewerexodusiiimpl.h> 11e0266925SMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 1278569bb4SMatthew G. Knepley /* 131e50132fSMatthew G. Knepley PETSC_VIEWER_EXODUSII_ - Creates an ExodusII PetscViewer shared by all processors in a communicator. 141e50132fSMatthew G. Knepley 151e50132fSMatthew G. Knepley Collective 161e50132fSMatthew G. Knepley 171e50132fSMatthew G. Knepley Input Parameter: 181e50132fSMatthew G. Knepley . comm - the MPI communicator to share the ExodusII PetscViewer 191e50132fSMatthew G. Knepley 201e50132fSMatthew G. Knepley Level: intermediate 211e50132fSMatthew G. Knepley 221e50132fSMatthew G. Knepley Notes: 231e50132fSMatthew G. Knepley misses Fortran bindings 241e50132fSMatthew G. Knepley 251e50132fSMatthew G. Knepley Notes: 261e50132fSMatthew G. Knepley Unlike almost all other PETSc routines, PETSC_VIEWER_EXODUSII_ does not return 271e50132fSMatthew G. Knepley an error code. The GLVIS PetscViewer is usually used in the form 281e50132fSMatthew G. Knepley $ XXXView(XXX object, PETSC_VIEWER_EXODUSII_(comm)); 291e50132fSMatthew G. Knepley 3000373969SVaclav Hapla .seealso: PetscViewerExodusIIOpen(), PetscViewerType, PetscViewerCreate(), PetscViewerDestroy() 311e50132fSMatthew G. Knepley */ 321e50132fSMatthew G. Knepley PetscViewer PETSC_VIEWER_EXODUSII_(MPI_Comm comm) 331e50132fSMatthew G. Knepley { 341e50132fSMatthew G. Knepley PetscViewer viewer; 351e50132fSMatthew G. Knepley PetscErrorCode ierr; 361e50132fSMatthew G. Knepley 371e50132fSMatthew G. Knepley PetscFunctionBegin; 381e50132fSMatthew G. Knepley ierr = PetscViewerExodusIIOpen(comm, "mesh.exo", FILE_MODE_WRITE, &viewer); 3900373969SVaclav Hapla if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_EXODUSII_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 401e50132fSMatthew G. Knepley ierr = PetscObjectRegisterDestroy((PetscObject) viewer); 4100373969SVaclav Hapla if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_EXODUSII_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 421e50132fSMatthew G. Knepley PetscFunctionReturn(viewer); 431e50132fSMatthew G. Knepley } 441e50132fSMatthew G. Knepley 451e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerView_ExodusII(PetscViewer v, PetscViewer viewer) 461e50132fSMatthew G. Knepley { 471e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 481e50132fSMatthew G. Knepley PetscErrorCode ierr; 491e50132fSMatthew G. Knepley 501e50132fSMatthew G. Knepley PetscFunctionBegin; 511e50132fSMatthew G. Knepley if (exo->filename) {ierr = PetscViewerASCIIPrintf(viewer, "Filename: %s\n", exo->filename);CHKERRQ(ierr);} 521e50132fSMatthew G. Knepley PetscFunctionReturn(0); 531e50132fSMatthew G. Knepley } 541e50132fSMatthew G. Knepley 551e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerSetFromOptions_ExodusII(PetscOptionItems *PetscOptionsObject, PetscViewer v) 561e50132fSMatthew G. Knepley { 571e50132fSMatthew G. Knepley PetscErrorCode ierr; 581e50132fSMatthew G. Knepley 591e50132fSMatthew G. Knepley PetscFunctionBegin; 601e50132fSMatthew G. Knepley ierr = PetscOptionsHead(PetscOptionsObject, "ExodusII PetscViewer Options");CHKERRQ(ierr); 611e50132fSMatthew G. Knepley ierr = PetscOptionsTail();CHKERRQ(ierr); 621e50132fSMatthew G. Knepley PetscFunctionReturn(0); 631e50132fSMatthew G. Knepley } 641e50132fSMatthew G. Knepley 651e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerSetUp_ExodusII(PetscViewer viewer) 661e50132fSMatthew G. Knepley { 671e50132fSMatthew G. Knepley PetscFunctionBegin; 681e50132fSMatthew G. Knepley PetscFunctionReturn(0); 691e50132fSMatthew G. Knepley } 701e50132fSMatthew G. Knepley 711e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerDestroy_ExodusII(PetscViewer viewer) 721e50132fSMatthew G. Knepley { 731e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 741e50132fSMatthew G. Knepley PetscErrorCode ierr; 751e50132fSMatthew G. Knepley 761e50132fSMatthew G. Knepley PetscFunctionBegin; 771e50132fSMatthew G. Knepley if (exo->exoid >= 0) {ierr = ex_close(exo->exoid);CHKERRQ(ierr);} 781e50132fSMatthew G. Knepley ierr = PetscFree(exo);CHKERRQ(ierr); 791e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL);CHKERRQ(ierr); 801e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",NULL);CHKERRQ(ierr); 811e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",NULL);CHKERRQ(ierr); 821e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerExodusIIGetId",NULL);CHKERRQ(ierr); 831e50132fSMatthew G. Knepley PetscFunctionReturn(0); 841e50132fSMatthew G. Knepley } 851e50132fSMatthew G. Knepley 861e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerFileSetName_ExodusII(PetscViewer viewer, const char name[]) 871e50132fSMatthew G. Knepley { 881e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 891e50132fSMatthew G. Knepley PetscMPIInt rank; 901e50132fSMatthew G. Knepley int CPU_word_size, IO_word_size, EXO_mode; 911e50132fSMatthew G. Knepley PetscErrorCode ierr; 921e50132fSMatthew G. Knepley 931e50132fSMatthew G. Knepley 941e50132fSMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) viewer), &rank);CHKERRQ(ierr); 951e50132fSMatthew G. Knepley CPU_word_size = sizeof(PetscReal); 961e50132fSMatthew G. Knepley IO_word_size = sizeof(PetscReal); 971e50132fSMatthew G. Knepley 981e50132fSMatthew G. Knepley PetscFunctionBegin; 991e50132fSMatthew G. Knepley if (exo->exoid >= 0) {ex_close(exo->exoid); exo->exoid = -1;} 1001e50132fSMatthew G. Knepley if (exo->filename) {ierr = PetscFree(exo->filename);CHKERRQ(ierr);} 1011e50132fSMatthew G. Knepley ierr = PetscStrallocpy(name, &exo->filename);CHKERRQ(ierr); 1021e50132fSMatthew G. Knepley /* Create or open the file collectively */ 1031e50132fSMatthew G. Knepley switch (exo->btype) { 1041e50132fSMatthew G. Knepley case FILE_MODE_READ: 1051e50132fSMatthew G. Knepley EXO_mode = EX_CLOBBER; 1061e50132fSMatthew G. Knepley break; 1071e50132fSMatthew G. Knepley case FILE_MODE_APPEND: 1081e50132fSMatthew G. Knepley EXO_mode = EX_CLOBBER; 1091e50132fSMatthew G. Knepley break; 1101e50132fSMatthew G. Knepley case FILE_MODE_WRITE: 1111e50132fSMatthew G. Knepley EXO_mode = EX_CLOBBER; 1121e50132fSMatthew G. Knepley break; 1131e50132fSMatthew G. Knepley default: 1141e50132fSMatthew G. Knepley SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 1151e50132fSMatthew G. Knepley } 1161e50132fSMatthew G. Knepley #if defined(PETSC_USE_64BIT_INDICES) 1171e50132fSMatthew G. Knepley EXO_mode += EX_ALL_INT64_API; 1181e50132fSMatthew G. Knepley #endif 1191e50132fSMatthew G. Knepley exo->exoid = ex_create(name, EXO_mode, &CPU_word_size, &IO_word_size); 1201e50132fSMatthew G. Knepley if (exo->exoid < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "ex_create failed for %s", name); 1211e50132fSMatthew G. Knepley PetscFunctionReturn(0); 1221e50132fSMatthew G. Knepley } 1231e50132fSMatthew G. Knepley 1241e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerFileGetName_ExodusII(PetscViewer viewer, const char **name) 1251e50132fSMatthew G. Knepley { 1261e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 1271e50132fSMatthew G. Knepley 1281e50132fSMatthew G. Knepley PetscFunctionBegin; 1291e50132fSMatthew G. Knepley *name = exo->filename; 1301e50132fSMatthew G. Knepley PetscFunctionReturn(0); 1311e50132fSMatthew G. Knepley } 1321e50132fSMatthew G. Knepley 1331e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerFileSetMode_ExodusII(PetscViewer viewer, PetscFileMode type) 1341e50132fSMatthew G. Knepley { 1351e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 1361e50132fSMatthew G. Knepley 1371e50132fSMatthew G. Knepley PetscFunctionBegin; 1381e50132fSMatthew G. Knepley exo->btype = type; 1391e50132fSMatthew G. Knepley PetscFunctionReturn(0); 1401e50132fSMatthew G. Knepley } 1411e50132fSMatthew G. Knepley 1421e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerFileGetMode_ExodusII(PetscViewer viewer, PetscFileMode *type) 1431e50132fSMatthew G. Knepley { 1441e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 1451e50132fSMatthew G. Knepley 1461e50132fSMatthew G. Knepley PetscFunctionBegin; 1471e50132fSMatthew G. Knepley *type = exo->btype; 1481e50132fSMatthew G. Knepley PetscFunctionReturn(0); 1491e50132fSMatthew G. Knepley } 1501e50132fSMatthew G. Knepley 1511e50132fSMatthew G. Knepley static PetscErrorCode PetscViewerExodusIIGetId_ExodusII(PetscViewer viewer, int *exoid) 1521e50132fSMatthew G. Knepley { 1531e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo = (PetscViewer_ExodusII *) viewer->data; 1541e50132fSMatthew G. Knepley 1551e50132fSMatthew G. Knepley PetscFunctionBegin; 1561e50132fSMatthew G. Knepley *exoid = exo->exoid; 1571e50132fSMatthew G. Knepley PetscFunctionReturn(0); 1581e50132fSMatthew G. Knepley } 1591e50132fSMatthew G. Knepley 1601e50132fSMatthew G. Knepley /*@C 1611e50132fSMatthew G. Knepley PetscViewerExodusIIOpen - Opens a file for ExodusII input/output. 1621e50132fSMatthew G. Knepley 1631e50132fSMatthew G. Knepley Collective 1641e50132fSMatthew G. Knepley 1651e50132fSMatthew G. Knepley Input Parameters: 1661e50132fSMatthew G. Knepley + comm - MPI communicator 1671e50132fSMatthew G. Knepley . name - name of file 1681e50132fSMatthew G. Knepley - type - type of file 1691e50132fSMatthew G. Knepley $ FILE_MODE_WRITE - create new file for binary output 1701e50132fSMatthew G. Knepley $ FILE_MODE_READ - open existing file for binary input 1711e50132fSMatthew G. Knepley $ FILE_MODE_APPEND - open existing file for binary output 1721e50132fSMatthew G. Knepley 1731e50132fSMatthew G. Knepley Output Parameter: 17400373969SVaclav Hapla . exo - PetscViewer for Exodus II input/output to use with the specified file 1751e50132fSMatthew G. Knepley 1761e50132fSMatthew G. Knepley Level: beginner 1771e50132fSMatthew G. Knepley 1781e50132fSMatthew G. Knepley Note: 1791e50132fSMatthew G. Knepley This PetscViewer should be destroyed with PetscViewerDestroy(). 1801e50132fSMatthew G. Knepley 1811e50132fSMatthew G. Knepley 18200373969SVaclav Hapla .seealso: PetscViewerPushFormat(), PetscViewerDestroy(), 18300373969SVaclav Hapla DMLoad(), PetscFileMode, PetscViewer, PetscViewerSetType(), PetscViewerFileSetMode(), PetscViewerFileSetName() 1841e50132fSMatthew G. Knepley @*/ 1851e50132fSMatthew G. Knepley PetscErrorCode PetscViewerExodusIIOpen(MPI_Comm comm, const char name[], PetscFileMode type, PetscViewer *exo) 1861e50132fSMatthew G. Knepley { 1871e50132fSMatthew G. Knepley PetscErrorCode ierr; 1881e50132fSMatthew G. Knepley 1891e50132fSMatthew G. Knepley PetscFunctionBegin; 1901e50132fSMatthew G. Knepley ierr = PetscViewerCreate(comm, exo);CHKERRQ(ierr); 1911e50132fSMatthew G. Knepley ierr = PetscViewerSetType(*exo, PETSCVIEWEREXODUSII);CHKERRQ(ierr); 1921e50132fSMatthew G. Knepley ierr = PetscViewerFileSetMode(*exo, type);CHKERRQ(ierr); 1931e50132fSMatthew G. Knepley ierr = PetscViewerFileSetName(*exo, name);CHKERRQ(ierr); 1941e50132fSMatthew G. Knepley ierr = PetscViewerSetFromOptions(*exo);CHKERRQ(ierr); 1951e50132fSMatthew G. Knepley PetscFunctionReturn(0); 1961e50132fSMatthew G. Knepley } 1971e50132fSMatthew G. Knepley 1981e50132fSMatthew G. Knepley /*MC 19900373969SVaclav Hapla PETSCVIEWEREXODUSII - A viewer that writes to an Exodus II file 2001e50132fSMatthew G. Knepley 2011e50132fSMatthew G. Knepley 20200373969SVaclav Hapla .seealso: PetscViewerExodusIIOpen(), PetscViewerCreate(), PETSCVIEWERBINARY, PETSCVIEWERHDF5, DMView(), 2031e50132fSMatthew G. Knepley PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 2041e50132fSMatthew G. Knepley 2051e50132fSMatthew G. Knepley Level: beginner 2061e50132fSMatthew G. Knepley M*/ 2071e50132fSMatthew G. Knepley 2081e50132fSMatthew G. Knepley PETSC_EXTERN PetscErrorCode PetscViewerCreate_ExodusII(PetscViewer v) 2091e50132fSMatthew G. Knepley { 2101e50132fSMatthew G. Knepley PetscViewer_ExodusII *exo; 2111e50132fSMatthew G. Knepley PetscErrorCode ierr; 2121e50132fSMatthew G. Knepley 2131e50132fSMatthew G. Knepley PetscFunctionBegin; 2141e50132fSMatthew G. Knepley ierr = PetscNewLog(v,&exo);CHKERRQ(ierr); 2151e50132fSMatthew G. Knepley 2161e50132fSMatthew G. Knepley v->data = (void*) exo; 2171e50132fSMatthew G. Knepley v->ops->destroy = PetscViewerDestroy_ExodusII; 2181e50132fSMatthew G. Knepley v->ops->setfromoptions = PetscViewerSetFromOptions_ExodusII; 2191e50132fSMatthew G. Knepley v->ops->setup = PetscViewerSetUp_ExodusII; 2201e50132fSMatthew G. Knepley v->ops->view = PetscViewerView_ExodusII; 2211e50132fSMatthew G. Knepley v->ops->flush = 0; 2221e50132fSMatthew G. Knepley exo->btype = (PetscFileMode) -1; 2231e50132fSMatthew G. Knepley exo->filename = 0; 2241e50132fSMatthew G. Knepley exo->exoid = -1; 2251e50132fSMatthew G. Knepley 2261e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_ExodusII);CHKERRQ(ierr); 2271e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_ExodusII);CHKERRQ(ierr); 2281e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ExodusII);CHKERRQ(ierr); 2291e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ExodusII);CHKERRQ(ierr); 2301e50132fSMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerExodusIIGetId_C",PetscViewerExodusIIGetId_ExodusII);CHKERRQ(ierr); 2311e50132fSMatthew G. Knepley PetscFunctionReturn(0); 2321e50132fSMatthew G. Knepley } 2331e50132fSMatthew G. Knepley 2341e50132fSMatthew G. Knepley /* 23578569bb4SMatthew G. Knepley EXOGetVarIndex - Locate a result in an exodus file based on its name 23678569bb4SMatthew G. Knepley 23778569bb4SMatthew G. Knepley Not collective 23878569bb4SMatthew G. Knepley 23978569bb4SMatthew G. Knepley Input Parameters: 24078569bb4SMatthew G. Knepley + exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 24178569bb4SMatthew G. Knepley . obj_type - the type of entity for instance EX_NODAL, EX_ELEM_BLOCK 24278569bb4SMatthew G. Knepley - name - the name of the result 24378569bb4SMatthew G. Knepley 24478569bb4SMatthew G. Knepley Output Parameters: 24578569bb4SMatthew G. Knepley . varIndex - the location in the exodus file of the result 24678569bb4SMatthew G. Knepley 24778569bb4SMatthew G. Knepley Notes: 24878569bb4SMatthew G. Knepley The exodus variable index is obtained by comparing name and the 24978569bb4SMatthew G. Knepley names of zonal variables declared in the exodus file. For instance if name is "V" 25078569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 25178569bb4SMatthew G. Knepley amongst all variables of type obj_type. 25278569bb4SMatthew G. Knepley 25378569bb4SMatthew G. Knepley Level: beginner 25478569bb4SMatthew G. Knepley 255cd921712SStefano Zampini .seealso: EXOGetVarIndex(),DMPlexView_ExodusII_Internal(),VecViewPlex_ExodusII_Nodal_Internal(),VecLoadNodal_PlexEXO(),VecLoadZonal_PlexEXO() 25678569bb4SMatthew G. Knepley */ 25778569bb4SMatthew G. Knepley static PetscErrorCode EXOGetVarIndex_Private(int exoid, ex_entity_type obj_type, const char name[], int *varIndex) 25878569bb4SMatthew G. Knepley { 2596de834b4SMatthew G. Knepley int num_vars, i, j; 26078569bb4SMatthew G. Knepley char ext_name[MAX_STR_LENGTH+1], var_name[MAX_STR_LENGTH+1]; 26178569bb4SMatthew G. Knepley const int num_suffix = 5; 26278569bb4SMatthew G. Knepley char *suffix[5]; 26378569bb4SMatthew G. Knepley PetscBool flg; 26478569bb4SMatthew G. Knepley PetscErrorCode ierr; 26578569bb4SMatthew G. Knepley 26678569bb4SMatthew G. Knepley PetscFunctionBegin; 26778569bb4SMatthew G. Knepley suffix[0] = (char *) ""; 26878569bb4SMatthew G. Knepley suffix[1] = (char *) "_X"; 26978569bb4SMatthew G. Knepley suffix[2] = (char *) "_XX"; 27078569bb4SMatthew G. Knepley suffix[3] = (char *) "_1"; 27178569bb4SMatthew G. Knepley suffix[4] = (char *) "_11"; 27278569bb4SMatthew G. Knepley 27378569bb4SMatthew G. Knepley *varIndex = 0; 2746de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_variable_param,(exoid, obj_type, &num_vars)); 27578569bb4SMatthew G. Knepley for (i = 0; i < num_vars; ++i) { 2766de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_variable_name,(exoid, obj_type, i+1, var_name)); 27778569bb4SMatthew G. Knepley for (j = 0; j < num_suffix; ++j){ 27878569bb4SMatthew G. Knepley ierr = PetscStrncpy(ext_name, name, MAX_STR_LENGTH);CHKERRQ(ierr); 279a126751eSBarry Smith ierr = PetscStrlcat(ext_name, suffix[j], MAX_STR_LENGTH);CHKERRQ(ierr); 28078569bb4SMatthew G. Knepley ierr = PetscStrcasecmp(ext_name, var_name, &flg); 28178569bb4SMatthew G. Knepley if (flg) { 28278569bb4SMatthew G. Knepley *varIndex = i+1; 28378569bb4SMatthew G. Knepley PetscFunctionReturn(0); 28478569bb4SMatthew G. Knepley } 28578569bb4SMatthew G. Knepley } 28678569bb4SMatthew G. Knepley } 28778569bb4SMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unable to locate variable %s in ExodusII file.", name); 28878569bb4SMatthew G. Knepley PetscFunctionReturn(-1); 28978569bb4SMatthew G. Knepley } 29078569bb4SMatthew G. Knepley 29178569bb4SMatthew G. Knepley /* 29278569bb4SMatthew G. Knepley DMPlexView_ExodusII_Internal - Write a DM to disk in exodus format 29378569bb4SMatthew G. Knepley 29478569bb4SMatthew G. Knepley Collective on dm 29578569bb4SMatthew G. Knepley 29678569bb4SMatthew G. Knepley Input Parameters: 29778569bb4SMatthew G. Knepley + dm - The dm to be written 29878569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 29978569bb4SMatthew G. Knepley - degree - the degree of the interpolation space 30078569bb4SMatthew G. Knepley 30178569bb4SMatthew G. Knepley Notes: 30278569bb4SMatthew G. Knepley Not all DM can be written to disk this way. For instance, exodus assume that element blocks (mapped to "Cell sets" labels) 30378569bb4SMatthew G. Knepley consists of sequentially numbered cells. If this is not the case, the exodus file will be corrupted. 30478569bb4SMatthew G. Knepley 30578569bb4SMatthew 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 30678569bb4SMatthew G. Knepley (including "ghost" cells and vertices) will be written. If all exoid points to the same file, the resulting file will 30778569bb4SMatthew G. Knepley probably be corrupted. 30878569bb4SMatthew G. Knepley 30978569bb4SMatthew G. Knepley DMPlex only represents geometry while most post-processing software expect that a mesh also provides information 31078569bb4SMatthew G. Knepley on the discretization space. This function assumes that the file represents Lagrange finite elements of order 1 or 2. 31178569bb4SMatthew G. Knepley It should be extended to use PetscFE objects. 31278569bb4SMatthew G. Knepley 31378569bb4SMatthew G. Knepley This function will only handle TRI, TET, QUAD and HEX cells. 31478569bb4SMatthew G. Knepley Level: beginner 31578569bb4SMatthew G. Knepley 31678569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(), VecViewPlex_ExodusII_Nodal_Internal(), VecLoadNodal_PlexEXO(), VecViewZonal_PlexEXO(), VecLoadZonal_PlexEXO() 31778569bb4SMatthew G. Knepley */ 31878569bb4SMatthew G. Knepley PetscErrorCode DMPlexView_ExodusII_Internal(DM dm, int exoid, PetscInt degree) 31978569bb4SMatthew G. Knepley { 32078569bb4SMatthew G. Knepley enum ElemType {TRI, QUAD, TET, HEX}; 32178569bb4SMatthew G. Knepley MPI_Comm comm; 32278569bb4SMatthew G. Knepley /* Connectivity Variables */ 32378569bb4SMatthew G. Knepley PetscInt cellsNotInConnectivity; 32478569bb4SMatthew G. Knepley /* Cell Sets */ 32578569bb4SMatthew G. Knepley DMLabel csLabel; 32678569bb4SMatthew G. Knepley IS csIS; 32778569bb4SMatthew G. Knepley const PetscInt *csIdx; 32878569bb4SMatthew G. Knepley PetscInt num_cs, cs; 32978569bb4SMatthew G. Knepley enum ElemType *type; 330fe209ef9SBlaise Bourdin PetscBool hasLabel; 33178569bb4SMatthew G. Knepley /* Coordinate Variables */ 33278569bb4SMatthew G. Knepley DM cdm; 33378569bb4SMatthew G. Knepley PetscSection section; 33478569bb4SMatthew G. Knepley Vec coord; 33578569bb4SMatthew G. Knepley PetscInt **nodes; 336eae8a387SMatthew G. Knepley PetscInt depth, d, dim, skipCells = 0; 33778569bb4SMatthew G. Knepley PetscInt pStart, pEnd, p, cStart, cEnd, numCells, vStart, vEnd, numVertices, eStart, eEnd, numEdges, fStart, fEnd, numFaces, numNodes; 33878569bb4SMatthew G. Knepley PetscInt num_vs, num_fs; 33978569bb4SMatthew G. Knepley PetscMPIInt rank, size; 34078569bb4SMatthew G. Knepley const char *dmName; 341fe209ef9SBlaise Bourdin PetscInt nodesTriP1[4] = {3,0,0,0}; 342fe209ef9SBlaise Bourdin PetscInt nodesTriP2[4] = {3,3,0,0}; 343fe209ef9SBlaise Bourdin PetscInt nodesQuadP1[4] = {4,0,0,0}; 344fe209ef9SBlaise Bourdin PetscInt nodesQuadP2[4] = {4,4,0,1}; 345fe209ef9SBlaise Bourdin PetscInt nodesTetP1[4] = {4,0,0,0}; 346fe209ef9SBlaise Bourdin PetscInt nodesTetP2[4] = {4,6,0,0}; 347fe209ef9SBlaise Bourdin PetscInt nodesHexP1[4] = {8,0,0,0}; 348fe209ef9SBlaise Bourdin PetscInt nodesHexP2[4] = {8,12,6,1}; 34978569bb4SMatthew G. Knepley PetscErrorCode ierr; 35078569bb4SMatthew G. Knepley 35178569bb4SMatthew G. Knepley PetscFunctionBegin; 35278569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr); 35378569bb4SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 35478569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 35578569bb4SMatthew G. Knepley /* --- Get DM info --- */ 35678569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &dmName);CHKERRQ(ierr); 35778569bb4SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 35878569bb4SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 35978569bb4SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 36078569bb4SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 36178569bb4SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 36278569bb4SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 36378569bb4SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 36478569bb4SMatthew G. Knepley numCells = cEnd - cStart; 36578569bb4SMatthew G. Knepley numEdges = eEnd - eStart; 36678569bb4SMatthew G. Knepley numVertices = vEnd - vStart; 36778569bb4SMatthew G. Knepley if (depth == 3) {numFaces = fEnd - fStart;} 36878569bb4SMatthew G. Knepley else {numFaces = 0;} 36978569bb4SMatthew G. Knepley ierr = DMGetLabelSize(dm, "Cell Sets", &num_cs);CHKERRQ(ierr); 37078569bb4SMatthew G. Knepley ierr = DMGetLabelSize(dm, "Vertex Sets", &num_vs);CHKERRQ(ierr); 37178569bb4SMatthew G. Knepley ierr = DMGetLabelSize(dm, "Face Sets", &num_fs);CHKERRQ(ierr); 37278569bb4SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coord);CHKERRQ(ierr); 37378569bb4SMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 37478569bb4SMatthew G. Knepley if (num_cs > 0) { 37578569bb4SMatthew G. Knepley ierr = DMGetLabel(dm, "Cell Sets", &csLabel);CHKERRQ(ierr); 37678569bb4SMatthew G. Knepley ierr = DMLabelGetValueIS(csLabel, &csIS);CHKERRQ(ierr); 37778569bb4SMatthew G. Knepley ierr = ISGetIndices(csIS, &csIdx);CHKERRQ(ierr); 37878569bb4SMatthew G. Knepley } 37978569bb4SMatthew G. Knepley ierr = PetscMalloc1(num_cs, &nodes);CHKERRQ(ierr); 38078569bb4SMatthew G. Knepley /* Set element type for each block and compute total number of nodes */ 38178569bb4SMatthew G. Knepley ierr = PetscMalloc1(num_cs, &type);CHKERRQ(ierr); 38278569bb4SMatthew G. Knepley numNodes = numVertices; 38378569bb4SMatthew G. Knepley if (degree == 2) {numNodes += numEdges;} 38478569bb4SMatthew G. Knepley cellsNotInConnectivity = numCells; 38578569bb4SMatthew G. Knepley for (cs = 0; cs < num_cs; ++cs) { 38678569bb4SMatthew G. Knepley IS stratumIS; 38778569bb4SMatthew G. Knepley const PetscInt *cells; 38878569bb4SMatthew G. Knepley PetscScalar *xyz = NULL; 38978569bb4SMatthew G. Knepley PetscInt csSize, closureSize; 39078569bb4SMatthew G. Knepley 39178569bb4SMatthew G. Knepley ierr = DMLabelGetStratumIS(csLabel, csIdx[cs], &stratumIS);CHKERRQ(ierr); 39278569bb4SMatthew G. Knepley ierr = ISGetIndices(stratumIS, &cells);CHKERRQ(ierr); 39378569bb4SMatthew G. Knepley ierr = ISGetSize(stratumIS, &csSize);CHKERRQ(ierr); 39478569bb4SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, NULL, coord, cells[0], &closureSize, &xyz);CHKERRQ(ierr); 39578569bb4SMatthew G. Knepley switch (dim) { 39678569bb4SMatthew G. Knepley case 2: 39778569bb4SMatthew G. Knepley if (closureSize == 3*dim) {type[cs] = TRI;} 39878569bb4SMatthew G. Knepley else if (closureSize == 4*dim) {type[cs] = QUAD;} 39978569bb4SMatthew 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); 40078569bb4SMatthew G. Knepley break; 40178569bb4SMatthew G. Knepley case 3: 40278569bb4SMatthew G. Knepley if (closureSize == 4*dim) {type[cs] = TET;} 40378569bb4SMatthew G. Knepley else if (closureSize == 8*dim) {type[cs] = HEX;} 40478569bb4SMatthew 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); 40578569bb4SMatthew G. Knepley break; 40678569bb4SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Dimension %D not handled by ExodusII viewer", dim); 40778569bb4SMatthew G. Knepley } 40878569bb4SMatthew G. Knepley if ((degree == 2) && (type[cs] == QUAD)) {numNodes += csSize;} 40978569bb4SMatthew G. Knepley if ((degree == 2) && (type[cs] == HEX)) {numNodes += csSize; numNodes += numFaces;} 41078569bb4SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, NULL, coord, cells[0], &closureSize, &xyz);CHKERRQ(ierr); 41178569bb4SMatthew G. Knepley /* Set nodes and Element type */ 41278569bb4SMatthew G. Knepley if (type[cs] == TRI) { 41378569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesTriP1; 41478569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesTriP2; 41578569bb4SMatthew G. Knepley } else if (type[cs] == QUAD) { 41678569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesQuadP1; 41778569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesQuadP2; 41878569bb4SMatthew G. Knepley } else if (type[cs] == TET) { 41978569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesTetP1; 42078569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesTetP2; 42178569bb4SMatthew G. Knepley } else if (type[cs] == HEX) { 42278569bb4SMatthew G. Knepley if (degree == 1) nodes[cs] = nodesHexP1; 42378569bb4SMatthew G. Knepley else if (degree == 2) nodes[cs] = nodesHexP2; 42478569bb4SMatthew G. Knepley } 42578569bb4SMatthew G. Knepley /* Compute the number of cells not in the connectivity table */ 42678569bb4SMatthew G. Knepley cellsNotInConnectivity -= nodes[cs][3]*csSize; 42778569bb4SMatthew G. Knepley 42878569bb4SMatthew G. Knepley ierr = ISRestoreIndices(stratumIS, &cells);CHKERRQ(ierr); 42978569bb4SMatthew G. Knepley ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 43078569bb4SMatthew G. Knepley } 4316de834b4SMatthew G. Knepley if (num_cs > 0) {PetscStackCallStandard(ex_put_init,(exoid, dmName, dim, numNodes, numCells, num_cs, num_vs, num_fs));} 43278569bb4SMatthew G. Knepley /* --- Connectivity --- */ 43378569bb4SMatthew G. Knepley for (cs = 0; cs < num_cs; ++cs) { 43478569bb4SMatthew G. Knepley IS stratumIS; 43578569bb4SMatthew G. Knepley const PetscInt *cells; 436fe209ef9SBlaise Bourdin PetscInt *connect, off = 0; 437eae8a387SMatthew G. Knepley PetscInt edgesInClosure = 0, facesInClosure = 0, verticesInClosure = 0; 43878569bb4SMatthew G. Knepley PetscInt csSize, c, connectSize, closureSize; 43978569bb4SMatthew G. Knepley char *elem_type = NULL; 44078569bb4SMatthew G. Knepley char elem_type_tri3[] = "TRI3", elem_type_quad4[] = "QUAD4"; 44178569bb4SMatthew G. Knepley char elem_type_tri6[] = "TRI6", elem_type_quad9[] = "QUAD9"; 44278569bb4SMatthew G. Knepley char elem_type_tet4[] = "TET4", elem_type_hex8[] = "HEX8"; 44378569bb4SMatthew G. Knepley char elem_type_tet10[] = "TET10", elem_type_hex27[] = "HEX27"; 44478569bb4SMatthew G. Knepley 44578569bb4SMatthew G. Knepley ierr = DMLabelGetStratumIS(csLabel, csIdx[cs], &stratumIS);CHKERRQ(ierr); 44678569bb4SMatthew G. Knepley ierr = ISGetIndices(stratumIS, &cells);CHKERRQ(ierr); 44778569bb4SMatthew G. Knepley ierr = ISGetSize(stratumIS, &csSize);CHKERRQ(ierr); 44878569bb4SMatthew G. Knepley /* Set Element type */ 44978569bb4SMatthew G. Knepley if (type[cs] == TRI) { 45078569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_tri3; 45178569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_tri6; 45278569bb4SMatthew G. Knepley } else if (type[cs] == QUAD) { 45378569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_quad4; 45478569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_quad9; 45578569bb4SMatthew G. Knepley } else if (type[cs] == TET) { 45678569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_tet4; 45778569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_tet10; 45878569bb4SMatthew G. Knepley } else if (type[cs] == HEX) { 45978569bb4SMatthew G. Knepley if (degree == 1) elem_type = elem_type_hex8; 46078569bb4SMatthew G. Knepley else if (degree == 2) elem_type = elem_type_hex27; 46178569bb4SMatthew G. Knepley } 46278569bb4SMatthew G. Knepley connectSize = nodes[cs][0] + nodes[cs][1] + nodes[cs][2] + nodes[cs][3]; 463fe209ef9SBlaise Bourdin ierr = PetscMalloc1(PetscMax(27,connectSize)*csSize, &connect);CHKERRQ(ierr); 464fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_block,(exoid, EX_ELEM_BLOCK, csIdx[cs], elem_type, csSize, connectSize, 0, 0, 1)); 46578569bb4SMatthew G. Knepley /* Find number of vertices, edges, and faces in the closure */ 46678569bb4SMatthew G. Knepley verticesInClosure = nodes[cs][0]; 46778569bb4SMatthew G. Knepley if (depth > 1) { 46878569bb4SMatthew G. Knepley if (dim == 2) { 46978569bb4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cells[0], &edgesInClosure);CHKERRQ(ierr); 47078569bb4SMatthew G. Knepley } else if (dim == 3) { 47178569bb4SMatthew G. Knepley PetscInt *closure = NULL; 47278569bb4SMatthew G. Knepley 47378569bb4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cells[0], &facesInClosure);CHKERRQ(ierr); 47478569bb4SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, cells[0], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 47578569bb4SMatthew G. Knepley edgesInClosure = closureSize - facesInClosure - 1 - verticesInClosure; 47678569bb4SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cells[0], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 47778569bb4SMatthew G. Knepley } 47878569bb4SMatthew G. Knepley } 47978569bb4SMatthew G. Knepley /* Get connectivity for each cell */ 48078569bb4SMatthew G. Knepley for (c = 0; c < csSize; ++c) { 48178569bb4SMatthew G. Knepley PetscInt *closure = NULL; 48278569bb4SMatthew G. Knepley PetscInt temp, i; 48378569bb4SMatthew G. Knepley 48478569bb4SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, cells[c], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 48578569bb4SMatthew G. Knepley for (i = 0; i < connectSize; ++i) { 48678569bb4SMatthew G. Knepley if (i < nodes[cs][0]) {/* Vertices */ 487fe209ef9SBlaise Bourdin connect[i+off] = closure[(i+edgesInClosure+facesInClosure+1)*2] + 1; 488fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 48978569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]) { /* Edges */ 490fe209ef9SBlaise Bourdin connect[i+off] = closure[(i-verticesInClosure+facesInClosure+1)*2] + 1; 491fe209ef9SBlaise Bourdin if (nodes[cs][2] == 0) connect[i+off] -= numFaces; 492fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 49378569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]+nodes[cs][3]){ /* Cells */ 494fe209ef9SBlaise Bourdin connect[i+off] = closure[0] + 1; 495fe209ef9SBlaise Bourdin connect[i+off] -= skipCells; 49678569bb4SMatthew G. Knepley } else if (i < nodes[cs][0]+nodes[cs][1]+nodes[cs][3]+nodes[cs][2]){ /* Faces */ 497fe209ef9SBlaise Bourdin connect[i+off] = closure[(i-edgesInClosure-verticesInClosure)*2] + 1; 498fe209ef9SBlaise Bourdin connect[i+off] -= cellsNotInConnectivity; 49978569bb4SMatthew G. Knepley } else { 500fe209ef9SBlaise Bourdin connect[i+off] = -1; 50178569bb4SMatthew G. Knepley } 50278569bb4SMatthew G. Knepley } 50378569bb4SMatthew G. Knepley /* Tetrahedra are inverted */ 50478569bb4SMatthew G. Knepley if (type[cs] == TET) { 505fe209ef9SBlaise Bourdin temp = connect[0+off]; connect[0+off] = connect[1+off]; connect[1+off] = temp; 50678569bb4SMatthew G. Knepley if (degree == 2) { 507e2c9586dSBlaise Bourdin temp = connect[5+off]; connect[5+off] = connect[6+off]; connect[6+off] = temp; 508e2c9586dSBlaise Bourdin temp = connect[7+off]; connect[7+off] = connect[8+off]; connect[8+off] = temp; 50978569bb4SMatthew G. Knepley } 51078569bb4SMatthew G. Knepley } 51178569bb4SMatthew G. Knepley /* Hexahedra are inverted */ 51278569bb4SMatthew G. Knepley if (type[cs] == HEX) { 513fe209ef9SBlaise Bourdin temp = connect[1+off]; connect[1+off] = connect[3+off]; connect[3+off] = temp; 51478569bb4SMatthew G. Knepley if (degree == 2) { 515fe209ef9SBlaise Bourdin temp = connect[8+off]; connect[8+off] = connect[11+off]; connect[11+off] = temp; 516fe209ef9SBlaise Bourdin temp = connect[9+off]; connect[9+off] = connect[10+off]; connect[10+off] = temp; 517fe209ef9SBlaise Bourdin temp = connect[16+off]; connect[16+off] = connect[17+off]; connect[17+off] = temp; 518fe209ef9SBlaise Bourdin temp = connect[18+off]; connect[18+off] = connect[19+off]; connect[19+off] = temp; 51978569bb4SMatthew G. Knepley 520fe209ef9SBlaise Bourdin temp = connect[12+off]; connect[12+off] = connect[16+off]; connect[16+off] = temp; 521fe209ef9SBlaise Bourdin temp = connect[13+off]; connect[13+off] = connect[17+off]; connect[17+off] = temp; 522fe209ef9SBlaise Bourdin temp = connect[14+off]; connect[14+off] = connect[18+off]; connect[18+off] = temp; 523fe209ef9SBlaise Bourdin temp = connect[15+off]; connect[15+off] = connect[19+off]; connect[19+off] = temp; 52478569bb4SMatthew G. Knepley 525fe209ef9SBlaise Bourdin temp = connect[23+off]; connect[23+off] = connect[26+off]; connect[26+off] = temp; 526fe209ef9SBlaise Bourdin temp = connect[24+off]; connect[24+off] = connect[25+off]; connect[25+off] = temp; 527fe209ef9SBlaise Bourdin temp = connect[25+off]; connect[25+off] = connect[26+off]; connect[26+off] = temp; 52878569bb4SMatthew G. Knepley } 52978569bb4SMatthew G. Knepley } 530fe209ef9SBlaise Bourdin off += connectSize; 53178569bb4SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cells[c], PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 53278569bb4SMatthew G. Knepley } 533fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_conn,(exoid, EX_ELEM_BLOCK, csIdx[cs], connect, 0, 0)); 53478569bb4SMatthew G. Knepley skipCells += (nodes[cs][3] == 0)*csSize; 53578569bb4SMatthew G. Knepley ierr = PetscFree(connect);CHKERRQ(ierr); 53678569bb4SMatthew G. Knepley ierr = ISRestoreIndices(stratumIS, &cells);CHKERRQ(ierr); 53778569bb4SMatthew G. Knepley ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 53878569bb4SMatthew G. Knepley } 53978569bb4SMatthew G. Knepley ierr = PetscFree(type);CHKERRQ(ierr); 54078569bb4SMatthew G. Knepley /* --- Coordinates --- */ 54178569bb4SMatthew G. Knepley ierr = PetscSectionCreate(comm, §ion);CHKERRQ(ierr); 54278569bb4SMatthew G. Knepley ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 5431e50132fSMatthew G. Knepley if (num_cs) { 54478569bb4SMatthew G. Knepley for (d = 0; d < depth; ++d) { 54578569bb4SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 54678569bb4SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 54778569bb4SMatthew G. Knepley ierr = PetscSectionSetDof(section, p, nodes[0][d] > 0);CHKERRQ(ierr); 54878569bb4SMatthew G. Knepley } 54978569bb4SMatthew G. Knepley } 5501e50132fSMatthew G. Knepley } 55178569bb4SMatthew G. Knepley for (cs = 0; cs < num_cs; ++cs) { 55278569bb4SMatthew G. Knepley IS stratumIS; 55378569bb4SMatthew G. Knepley const PetscInt *cells; 55478569bb4SMatthew G. Knepley PetscInt csSize, c; 55578569bb4SMatthew G. Knepley 55678569bb4SMatthew G. Knepley ierr = DMLabelGetStratumIS(csLabel, csIdx[cs], &stratumIS);CHKERRQ(ierr); 55778569bb4SMatthew G. Knepley ierr = ISGetIndices(stratumIS, &cells);CHKERRQ(ierr); 55878569bb4SMatthew G. Knepley ierr = ISGetSize(stratumIS, &csSize);CHKERRQ(ierr); 55978569bb4SMatthew G. Knepley for (c = 0; c < csSize; ++c) { 56078569bb4SMatthew G. Knepley ierr = PetscSectionSetDof(section, cells[c], nodes[cs][3] > 0);CHKERRQ(ierr); 56178569bb4SMatthew G. Knepley } 56278569bb4SMatthew G. Knepley ierr = ISRestoreIndices(stratumIS, &cells);CHKERRQ(ierr); 56378569bb4SMatthew G. Knepley ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 56478569bb4SMatthew G. Knepley } 56578569bb4SMatthew G. Knepley if (num_cs > 0) { 56678569bb4SMatthew G. Knepley ierr = ISRestoreIndices(csIS, &csIdx);CHKERRQ(ierr); 56778569bb4SMatthew G. Knepley ierr = ISDestroy(&csIS);CHKERRQ(ierr); 56878569bb4SMatthew G. Knepley } 56978569bb4SMatthew G. Knepley ierr = PetscFree(nodes);CHKERRQ(ierr); 57078569bb4SMatthew G. Knepley ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 57178569bb4SMatthew G. Knepley if (numNodes > 0) { 57278569bb4SMatthew G. Knepley const char *coordNames[3] = {"x", "y", "z"}; 57378569bb4SMatthew G. Knepley PetscScalar *coords, *closure; 57478569bb4SMatthew G. Knepley PetscReal *cval; 57578569bb4SMatthew G. Knepley PetscInt hasDof, n = 0; 57678569bb4SMatthew G. Knepley 57778569bb4SMatthew G. Knepley /* There can't be more than 24 values in the closure of a point for the coord section */ 5786de834b4SMatthew G. Knepley ierr = PetscCalloc3(numNodes*3, &coords, dim, &cval, 24, &closure);CHKERRQ(ierr); 57978569bb4SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coord);CHKERRQ(ierr); 58078569bb4SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 58178569bb4SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 58278569bb4SMatthew G. Knepley ierr = PetscSectionGetDof(section, p, &hasDof); 58378569bb4SMatthew G. Knepley if (hasDof) { 58478569bb4SMatthew G. Knepley PetscInt closureSize = 24, j; 58578569bb4SMatthew G. Knepley 58678569bb4SMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, NULL, coord, p, &closureSize, &closure);CHKERRQ(ierr); 58778569bb4SMatthew G. Knepley for (d = 0; d < dim; ++d) { 58878569bb4SMatthew G. Knepley cval[d] = 0.0; 58978569bb4SMatthew G. Knepley for (j = 0; j < closureSize/dim; j++) cval[d] += closure[j*dim+d]; 59078569bb4SMatthew G. Knepley coords[d*numNodes+n] = cval[d] * dim / closureSize; 59178569bb4SMatthew G. Knepley } 59278569bb4SMatthew G. Knepley ++n; 59378569bb4SMatthew G. Knepley } 59478569bb4SMatthew G. Knepley } 5956de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_coord,(exoid, &coords[0*numNodes], &coords[1*numNodes], &coords[2*numNodes])); 59678569bb4SMatthew G. Knepley ierr = PetscFree3(coords, cval, closure);CHKERRQ(ierr); 5976de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_coord_names,(exoid, (char **) coordNames)); 59878569bb4SMatthew G. Knepley } 59978569bb4SMatthew G. Knepley ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 600fe209ef9SBlaise Bourdin /* --- Node Sets/Vertex Sets --- */ 601fe209ef9SBlaise Bourdin DMHasLabel(dm, "Vertex Sets", &hasLabel); 602fe209ef9SBlaise Bourdin if (hasLabel) { 603fe209ef9SBlaise Bourdin PetscInt i, vs, vsSize; 604fe209ef9SBlaise Bourdin const PetscInt *vsIdx, *vertices; 605fe209ef9SBlaise Bourdin PetscInt *nodeList; 606fe209ef9SBlaise Bourdin IS vsIS, stratumIS; 607fe209ef9SBlaise Bourdin DMLabel vsLabel; 608fe209ef9SBlaise Bourdin ierr = DMGetLabel(dm, "Vertex Sets", &vsLabel);CHKERRQ(ierr); 609fe209ef9SBlaise Bourdin ierr = DMLabelGetValueIS(vsLabel, &vsIS);CHKERRQ(ierr); 610fe209ef9SBlaise Bourdin ierr = ISGetIndices(vsIS, &vsIdx);CHKERRQ(ierr); 611fe209ef9SBlaise Bourdin for (vs=0; vs<num_vs; ++vs) { 612fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(vsLabel, vsIdx[vs], &stratumIS);CHKERRQ(ierr); 613fe209ef9SBlaise Bourdin ierr = ISGetIndices(stratumIS, &vertices);CHKERRQ(ierr); 614fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &vsSize);CHKERRQ(ierr); 615fe209ef9SBlaise Bourdin ierr = PetscMalloc1(vsSize, &nodeList); 616fe209ef9SBlaise Bourdin for (i=0; i<vsSize; ++i) { 617fe209ef9SBlaise Bourdin nodeList[i] = vertices[i] - skipCells + 1; 618fe209ef9SBlaise Bourdin } 619fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set_param,(exoid, EX_NODE_SET, vsIdx[vs], vsSize, 0)); 620fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set,(exoid, EX_NODE_SET, vsIdx[vs], nodeList, NULL)); 621fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(stratumIS, &vertices);CHKERRQ(ierr); 622fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 623fe209ef9SBlaise Bourdin ierr = PetscFree(nodeList);CHKERRQ(ierr); 624fe209ef9SBlaise Bourdin } 625fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(vsIS, &vsIdx);CHKERRQ(ierr); 626fe209ef9SBlaise Bourdin ierr = ISDestroy(&vsIS);CHKERRQ(ierr); 627fe209ef9SBlaise Bourdin } 628fe209ef9SBlaise Bourdin /* --- Side Sets/Face Sets --- */ 629fe209ef9SBlaise Bourdin ierr = DMHasLabel(dm, "Face Sets", &hasLabel);CHKERRQ(ierr); 630fe209ef9SBlaise Bourdin if (hasLabel) { 631fe209ef9SBlaise Bourdin PetscInt i, j, fs, fsSize; 632fe209ef9SBlaise Bourdin const PetscInt *fsIdx, *faces; 633fe209ef9SBlaise Bourdin IS fsIS, stratumIS; 634fe209ef9SBlaise Bourdin DMLabel fsLabel; 635fe209ef9SBlaise Bourdin PetscInt numPoints, *points; 636fe209ef9SBlaise Bourdin PetscInt elem_list_size = 0; 637fe209ef9SBlaise Bourdin PetscInt *elem_list, *elem_ind, *side_list; 638fe209ef9SBlaise Bourdin 639fe209ef9SBlaise Bourdin ierr = DMGetLabel(dm, "Face Sets", &fsLabel);CHKERRQ(ierr); 640fe209ef9SBlaise Bourdin /* Compute size of Node List and Element List */ 641fe209ef9SBlaise Bourdin ierr = DMLabelGetValueIS(fsLabel, &fsIS);CHKERRQ(ierr); 642fe209ef9SBlaise Bourdin ierr = ISGetIndices(fsIS, &fsIdx);CHKERRQ(ierr); 643fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 644feb237baSPierre Jolivet ierr = DMLabelGetStratumIS(fsLabel, fsIdx[fs], &stratumIS);CHKERRQ(ierr); 645fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &fsSize);CHKERRQ(ierr); 646fe209ef9SBlaise Bourdin elem_list_size += fsSize; 647fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 648fe209ef9SBlaise Bourdin } 649fe209ef9SBlaise Bourdin ierr = PetscMalloc3(num_fs, &elem_ind, 650fe209ef9SBlaise Bourdin elem_list_size, &elem_list, 651fe209ef9SBlaise Bourdin elem_list_size, &side_list);CHKERRQ(ierr); 652fe209ef9SBlaise Bourdin elem_ind[0] = 0; 653fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 654fe209ef9SBlaise Bourdin ierr = DMLabelGetStratumIS(fsLabel, fsIdx[fs], &stratumIS);CHKERRQ(ierr); 655fe209ef9SBlaise Bourdin ierr = ISGetIndices(stratumIS, &faces);CHKERRQ(ierr); 656fe209ef9SBlaise Bourdin ierr = ISGetSize(stratumIS, &fsSize);CHKERRQ(ierr); 657fe209ef9SBlaise Bourdin /* Set Parameters */ 658fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set_param,(exoid, EX_SIDE_SET, fsIdx[fs], fsSize, 0)); 659fe209ef9SBlaise Bourdin /* Indices */ 660fe209ef9SBlaise Bourdin if (fs<num_fs-1) { 661fe209ef9SBlaise Bourdin elem_ind[fs+1] = elem_ind[fs] + fsSize; 662fe209ef9SBlaise Bourdin } 663fe209ef9SBlaise Bourdin 664fe209ef9SBlaise Bourdin for (i=0; i<fsSize; ++i) { 665fe209ef9SBlaise Bourdin /* Element List */ 666fe209ef9SBlaise Bourdin points = NULL; 667fe209ef9SBlaise Bourdin ierr = DMPlexGetTransitiveClosure(dm, faces[i], PETSC_FALSE, &numPoints, &points);CHKERRQ(ierr); 668fe209ef9SBlaise Bourdin elem_list[elem_ind[fs] + i] = points[2] +1; 669fe209ef9SBlaise Bourdin ierr = DMPlexRestoreTransitiveClosure(dm, faces[i], PETSC_FALSE, &numPoints, &points);CHKERRQ(ierr); 670fe209ef9SBlaise Bourdin 671fe209ef9SBlaise Bourdin /* Side List */ 672fe209ef9SBlaise Bourdin points = NULL; 673fe209ef9SBlaise Bourdin ierr = DMPlexGetTransitiveClosure(dm, elem_list[elem_ind[fs] + i]-1, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 674fe209ef9SBlaise Bourdin for (j=1; j<numPoints; ++j) { 675fe209ef9SBlaise Bourdin if (points[j*2]==faces[i]) {break;} 676fe209ef9SBlaise Bourdin } 677fe209ef9SBlaise Bourdin /* Convert HEX sides */ 678fe209ef9SBlaise Bourdin if (numPoints == 27) { 679fe209ef9SBlaise Bourdin if (j == 1) {j = 5;} 680fe209ef9SBlaise Bourdin else if (j == 2) {j = 6;} 681fe209ef9SBlaise Bourdin else if (j == 3) {j = 1;} 682fe209ef9SBlaise Bourdin else if (j == 4) {j = 3;} 683fe209ef9SBlaise Bourdin else if (j == 5) {j = 2;} 684fe209ef9SBlaise Bourdin else if (j == 6) {j = 4;} 685fe209ef9SBlaise Bourdin } 686fe209ef9SBlaise Bourdin /* Convert TET sides */ 687fe209ef9SBlaise Bourdin if (numPoints == 15) { 688fe209ef9SBlaise Bourdin --j; 689fe209ef9SBlaise Bourdin if (j == 0) {j = 4;} 690fe209ef9SBlaise Bourdin } 691fe209ef9SBlaise Bourdin side_list[elem_ind[fs] + i] = j; 692fe209ef9SBlaise Bourdin ierr = DMPlexRestoreTransitiveClosure(dm, elem_list[elem_ind[fs] + i]-1, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 693fe209ef9SBlaise Bourdin 694fe209ef9SBlaise Bourdin } 695fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(stratumIS, &faces);CHKERRQ(ierr); 696fe209ef9SBlaise Bourdin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 697fe209ef9SBlaise Bourdin } 698fe209ef9SBlaise Bourdin ierr = ISRestoreIndices(fsIS, &fsIdx);CHKERRQ(ierr); 699fe209ef9SBlaise Bourdin ierr = ISDestroy(&fsIS);CHKERRQ(ierr); 700fe209ef9SBlaise Bourdin 701fe209ef9SBlaise Bourdin /* Put side sets */ 702fe209ef9SBlaise Bourdin for (fs=0; fs<num_fs; ++fs) { 703fe209ef9SBlaise Bourdin PetscStackCallStandard(ex_put_set,(exoid, EX_SIDE_SET, fsIdx[fs], &elem_list[elem_ind[fs]], &side_list[elem_ind[fs]])); 704fe209ef9SBlaise Bourdin } 705fe209ef9SBlaise Bourdin ierr = PetscFree3(elem_ind,elem_list,side_list);CHKERRQ(ierr); 706fe209ef9SBlaise Bourdin } 70778569bb4SMatthew G. Knepley PetscFunctionReturn(0); 70878569bb4SMatthew G. Knepley } 70978569bb4SMatthew G. Knepley 71078569bb4SMatthew G. Knepley /* 71178569bb4SMatthew G. Knepley VecViewPlex_ExodusII_Nodal_Internal - Write a Vec corresponding to a nodal field to an exodus file 71278569bb4SMatthew G. Knepley 71378569bb4SMatthew G. Knepley Collective on v 71478569bb4SMatthew G. Knepley 71578569bb4SMatthew G. Knepley Input Parameters: 71678569bb4SMatthew G. Knepley + v - The vector to be written 71778569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 71878569bb4SMatthew G. Knepley - step - the time step to write at (exodus steps are numbered starting from 1) 71978569bb4SMatthew G. Knepley 72078569bb4SMatthew G. Knepley Notes: 72178569bb4SMatthew G. Knepley The exodus result nodal variable index is obtained by comparing the Vec name and the 72278569bb4SMatthew G. Knepley names of nodal variables declared in the exodus file. For instance for a Vec named "V" 72378569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 72478569bb4SMatthew G. Knepley amongst all nodal variables. 72578569bb4SMatthew G. Knepley 72678569bb4SMatthew G. Knepley Level: beginner 72778569bb4SMatthew G. Knepley 72878569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(),DMPlexView_ExodusII_Internal(),VecLoadNodal_PlexEXO(),VecViewZonal_PlexEXO(),VecLoadZonal_PlexEXO() 72978569bb4SMatthew G. Knepley @*/ 73078569bb4SMatthew G. Knepley PetscErrorCode VecViewPlex_ExodusII_Nodal_Internal(Vec v, int exoid, int step) 73178569bb4SMatthew G. Knepley { 73278569bb4SMatthew G. Knepley MPI_Comm comm; 73378569bb4SMatthew G. Knepley PetscMPIInt size; 73478569bb4SMatthew G. Knepley DM dm; 73578569bb4SMatthew G. Knepley Vec vNatural, vComp; 73622a7544eSVaclav Hapla const PetscScalar *varray; 73778569bb4SMatthew G. Knepley const char *vecname; 73878569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 73978569bb4SMatthew G. Knepley PetscBool useNatural; 74078569bb4SMatthew G. Knepley int offset; 74178569bb4SMatthew G. Knepley PetscErrorCode ierr; 74278569bb4SMatthew G. Knepley 74378569bb4SMatthew G. Knepley PetscFunctionBegin; 74478569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) v, &comm);CHKERRQ(ierr); 74578569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 74678569bb4SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 74778569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 74878569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 74978569bb4SMatthew G. Knepley if (useNatural) { 75078569bb4SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &vNatural);CHKERRQ(ierr); 75178569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, v, vNatural);CHKERRQ(ierr); 75278569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, v, vNatural);CHKERRQ(ierr); 75378569bb4SMatthew G. Knepley } else { 75478569bb4SMatthew G. Knepley vNatural = v; 75578569bb4SMatthew G. Knepley } 75678569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 75778569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 75878569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_NODAL, vecname, &offset);CHKERRQ(ierr); 75978569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate nodal variable %s in exodus file\n", vecname); 76078569bb4SMatthew G. Knepley /* Write local chunk of the result in the exodus file 76178569bb4SMatthew G. Knepley exodus stores each component of a vector-valued field as a separate variable. 76278569bb4SMatthew G. Knepley We assume that they are stored sequentially */ 76378569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 76478569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 76578569bb4SMatthew G. Knepley if (bs == 1) { 76678569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vNatural, &varray);CHKERRQ(ierr); 7676de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_partial_var,(exoid, step, EX_NODAL, offset, 1, xs+1, xe-xs, varray)); 76878569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vNatural, &varray);CHKERRQ(ierr); 76978569bb4SMatthew G. Knepley } else { 77078569bb4SMatthew G. Knepley IS compIS; 77178569bb4SMatthew G. Knepley PetscInt c; 77278569bb4SMatthew G. Knepley 77394a2d30dSStefano Zampini ierr = ISCreateStride(comm, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr); 77478569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 77578569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 77678569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 77778569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vComp, &varray);CHKERRQ(ierr); 7786de834b4SMatthew G. Knepley PetscStackCallStandard(ex_put_partial_var,(exoid, step, EX_NODAL, offset+c, 1, xs/bs+1, (xe-xs)/bs, varray)); 77978569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vComp, &varray);CHKERRQ(ierr); 78078569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 78178569bb4SMatthew G. Knepley } 78278569bb4SMatthew G. Knepley ierr = ISDestroy(&compIS);CHKERRQ(ierr); 78378569bb4SMatthew G. Knepley } 78478569bb4SMatthew G. Knepley if (useNatural) {ierr = DMRestoreGlobalVector(dm, &vNatural);CHKERRQ(ierr);} 78578569bb4SMatthew G. Knepley PetscFunctionReturn(0); 78678569bb4SMatthew G. Knepley } 78778569bb4SMatthew G. Knepley 78878569bb4SMatthew G. Knepley /* 78978569bb4SMatthew G. Knepley VecLoadPlex_ExodusII_Nodal_Internal - Read a Vec corresponding to a nodal field from an exodus file 79078569bb4SMatthew G. Knepley 79178569bb4SMatthew G. Knepley Collective on v 79278569bb4SMatthew G. Knepley 79378569bb4SMatthew G. Knepley Input Parameters: 79478569bb4SMatthew G. Knepley + v - The vector to be written 79578569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 79678569bb4SMatthew G. Knepley - step - the time step to read at (exodus steps are numbered starting from 1) 79778569bb4SMatthew G. Knepley 79878569bb4SMatthew G. Knepley Notes: 79978569bb4SMatthew G. Knepley The exodus result nodal variable index is obtained by comparing the Vec name and the 80078569bb4SMatthew G. Knepley names of nodal variables declared in the exodus file. For instance for a Vec named "V" 80178569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 80278569bb4SMatthew G. Knepley amongst all nodal variables. 80378569bb4SMatthew G. Knepley 80478569bb4SMatthew G. Knepley Level: beginner 80578569bb4SMatthew G. Knepley 80678569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(), DMPlexView_ExodusII_Internal(), VecViewPlex_ExodusII_Nodal_Internal(), VecViewZonal_PlexEXO(), VecLoadZonal_PlexEXO() 80778569bb4SMatthew G. Knepley */ 80878569bb4SMatthew G. Knepley PetscErrorCode VecLoadPlex_ExodusII_Nodal_Internal(Vec v, int exoid, int step) 80978569bb4SMatthew G. Knepley { 81078569bb4SMatthew G. Knepley MPI_Comm comm; 81178569bb4SMatthew G. Knepley PetscMPIInt size; 81278569bb4SMatthew G. Knepley DM dm; 81378569bb4SMatthew G. Knepley Vec vNatural, vComp; 81422a7544eSVaclav Hapla PetscScalar *varray; 81578569bb4SMatthew G. Knepley const char *vecname; 81678569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 81778569bb4SMatthew G. Knepley PetscBool useNatural; 81878569bb4SMatthew G. Knepley int offset; 81978569bb4SMatthew G. Knepley PetscErrorCode ierr; 82078569bb4SMatthew G. Knepley 82178569bb4SMatthew G. Knepley PetscFunctionBegin; 82278569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) v, &comm);CHKERRQ(ierr); 82378569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 82478569bb4SMatthew G. Knepley ierr = VecGetDM(v,&dm);CHKERRQ(ierr); 82578569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 82678569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 82778569bb4SMatthew G. Knepley if (useNatural) {ierr = DMGetGlobalVector(dm,&vNatural);CHKERRQ(ierr);} 82878569bb4SMatthew G. Knepley else {vNatural = v;} 82978569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 83078569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 83178569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_NODAL, vecname, &offset);CHKERRQ(ierr); 83278569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate nodal variable %s in exodus file", vecname); 83378569bb4SMatthew G. Knepley /* Read local chunk from the file */ 83478569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 83578569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 83678569bb4SMatthew G. Knepley if (bs == 1) { 83778569bb4SMatthew G. Knepley ierr = VecGetArray(vNatural, &varray);CHKERRQ(ierr); 8386de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_partial_var,(exoid, step, EX_NODAL, offset, 1, xs+1, xe-xs, varray)); 83978569bb4SMatthew G. Knepley ierr = VecRestoreArray(vNatural, &varray);CHKERRQ(ierr); 84078569bb4SMatthew G. Knepley } else { 84178569bb4SMatthew G. Knepley IS compIS; 84278569bb4SMatthew G. Knepley PetscInt c; 84378569bb4SMatthew G. Knepley 84494a2d30dSStefano Zampini ierr = ISCreateStride(comm, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr); 84578569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 84678569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 84778569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 84878569bb4SMatthew G. Knepley ierr = VecGetArray(vComp, &varray);CHKERRQ(ierr); 8496de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_partial_var,(exoid, step, EX_NODAL, offset+c, 1, xs/bs+1, (xe-xs)/bs, varray)); 85078569bb4SMatthew G. Knepley ierr = VecRestoreArray(vComp, &varray);CHKERRQ(ierr); 85178569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 85278569bb4SMatthew G. Knepley } 85378569bb4SMatthew G. Knepley ierr = ISDestroy(&compIS);CHKERRQ(ierr); 85478569bb4SMatthew G. Knepley } 85578569bb4SMatthew G. Knepley if (useNatural) { 85678569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, vNatural, v);CHKERRQ(ierr); 85778569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, vNatural, v);CHKERRQ(ierr); 85878569bb4SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &vNatural);CHKERRQ(ierr); 85978569bb4SMatthew G. Knepley } 86078569bb4SMatthew G. Knepley PetscFunctionReturn(0); 86178569bb4SMatthew G. Knepley } 86278569bb4SMatthew G. Knepley 86378569bb4SMatthew G. Knepley /* 86478569bb4SMatthew G. Knepley VecViewPlex_ExodusII_Zonal_Internal - Write a Vec corresponding to a zonal (cell based) field to an exodus file 86578569bb4SMatthew G. Knepley 86678569bb4SMatthew G. Knepley Collective on v 86778569bb4SMatthew G. Knepley 86878569bb4SMatthew G. Knepley Input Parameters: 86978569bb4SMatthew G. Knepley + v - The vector to be written 87078569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 87178569bb4SMatthew G. Knepley - step - the time step to write at (exodus steps are numbered starting from 1) 87278569bb4SMatthew G. Knepley 87378569bb4SMatthew G. Knepley Notes: 87478569bb4SMatthew G. Knepley The exodus result zonal variable index is obtained by comparing the Vec name and the 87578569bb4SMatthew G. Knepley names of zonal variables declared in the exodus file. For instance for a Vec named "V" 87678569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 87778569bb4SMatthew G. Knepley amongst all zonal variables. 87878569bb4SMatthew G. Knepley 87978569bb4SMatthew G. Knepley Level: beginner 88078569bb4SMatthew G. Knepley 88178569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(),DMPlexView_ExodusII_Internal(),VecViewPlex_ExodusII_Nodal_Internal(),VecLoadPlex_ExodusII_Nodal_Internal(),VecLoadPlex_ExodusII_Zonal_Internal() 88278569bb4SMatthew G. Knepley */ 88378569bb4SMatthew G. Knepley PetscErrorCode VecViewPlex_ExodusII_Zonal_Internal(Vec v, int exoid, int step) 88478569bb4SMatthew G. Knepley { 88578569bb4SMatthew G. Knepley MPI_Comm comm; 88678569bb4SMatthew G. Knepley PetscMPIInt size; 88778569bb4SMatthew G. Knepley DM dm; 88878569bb4SMatthew G. Knepley Vec vNatural, vComp; 88922a7544eSVaclav Hapla const PetscScalar *varray; 89078569bb4SMatthew G. Knepley const char *vecname; 89178569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 89278569bb4SMatthew G. Knepley PetscBool useNatural; 89378569bb4SMatthew G. Knepley int offset; 89478569bb4SMatthew G. Knepley IS compIS; 89578569bb4SMatthew G. Knepley PetscInt *csSize, *csID; 89678569bb4SMatthew G. Knepley PetscInt numCS, set, csxs = 0; 89778569bb4SMatthew G. Knepley PetscErrorCode ierr; 89878569bb4SMatthew G. Knepley 89978569bb4SMatthew G. Knepley PetscFunctionBegin; 90078569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)v, &comm);CHKERRQ(ierr); 90178569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 90278569bb4SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 90378569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 90478569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 90578569bb4SMatthew G. Knepley if (useNatural) { 90678569bb4SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &vNatural);CHKERRQ(ierr); 90778569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, v, vNatural);CHKERRQ(ierr); 90878569bb4SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, v, vNatural);CHKERRQ(ierr); 90978569bb4SMatthew G. Knepley } else { 91078569bb4SMatthew G. Knepley vNatural = v; 91178569bb4SMatthew G. Knepley } 91278569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 91378569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 91478569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_ELEM_BLOCK, vecname, &offset);CHKERRQ(ierr); 91578569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate zonal variable %s in exodus file\n", vecname); 91678569bb4SMatthew G. Knepley /* Write local chunk of the result in the exodus file 91778569bb4SMatthew G. Knepley exodus stores each component of a vector-valued field as a separate variable. 91878569bb4SMatthew G. Knepley We assume that they are stored sequentially 91978569bb4SMatthew G. Knepley Zonal variables are accessed one element block at a time, so we loop through the cell sets, 92078569bb4SMatthew G. Knepley but once the vector has been reordered to natural size, we cannot use the label informations 92178569bb4SMatthew G. Knepley to figure out what to save where. */ 92278569bb4SMatthew G. Knepley numCS = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); 92378569bb4SMatthew G. Knepley ierr = PetscMalloc2(numCS, &csID, numCS, &csSize);CHKERRQ(ierr); 9246de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_ELEM_BLOCK, csID)); 92578569bb4SMatthew G. Knepley for (set = 0; set < numCS; ++set) { 92678569bb4SMatthew G. Knepley ex_block block; 92778569bb4SMatthew G. Knepley 92878569bb4SMatthew G. Knepley block.id = csID[set]; 92978569bb4SMatthew G. Knepley block.type = EX_ELEM_BLOCK; 9306de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_block_param,(exoid, &block)); 93178569bb4SMatthew G. Knepley csSize[set] = block.num_entry; 93278569bb4SMatthew G. Knepley } 93378569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 93478569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 93578569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISCreateStride(comm, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr);} 93678569bb4SMatthew G. Knepley for (set = 0; set < numCS; set++) { 93778569bb4SMatthew G. Knepley PetscInt csLocalSize, c; 93878569bb4SMatthew G. Knepley 93978569bb4SMatthew G. Knepley /* range of indices for set setID[set]: csxs:csxs + csSize[set]-1 94078569bb4SMatthew G. Knepley local slice of zonal values: xs/bs,xm/bs-1 94178569bb4SMatthew G. Knepley intersection: max(xs/bs,csxs),min(xm/bs-1,csxs + csSize[set]-1) */ 94278569bb4SMatthew G. Knepley csLocalSize = PetscMax(0, PetscMin(xe/bs, csxs+csSize[set]) - PetscMax(xs/bs, csxs)); 94378569bb4SMatthew G. Knepley if (bs == 1) { 94478569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vNatural, &varray);CHKERRQ(ierr); 9456de834b4SMatthew 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)])); 94678569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vNatural, &varray);CHKERRQ(ierr); 94778569bb4SMatthew G. Knepley } else { 94878569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 94978569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 95078569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 95178569bb4SMatthew G. Knepley ierr = VecGetArrayRead(vComp, &varray);CHKERRQ(ierr); 9526de834b4SMatthew 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)])); 95378569bb4SMatthew G. Knepley ierr = VecRestoreArrayRead(vComp, &varray);CHKERRQ(ierr); 95478569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 95578569bb4SMatthew G. Knepley } 95678569bb4SMatthew G. Knepley } 95778569bb4SMatthew G. Knepley csxs += csSize[set]; 95878569bb4SMatthew G. Knepley } 95978569bb4SMatthew G. Knepley ierr = PetscFree2(csID, csSize);CHKERRQ(ierr); 96078569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISDestroy(&compIS);CHKERRQ(ierr);} 96178569bb4SMatthew G. Knepley if (useNatural) {ierr = DMRestoreGlobalVector(dm,&vNatural);CHKERRQ(ierr);} 96278569bb4SMatthew G. Knepley PetscFunctionReturn(0); 96378569bb4SMatthew G. Knepley } 96478569bb4SMatthew G. Knepley 96578569bb4SMatthew G. Knepley /* 96678569bb4SMatthew G. Knepley VecLoadPlex_ExodusII_Zonal_Internal - Read a Vec corresponding to a zonal (cell based) field from an exodus file 96778569bb4SMatthew G. Knepley 96878569bb4SMatthew G. Knepley Collective on v 96978569bb4SMatthew G. Knepley 97078569bb4SMatthew G. Knepley Input Parameters: 97178569bb4SMatthew G. Knepley + v - The vector to be written 97278569bb4SMatthew G. Knepley . exoid - the exodus id of a file (obtained from ex_open or ex_create for instance) 97378569bb4SMatthew G. Knepley - step - the time step to read at (exodus steps are numbered starting from 1) 97478569bb4SMatthew G. Knepley 97578569bb4SMatthew G. Knepley Notes: 97678569bb4SMatthew G. Knepley The exodus result zonal variable index is obtained by comparing the Vec name and the 97778569bb4SMatthew G. Knepley names of zonal variables declared in the exodus file. For instance for a Vec named "V" 97878569bb4SMatthew G. Knepley the location in the exodus file will be the first match of "V", "V_X", "V_XX", "V_1", or "V_11" 97978569bb4SMatthew G. Knepley amongst all zonal variables. 98078569bb4SMatthew G. Knepley 98178569bb4SMatthew G. Knepley Level: beginner 98278569bb4SMatthew G. Knepley 98378569bb4SMatthew G. Knepley .seealso: EXOGetVarIndex_Private(), DMPlexView_ExodusII_Internal(), VecViewPlex_ExodusII_Nodal_Internal(), VecLoadPlex_ExodusII_Nodal_Internal(), VecLoadPlex_ExodusII_Zonal_Internal() 98478569bb4SMatthew G. Knepley */ 98578569bb4SMatthew G. Knepley PetscErrorCode VecLoadPlex_ExodusII_Zonal_Internal(Vec v, int exoid, int step) 98678569bb4SMatthew G. Knepley { 98778569bb4SMatthew G. Knepley MPI_Comm comm; 98878569bb4SMatthew G. Knepley PetscMPIInt size; 98978569bb4SMatthew G. Knepley DM dm; 99078569bb4SMatthew G. Knepley Vec vNatural, vComp; 99122a7544eSVaclav Hapla PetscScalar *varray; 99278569bb4SMatthew G. Knepley const char *vecname; 99378569bb4SMatthew G. Knepley PetscInt xs, xe, bs; 99478569bb4SMatthew G. Knepley PetscBool useNatural; 99578569bb4SMatthew G. Knepley int offset; 99678569bb4SMatthew G. Knepley IS compIS; 99778569bb4SMatthew G. Knepley PetscInt *csSize, *csID; 99878569bb4SMatthew G. Knepley PetscInt numCS, set, csxs = 0; 99978569bb4SMatthew G. Knepley PetscErrorCode ierr; 100078569bb4SMatthew G. Knepley 100178569bb4SMatthew G. Knepley PetscFunctionBegin; 100278569bb4SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 100378569bb4SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 100478569bb4SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 100578569bb4SMatthew G. Knepley ierr = DMGetUseNatural(dm, &useNatural);CHKERRQ(ierr); 100678569bb4SMatthew G. Knepley useNatural = useNatural && size > 1 ? PETSC_TRUE : PETSC_FALSE; 100778569bb4SMatthew G. Knepley if (useNatural) {ierr = DMGetGlobalVector(dm,&vNatural);CHKERRQ(ierr);} 100878569bb4SMatthew G. Knepley else {vNatural = v;} 100978569bb4SMatthew G. Knepley /* Get the location of the variable in the exodus file */ 101078569bb4SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &vecname);CHKERRQ(ierr); 101178569bb4SMatthew G. Knepley ierr = EXOGetVarIndex_Private(exoid, EX_ELEM_BLOCK, vecname, &offset);CHKERRQ(ierr); 101278569bb4SMatthew G. Knepley if (!offset) SETERRQ1(comm, PETSC_ERR_FILE_UNEXPECTED, "Cannot locate zonal variable %s in exodus file\n", vecname); 101378569bb4SMatthew G. Knepley /* Read local chunk of the result in the exodus file 101478569bb4SMatthew G. Knepley exodus stores each component of a vector-valued field as a separate variable. 101578569bb4SMatthew G. Knepley We assume that they are stored sequentially 101678569bb4SMatthew G. Knepley Zonal variables are accessed one element block at a time, so we loop through the cell sets, 101778569bb4SMatthew G. Knepley but once the vector has been reordered to natural size, we cannot use the label informations 101878569bb4SMatthew G. Knepley to figure out what to save where. */ 101978569bb4SMatthew G. Knepley numCS = ex_inquire_int(exoid, EX_INQ_ELEM_BLK); 102078569bb4SMatthew G. Knepley ierr = PetscMalloc2(numCS, &csID, numCS, &csSize);CHKERRQ(ierr); 10216de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_ELEM_BLOCK, csID)); 102278569bb4SMatthew G. Knepley for (set = 0; set < numCS; ++set) { 102378569bb4SMatthew G. Knepley ex_block block; 102478569bb4SMatthew G. Knepley 102578569bb4SMatthew G. Knepley block.id = csID[set]; 102678569bb4SMatthew G. Knepley block.type = EX_ELEM_BLOCK; 10276de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_block_param,(exoid, &block)); 102878569bb4SMatthew G. Knepley csSize[set] = block.num_entry; 102978569bb4SMatthew G. Knepley } 103078569bb4SMatthew G. Knepley ierr = VecGetOwnershipRange(vNatural, &xs, &xe);CHKERRQ(ierr); 103178569bb4SMatthew G. Knepley ierr = VecGetBlockSize(vNatural, &bs);CHKERRQ(ierr); 103278569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISCreateStride(comm, (xe-xs)/bs, xs, bs, &compIS);CHKERRQ(ierr);} 103378569bb4SMatthew G. Knepley for (set = 0; set < numCS; ++set) { 103478569bb4SMatthew G. Knepley PetscInt csLocalSize, c; 103578569bb4SMatthew G. Knepley 103678569bb4SMatthew G. Knepley /* range of indices for set setID[set]: csxs:csxs + csSize[set]-1 103778569bb4SMatthew G. Knepley local slice of zonal values: xs/bs,xm/bs-1 103878569bb4SMatthew G. Knepley intersection: max(xs/bs,csxs),min(xm/bs-1,csxs + csSize[set]-1) */ 103978569bb4SMatthew G. Knepley csLocalSize = PetscMax(0, PetscMin(xe/bs, csxs+csSize[set]) - PetscMax(xs/bs, csxs)); 104078569bb4SMatthew G. Knepley if (bs == 1) { 104178569bb4SMatthew G. Knepley ierr = VecGetArray(vNatural, &varray);CHKERRQ(ierr); 10426de834b4SMatthew 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)])); 104378569bb4SMatthew G. Knepley ierr = VecRestoreArray(vNatural, &varray);CHKERRQ(ierr); 104478569bb4SMatthew G. Knepley } else { 104578569bb4SMatthew G. Knepley for (c = 0; c < bs; ++c) { 104678569bb4SMatthew G. Knepley ierr = ISStrideSetStride(compIS, (xe-xs)/bs, xs+c, bs);CHKERRQ(ierr); 104778569bb4SMatthew G. Knepley ierr = VecGetSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 104878569bb4SMatthew G. Knepley ierr = VecGetArray(vComp, &varray);CHKERRQ(ierr); 10496de834b4SMatthew 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)])); 105078569bb4SMatthew G. Knepley ierr = VecRestoreArray(vComp, &varray);CHKERRQ(ierr); 105178569bb4SMatthew G. Knepley ierr = VecRestoreSubVector(vNatural, compIS, &vComp);CHKERRQ(ierr); 105278569bb4SMatthew G. Knepley } 105378569bb4SMatthew G. Knepley } 105478569bb4SMatthew G. Knepley csxs += csSize[set]; 105578569bb4SMatthew G. Knepley } 105678569bb4SMatthew G. Knepley ierr = PetscFree2(csID, csSize);CHKERRQ(ierr); 105778569bb4SMatthew G. Knepley if (bs > 1) {ierr = ISDestroy(&compIS);CHKERRQ(ierr);} 105878569bb4SMatthew G. Knepley if (useNatural) { 105978569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, vNatural, v);CHKERRQ(ierr); 106078569bb4SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, vNatural, v);CHKERRQ(ierr); 106178569bb4SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &vNatural);CHKERRQ(ierr); 106278569bb4SMatthew G. Knepley } 106378569bb4SMatthew G. Knepley PetscFunctionReturn(0); 106478569bb4SMatthew G. Knepley } 1065b53c8456SSatish Balay #endif 106678569bb4SMatthew G. Knepley 10671e50132fSMatthew G. Knepley /*@ 10681e50132fSMatthew G. Knepley PetscViewerExodusIIGetId - Get the file id of the ExodusII file 10691e50132fSMatthew G. Knepley 10701e50132fSMatthew G. Knepley Logically Collective on PetscViewer 10711e50132fSMatthew G. Knepley 10721e50132fSMatthew G. Knepley Input Parameter: 10731e50132fSMatthew G. Knepley . viewer - the PetscViewer 10741e50132fSMatthew G. Knepley 10751e50132fSMatthew G. Knepley Output Parameter: 10761e50132fSMatthew G. Knepley - exoid - The ExodusII file id 10771e50132fSMatthew G. Knepley 10781e50132fSMatthew G. Knepley Level: intermediate 10791e50132fSMatthew G. Knepley 10801e50132fSMatthew G. Knepley .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 10811e50132fSMatthew G. Knepley @*/ 10821e50132fSMatthew G. Knepley PetscErrorCode PetscViewerExodusIIGetId(PetscViewer viewer, int *exoid) 10831e50132fSMatthew G. Knepley { 10841e50132fSMatthew G. Knepley PetscErrorCode ierr; 10851e50132fSMatthew G. Knepley 10861e50132fSMatthew G. Knepley PetscFunctionBegin; 10871e50132fSMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 10881e50132fSMatthew G. Knepley ierr = PetscTryMethod(viewer, "PetscViewerExodusIIGetId_C",(PetscViewer,int*),(viewer,exoid));CHKERRQ(ierr); 10891e50132fSMatthew G. Knepley PetscFunctionReturn(0); 10901e50132fSMatthew G. Knepley } 10911e50132fSMatthew G. Knepley 109233751fbdSMichael Lange /*@C 1093eaf898f9SPatrick Sanan DMPlexCreateExodusFromFile - Create a DMPlex mesh from an ExodusII file. 109433751fbdSMichael Lange 1095d083f849SBarry Smith Collective 109633751fbdSMichael Lange 109733751fbdSMichael Lange Input Parameters: 109833751fbdSMichael Lange + comm - The MPI communicator 109933751fbdSMichael Lange . filename - The name of the ExodusII file 110033751fbdSMichael Lange - interpolate - Create faces and edges in the mesh 110133751fbdSMichael Lange 110233751fbdSMichael Lange Output Parameter: 110333751fbdSMichael Lange . dm - The DM object representing the mesh 110433751fbdSMichael Lange 110533751fbdSMichael Lange Level: beginner 110633751fbdSMichael Lange 110733751fbdSMichael Lange .seealso: DMPLEX, DMCreate(), DMPlexCreateExodus() 110833751fbdSMichael Lange @*/ 110933751fbdSMichael Lange PetscErrorCode DMPlexCreateExodusFromFile(MPI_Comm comm, const char filename[], PetscBool interpolate, DM *dm) 111033751fbdSMichael Lange { 111133751fbdSMichael Lange PetscMPIInt rank; 111233751fbdSMichael Lange PetscErrorCode ierr; 111333751fbdSMichael Lange #if defined(PETSC_HAVE_EXODUSII) 1114e84f7031SBlaise Bourdin int CPU_word_size = sizeof(PetscReal), IO_word_size = 0, exoid = -1; 111533751fbdSMichael Lange float version; 111633751fbdSMichael Lange #endif 111733751fbdSMichael Lange 111833751fbdSMichael Lange PetscFunctionBegin; 111933751fbdSMichael Lange PetscValidCharPointer(filename, 2); 112033751fbdSMichael Lange ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 112133751fbdSMichael Lange #if defined(PETSC_HAVE_EXODUSII) 112233751fbdSMichael Lange if (!rank) { 112333751fbdSMichael Lange exoid = ex_open(filename, EX_READ, &CPU_word_size, &IO_word_size, &version); 112433751fbdSMichael Lange if (exoid <= 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_LIB, "ex_open(\"%s\",...) did not return a valid file ID", filename); 112533751fbdSMichael Lange } 112633751fbdSMichael Lange ierr = DMPlexCreateExodus(comm, exoid, interpolate, dm);CHKERRQ(ierr); 11276de834b4SMatthew G. Knepley if (!rank) {PetscStackCallStandard(ex_close,(exoid));} 1128*b458e8f1SJose E. Roman PetscFunctionReturn(0); 112933751fbdSMichael Lange #else 113033751fbdSMichael Lange SETERRQ(comm, PETSC_ERR_SUP, "This method requires ExodusII support. Reconfigure using --download-exodusii"); 113133751fbdSMichael Lange #endif 113233751fbdSMichael Lange } 113333751fbdSMichael Lange 11348f861fbcSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 11358f861fbcSMatthew G. Knepley static PetscErrorCode ExodusGetCellType_Private(const char *elem_type, DMPolytopeType *ct) 11368f861fbcSMatthew G. Knepley { 11378f861fbcSMatthew G. Knepley PetscBool flg; 11388f861fbcSMatthew G. Knepley PetscErrorCode ierr; 11398f861fbcSMatthew G. Knepley 11408f861fbcSMatthew G. Knepley PetscFunctionBegin; 11418f861fbcSMatthew G. Knepley *ct = DM_POLYTOPE_UNKNOWN; 11428f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "TRI", &flg);CHKERRQ(ierr); 11438f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_TRIANGLE; goto done;} 11448f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "TRI3", &flg);CHKERRQ(ierr); 11458f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_TRIANGLE; goto done;} 11468f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "QUAD", &flg);CHKERRQ(ierr); 11478f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_QUADRILATERAL; goto done;} 11488f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "QUAD4", &flg);CHKERRQ(ierr); 11498f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_QUADRILATERAL; goto done;} 11508f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "SHELL4", &flg);CHKERRQ(ierr); 11518f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_QUADRILATERAL; goto done;} 11528f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "TETRA", &flg);CHKERRQ(ierr); 11538f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_TETRAHEDRON; goto done;} 11548f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "TET4", &flg);CHKERRQ(ierr); 11558f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_TETRAHEDRON; goto done;} 11568f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "WEDGE", &flg);CHKERRQ(ierr); 11578f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_TRI_PRISM; goto done;} 11588f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "HEX", &flg);CHKERRQ(ierr); 11598f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_HEXAHEDRON; goto done;} 11608f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "HEX8", &flg);CHKERRQ(ierr); 11618f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_HEXAHEDRON; goto done;} 11628f861fbcSMatthew G. Knepley ierr = PetscStrcmp(elem_type, "HEXAHEDRON", &flg);CHKERRQ(ierr); 11638f861fbcSMatthew G. Knepley if (flg) {*ct = DM_POLYTOPE_HEXAHEDRON; goto done;} 11648f861fbcSMatthew G. Knepley SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unrecognized element type %s", elem_type); 11658f861fbcSMatthew G. Knepley done: 11668f861fbcSMatthew G. Knepley PetscFunctionReturn(0); 11678f861fbcSMatthew G. Knepley } 11688f861fbcSMatthew G. Knepley #endif 11698f861fbcSMatthew G. Knepley 1170552f7358SJed Brown /*@ 117133751fbdSMichael Lange DMPlexCreateExodus - Create a DMPlex mesh from an ExodusII file ID. 1172552f7358SJed Brown 1173d083f849SBarry Smith Collective 1174552f7358SJed Brown 1175552f7358SJed Brown Input Parameters: 1176552f7358SJed Brown + comm - The MPI communicator 1177552f7358SJed Brown . exoid - The ExodusII id associated with a exodus file and obtained using ex_open 1178552f7358SJed Brown - interpolate - Create faces and edges in the mesh 1179552f7358SJed Brown 1180552f7358SJed Brown Output Parameter: 1181552f7358SJed Brown . dm - The DM object representing the mesh 1182552f7358SJed Brown 1183552f7358SJed Brown Level: beginner 1184552f7358SJed Brown 1185e84e7769SJed Brown .seealso: DMPLEX, DMCreate() 1186552f7358SJed Brown @*/ 1187552f7358SJed Brown PetscErrorCode DMPlexCreateExodus(MPI_Comm comm, PetscInt exoid, PetscBool interpolate, DM *dm) 1188552f7358SJed Brown { 1189552f7358SJed Brown #if defined(PETSC_HAVE_EXODUSII) 1190552f7358SJed Brown PetscMPIInt num_proc, rank; 1191552f7358SJed Brown PetscSection coordSection; 1192552f7358SJed Brown Vec coordinates; 1193552f7358SJed Brown PetscScalar *coords; 1194552f7358SJed Brown PetscInt coordSize, v; 1195552f7358SJed Brown PetscErrorCode ierr; 1196552f7358SJed Brown /* Read from ex_get_init() */ 1197552f7358SJed Brown char title[PETSC_MAX_PATH_LEN+1]; 11988f861fbcSMatthew G. Knepley int dim = 0, dimEmbed = 0, numVertices = 0, numCells = 0, numHybridCells = 0; 1199552f7358SJed Brown int num_cs = 0, num_vs = 0, num_fs = 0; 1200552f7358SJed Brown #endif 1201552f7358SJed Brown 1202552f7358SJed Brown PetscFunctionBegin; 1203552f7358SJed Brown #if defined(PETSC_HAVE_EXODUSII) 1204552f7358SJed Brown ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1205552f7358SJed Brown ierr = MPI_Comm_size(comm, &num_proc);CHKERRQ(ierr); 1206552f7358SJed Brown ierr = DMCreate(comm, dm);CHKERRQ(ierr); 1207552f7358SJed Brown ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 1208552f7358SJed Brown /* Open EXODUS II file and read basic informations on rank 0, then broadcast to all processors */ 1209552f7358SJed Brown if (!rank) { 1210580bdb30SBarry Smith ierr = PetscMemzero(title,PETSC_MAX_PATH_LEN+1);CHKERRQ(ierr); 12118f861fbcSMatthew G. Knepley PetscStackCallStandard(ex_get_init,(exoid, title, &dimEmbed, &numVertices, &numCells, &num_cs, &num_vs, &num_fs)); 1212552f7358SJed Brown if (!num_cs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Exodus file does not contain any cell set\n"); 1213552f7358SJed Brown } 1214552f7358SJed Brown ierr = MPI_Bcast(title, PETSC_MAX_PATH_LEN+1, MPI_CHAR, 0, comm);CHKERRQ(ierr); 1215552f7358SJed Brown ierr = MPI_Bcast(&dim, 1, MPI_INT, 0, comm);CHKERRQ(ierr); 1216552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) *dm, title);CHKERRQ(ierr); 1217552f7358SJed Brown ierr = DMPlexSetChart(*dm, 0, numCells+numVertices);CHKERRQ(ierr); 1218412e9a14SMatthew G. Knepley /* We do not want this label automatically computed, instead we compute it here */ 1219412e9a14SMatthew G. Knepley ierr = DMCreateLabel(*dm, "celltype");CHKERRQ(ierr); 1220552f7358SJed Brown 1221552f7358SJed Brown /* Read cell sets information */ 1222552f7358SJed Brown if (!rank) { 1223552f7358SJed Brown PetscInt *cone; 1224e8f6893fSMatthew G. Knepley int c, cs, ncs, c_loc, v, v_loc; 1225552f7358SJed Brown /* Read from ex_get_elem_blk_ids() */ 1226e8f6893fSMatthew G. Knepley int *cs_id, *cs_order; 1227552f7358SJed Brown /* Read from ex_get_elem_block() */ 1228552f7358SJed Brown char buffer[PETSC_MAX_PATH_LEN+1]; 1229e8f6893fSMatthew G. Knepley int num_cell_in_set, num_vertex_per_cell, num_hybrid, num_attr; 1230552f7358SJed Brown /* Read from ex_get_elem_conn() */ 1231552f7358SJed Brown int *cs_connect; 1232552f7358SJed Brown 1233552f7358SJed Brown /* Get cell sets IDs */ 1234e8f6893fSMatthew G. Knepley ierr = PetscMalloc2(num_cs, &cs_id, num_cs, &cs_order);CHKERRQ(ierr); 12356de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_ELEM_BLOCK, cs_id)); 1236552f7358SJed Brown /* Read the cell set connectivity table and build mesh topology 1237552f7358SJed Brown EXO standard requires that cells in cell sets be numbered sequentially and be pairwise disjoint. */ 1238e8f6893fSMatthew G. Knepley /* Check for a hybrid mesh */ 1239e8f6893fSMatthew G. Knepley for (cs = 0, num_hybrid = 0; cs < num_cs; ++cs) { 12408f861fbcSMatthew G. Knepley DMPolytopeType ct; 12418f861fbcSMatthew G. Knepley char elem_type[PETSC_MAX_PATH_LEN]; 12428f861fbcSMatthew G. Knepley 12438f861fbcSMatthew G. Knepley ierr = PetscArrayzero(elem_type, sizeof(elem_type));CHKERRQ(ierr); 12448f861fbcSMatthew G. Knepley PetscStackCallStandard(ex_get_elem_type,(exoid, cs_id[cs], elem_type)); 12458f861fbcSMatthew G. Knepley ierr = ExodusGetCellType_Private(elem_type, &ct);CHKERRQ(ierr); 12468f861fbcSMatthew G. Knepley dim = PetscMax(dim, DMPolytopeTypeGetDim(ct)); 1247e8f6893fSMatthew 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)); 12488f861fbcSMatthew G. Knepley switch (ct) { 12498f861fbcSMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 1250e8f6893fSMatthew G. Knepley cs_order[cs] = cs; 1251e8f6893fSMatthew G. Knepley numHybridCells += num_cell_in_set; 1252e8f6893fSMatthew G. Knepley ++num_hybrid; 1253e8f6893fSMatthew G. Knepley break; 1254e8f6893fSMatthew G. Knepley default: 1255e8f6893fSMatthew G. Knepley for (c = cs; c > cs-num_hybrid; --c) cs_order[c] = cs_order[c-1]; 1256e8f6893fSMatthew G. Knepley cs_order[cs-num_hybrid] = cs; 1257e8f6893fSMatthew G. Knepley } 1258e8f6893fSMatthew G. Knepley } 1259552f7358SJed Brown /* First set sizes */ 1260e8f6893fSMatthew G. Knepley for (ncs = 0, c = 0; ncs < num_cs; ++ncs) { 12618f861fbcSMatthew G. Knepley DMPolytopeType ct; 12628f861fbcSMatthew G. Knepley char elem_type[PETSC_MAX_PATH_LEN]; 1263e8f6893fSMatthew G. Knepley const PetscInt cs = cs_order[ncs]; 12648f861fbcSMatthew G. Knepley 12658f861fbcSMatthew G. Knepley ierr = PetscArrayzero(elem_type, sizeof(elem_type));CHKERRQ(ierr); 12668f861fbcSMatthew G. Knepley PetscStackCallStandard(ex_get_elem_type,(exoid, cs_id[cs], elem_type)); 12678f861fbcSMatthew G. Knepley ierr = ExodusGetCellType_Private(elem_type, &ct);CHKERRQ(ierr); 12686de834b4SMatthew 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)); 1269552f7358SJed Brown for (c_loc = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { 1270552f7358SJed Brown ierr = DMPlexSetConeSize(*dm, c, num_vertex_per_cell);CHKERRQ(ierr); 1271412e9a14SMatthew G. Knepley ierr = DMPlexSetCellType(*dm, c, ct);CHKERRQ(ierr); 1272552f7358SJed Brown } 1273552f7358SJed Brown } 1274412e9a14SMatthew G. Knepley for (v = numCells; v < numCells+numVertices; ++v) {ierr = DMPlexSetCellType(*dm, v, DM_POLYTOPE_POINT);CHKERRQ(ierr);} 1275552f7358SJed Brown ierr = DMSetUp(*dm);CHKERRQ(ierr); 1276e8f6893fSMatthew G. Knepley for (ncs = 0, c = 0; ncs < num_cs; ++ncs) { 1277e8f6893fSMatthew G. Knepley const PetscInt cs = cs_order[ncs]; 12786de834b4SMatthew 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)); 1279dcca6d9dSJed Brown ierr = PetscMalloc2(num_vertex_per_cell*num_cell_in_set,&cs_connect,num_vertex_per_cell,&cone);CHKERRQ(ierr); 12806de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_conn,(exoid, EX_ELEM_BLOCK, cs_id[cs], cs_connect,NULL,NULL)); 1281eaf898f9SPatrick Sanan /* EXO uses Fortran-based indexing, DMPlex uses C-style and numbers cell first then vertices. */ 1282552f7358SJed Brown for (c_loc = 0, v = 0; c_loc < num_cell_in_set; ++c_loc, ++c) { 1283636e64ffSStefano Zampini DMPolytopeType ct; 1284636e64ffSStefano Zampini 1285552f7358SJed Brown for (v_loc = 0; v_loc < num_vertex_per_cell; ++v_loc, ++v) { 1286552f7358SJed Brown cone[v_loc] = cs_connect[v]+numCells-1; 1287552f7358SJed Brown } 1288636e64ffSStefano Zampini ierr = DMPlexGetCellType(*dm, c, &ct);CHKERRQ(ierr); 1289636e64ffSStefano Zampini ierr = DMPlexInvertCell(ct, cone);CHKERRQ(ierr); 1290552f7358SJed Brown ierr = DMPlexSetCone(*dm, c, cone);CHKERRQ(ierr); 1291c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Cell Sets", c, cs_id[cs]);CHKERRQ(ierr); 1292552f7358SJed Brown } 1293552f7358SJed Brown ierr = PetscFree2(cs_connect,cone);CHKERRQ(ierr); 1294552f7358SJed Brown } 1295e8f6893fSMatthew G. Knepley ierr = PetscFree2(cs_id, cs_order);CHKERRQ(ierr); 1296552f7358SJed Brown } 12978f861fbcSMatthew G. Knepley { 12988f861fbcSMatthew G. Knepley PetscInt ints[] = {dim, dimEmbed}; 12998f861fbcSMatthew G. Knepley 13008f861fbcSMatthew G. Knepley ierr = MPI_Bcast(ints, 2, MPIU_INT, 0, comm);CHKERRQ(ierr); 13018f861fbcSMatthew G. Knepley ierr = DMSetDimension(*dm, ints[0]);CHKERRQ(ierr); 13028f861fbcSMatthew G. Knepley ierr = DMSetCoordinateDim(*dm, ints[1]);CHKERRQ(ierr); 13038f861fbcSMatthew G. Knepley dim = ints[0]; 13048f861fbcSMatthew G. Knepley dimEmbed = ints[1]; 13058f861fbcSMatthew G. Knepley } 1306552f7358SJed Brown ierr = DMPlexSymmetrize(*dm);CHKERRQ(ierr); 1307552f7358SJed Brown ierr = DMPlexStratify(*dm);CHKERRQ(ierr); 1308552f7358SJed Brown if (interpolate) { 13095fd9971aSMatthew G. Knepley DM idm; 1310552f7358SJed Brown 13119f074e33SMatthew G Knepley ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); 1312552f7358SJed Brown ierr = DMDestroy(dm);CHKERRQ(ierr); 1313552f7358SJed Brown *dm = idm; 1314552f7358SJed Brown } 1315552f7358SJed Brown 1316552f7358SJed Brown /* Create vertex set label */ 1317552f7358SJed Brown if (!rank && (num_vs > 0)) { 1318552f7358SJed Brown int vs, v; 1319552f7358SJed Brown /* Read from ex_get_node_set_ids() */ 1320552f7358SJed Brown int *vs_id; 1321552f7358SJed Brown /* Read from ex_get_node_set_param() */ 1322f958083aSBlaise Bourdin int num_vertex_in_set; 1323552f7358SJed Brown /* Read from ex_get_node_set() */ 1324552f7358SJed Brown int *vs_vertex_list; 1325552f7358SJed Brown 1326552f7358SJed Brown /* Get vertex set ids */ 1327785e854fSJed Brown ierr = PetscMalloc1(num_vs, &vs_id);CHKERRQ(ierr); 13286de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_NODE_SET, vs_id)); 1329552f7358SJed Brown for (vs = 0; vs < num_vs; ++vs) { 13306de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_set_param,(exoid, EX_NODE_SET, vs_id[vs], &num_vertex_in_set, NULL)); 1331785e854fSJed Brown ierr = PetscMalloc1(num_vertex_in_set, &vs_vertex_list);CHKERRQ(ierr); 13326de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_set,(exoid, EX_NODE_SET, vs_id[vs], vs_vertex_list, NULL)); 1333552f7358SJed Brown for (v = 0; v < num_vertex_in_set; ++v) { 1334c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Vertex Sets", vs_vertex_list[v]+numCells-1, vs_id[vs]);CHKERRQ(ierr); 1335552f7358SJed Brown } 1336552f7358SJed Brown ierr = PetscFree(vs_vertex_list);CHKERRQ(ierr); 1337552f7358SJed Brown } 1338552f7358SJed Brown ierr = PetscFree(vs_id);CHKERRQ(ierr); 1339552f7358SJed Brown } 1340552f7358SJed Brown /* Read coordinates */ 134169d8a9ceSMatthew G. Knepley ierr = DMGetCoordinateSection(*dm, &coordSection);CHKERRQ(ierr); 1342552f7358SJed Brown ierr = PetscSectionSetNumFields(coordSection, 1);CHKERRQ(ierr); 13438f861fbcSMatthew G. Knepley ierr = PetscSectionSetFieldComponents(coordSection, 0, dimEmbed);CHKERRQ(ierr); 1344552f7358SJed Brown ierr = PetscSectionSetChart(coordSection, numCells, numCells + numVertices);CHKERRQ(ierr); 1345552f7358SJed Brown for (v = numCells; v < numCells+numVertices; ++v) { 13468f861fbcSMatthew G. Knepley ierr = PetscSectionSetDof(coordSection, v, dimEmbed);CHKERRQ(ierr); 13478f861fbcSMatthew G. Knepley ierr = PetscSectionSetFieldDof(coordSection, v, 0, dimEmbed);CHKERRQ(ierr); 1348552f7358SJed Brown } 1349552f7358SJed Brown ierr = PetscSectionSetUp(coordSection);CHKERRQ(ierr); 1350552f7358SJed Brown ierr = PetscSectionGetStorageSize(coordSection, &coordSize);CHKERRQ(ierr); 13518b9ced59SLisandro Dalcin ierr = VecCreate(PETSC_COMM_SELF, &coordinates);CHKERRQ(ierr); 1352552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) coordinates, "coordinates");CHKERRQ(ierr); 1353552f7358SJed Brown ierr = VecSetSizes(coordinates, coordSize, PETSC_DETERMINE);CHKERRQ(ierr); 13548f861fbcSMatthew G. Knepley ierr = VecSetBlockSize(coordinates, dimEmbed);CHKERRQ(ierr); 13552eb5907fSJed Brown ierr = VecSetType(coordinates,VECSTANDARD);CHKERRQ(ierr); 1356552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 13570aba08f6SKarl Rupp if (!rank) { 1358e84f7031SBlaise Bourdin PetscReal *x, *y, *z; 1359552f7358SJed Brown 1360dcca6d9dSJed Brown ierr = PetscMalloc3(numVertices,&x,numVertices,&y,numVertices,&z);CHKERRQ(ierr); 13616de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_coord,(exoid, x, y, z)); 13628f861fbcSMatthew G. Knepley if (dimEmbed > 0) { 13638f861fbcSMatthew G. Knepley for (v = 0; v < numVertices; ++v) coords[v*dimEmbed+0] = x[v]; 13640d644c17SKarl Rupp } 13658f861fbcSMatthew G. Knepley if (dimEmbed > 1) { 13668f861fbcSMatthew G. Knepley for (v = 0; v < numVertices; ++v) coords[v*dimEmbed+1] = y[v]; 13670d644c17SKarl Rupp } 13688f861fbcSMatthew G. Knepley if (dimEmbed > 2) { 13698f861fbcSMatthew G. Knepley for (v = 0; v < numVertices; ++v) coords[v*dimEmbed+2] = z[v]; 13700d644c17SKarl Rupp } 1371552f7358SJed Brown ierr = PetscFree3(x,y,z);CHKERRQ(ierr); 1372552f7358SJed Brown } 1373552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 1374552f7358SJed Brown ierr = DMSetCoordinatesLocal(*dm, coordinates);CHKERRQ(ierr); 1375552f7358SJed Brown ierr = VecDestroy(&coordinates);CHKERRQ(ierr); 1376552f7358SJed Brown 1377552f7358SJed Brown /* Create side set label */ 1378552f7358SJed Brown if (!rank && interpolate && (num_fs > 0)) { 1379552f7358SJed Brown int fs, f, voff; 1380552f7358SJed Brown /* Read from ex_get_side_set_ids() */ 1381552f7358SJed Brown int *fs_id; 1382552f7358SJed Brown /* Read from ex_get_side_set_param() */ 1383f958083aSBlaise Bourdin int num_side_in_set; 1384552f7358SJed Brown /* Read from ex_get_side_set_node_list() */ 1385552f7358SJed Brown int *fs_vertex_count_list, *fs_vertex_list; 1386ef073283Smichael_afanasiev /* Read side set labels */ 1387ef073283Smichael_afanasiev char fs_name[MAX_STR_LENGTH+1]; 1388552f7358SJed Brown 1389552f7358SJed Brown /* Get side set ids */ 1390785e854fSJed Brown ierr = PetscMalloc1(num_fs, &fs_id);CHKERRQ(ierr); 13916de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_ids,(exoid, EX_SIDE_SET, fs_id)); 1392552f7358SJed Brown for (fs = 0; fs < num_fs; ++fs) { 13936de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_set_param,(exoid, EX_SIDE_SET, fs_id[fs], &num_side_in_set, NULL)); 1394dcca6d9dSJed Brown ierr = PetscMalloc2(num_side_in_set,&fs_vertex_count_list,num_side_in_set*4,&fs_vertex_list);CHKERRQ(ierr); 13956de834b4SMatthew G. Knepley PetscStackCallStandard(ex_get_side_set_node_list,(exoid, fs_id[fs], fs_vertex_count_list, fs_vertex_list)); 1396ef073283Smichael_afanasiev /* Get the specific name associated with this side set ID. */ 1397ef073283Smichael_afanasiev int fs_name_err = ex_get_name(exoid, EX_SIDE_SET, fs_id[fs], fs_name); 1398552f7358SJed Brown for (f = 0, voff = 0; f < num_side_in_set; ++f) { 13990298fd71SBarry Smith const PetscInt *faces = NULL; 1400552f7358SJed Brown PetscInt faceSize = fs_vertex_count_list[f], numFaces; 1401552f7358SJed Brown PetscInt faceVertices[4], v; 1402552f7358SJed Brown 1403552f7358SJed Brown if (faceSize > 4) SETERRQ1(comm, PETSC_ERR_ARG_WRONG, "ExodusII side cannot have %d > 4 vertices", faceSize); 1404552f7358SJed Brown for (v = 0; v < faceSize; ++v, ++voff) { 1405552f7358SJed Brown faceVertices[v] = fs_vertex_list[voff]+numCells-1; 1406552f7358SJed Brown } 1407552f7358SJed Brown ierr = DMPlexGetFullJoin(*dm, faceSize, faceVertices, &numFaces, &faces);CHKERRQ(ierr); 1408552f7358SJed Brown if (numFaces != 1) SETERRQ3(comm, PETSC_ERR_ARG_WRONG, "Invalid ExodusII side %d in set %d maps to %d faces", f, fs, numFaces); 1409c58f1c22SToby Isaac ierr = DMSetLabelValue(*dm, "Face Sets", faces[0], fs_id[fs]);CHKERRQ(ierr); 1410ef073283Smichael_afanasiev /* Only add the label if one has been detected for this side set. */ 1411ef073283Smichael_afanasiev if (!fs_name_err) { 1412ef073283Smichael_afanasiev ierr = DMSetLabelValue(*dm, fs_name, faces[0], fs_id[fs]);CHKERRQ(ierr); 1413ef073283Smichael_afanasiev } 1414552f7358SJed Brown ierr = DMPlexRestoreJoin(*dm, faceSize, faceVertices, &numFaces, &faces);CHKERRQ(ierr); 1415552f7358SJed Brown } 1416552f7358SJed Brown ierr = PetscFree2(fs_vertex_count_list,fs_vertex_list);CHKERRQ(ierr); 1417552f7358SJed Brown } 1418552f7358SJed Brown ierr = PetscFree(fs_id);CHKERRQ(ierr); 1419552f7358SJed Brown } 1420*b458e8f1SJose E. Roman PetscFunctionReturn(0); 1421552f7358SJed Brown #else 1422552f7358SJed Brown SETERRQ(comm, PETSC_ERR_SUP, "This method requires ExodusII support. Reconfigure using --download-exodusii"); 1423552f7358SJed Brown #endif 1424552f7358SJed Brown } 1425