3.2.1. Meshes
[3.2. Reading Geometry]

This section is intended to be a quick overview of reading and writing meshes. For more detailed function descriptions see section 4.8. The mesh geometry in XMDF files is relatively straight-forward. The mesh contains nodes with X, Y, and Z coordinates. The mesh also contains information about how the nodes are connected to form elements. Each element has an element type and a list of nodes belonging to the element. The nodes are referenced by their location in the node dataset. Note: The node locations used in this context are always one-based (i.e., start at 1 rather than 0). The types of elements and number of nodes associated with each type are discussed in 4.8.2. The following steps are used to read a mesh:

Open the file and the mesh group using the functions xfOpenFile and xfOpenGroup.

Read the number of nodes, number of elements, and the maximum number of nodes in an element. These values are retrieved using the functions xfGetNumberOfNodes, xfGetNumberOfElements, and xfGetMaxNodesInElem.

Allocate arrays to store the node locations, element type, and connectivity arrays.

Read the node locations, element types, and connectivity arrays. These arrays are read using the functions xfReadXNodeLocations, xfReadYNodeLocations, xfReadZNodeLocations, xfReadElemTypes, and xfReadElemNodeIds.

Close the file and mesh group using xfCloseFile and xfCloseGroup.

Convert the arrays to native model data definitions if necessary.

C++ code
The following sample C++ code illustrates how to read a mesh using XMDF:

int fg_nElems;
int fg_nNodes;
int fg_nNodesPerElem;
int *fg_ElemTypes;
double *fg_XNodeLocs, *fg_YNodeLocs, *fg_ZNodeLocs;
int *fg_NodesInElem;
 
int xfReadMesh(const char *FileName, const char *PathToMesh) {
  xid    xFileId, xGroupId;
  int    nElemType, nNodeId;
  int    status;
 
  // Open the file and the mesh group
  status = xfOpenFile(FileName, &xFileId, TRUE);
  if (status < 0) {
    return -1;
  }
 
  if (status >= 0) {
    status = xfOpenGroup(xFileId, PathToMesh, &xGroupId);
  }
  if (status < 0) {
    // group was not opened successfully
    xfCloseFile(xFileId);
    return -1;
  }
 
 
  // Get the number of elements, nodes, and Maximum number of nodes per element
  status = xfGetNumberOfElements(xGroupId, &fg_nElems);
  if (status >= 0) {
    status = xfGetNumberOfNodes(xGroupId, &fg_nNodes);
    if (status >= 0) {
      status = xfGetMaxNodesInElem(xGroupId, &fg_nNodesPerElem);
    }
  }
  if (status < 0) {
    return -1;
  }
 
  fg_ElemTypes = new int[fg_nElems];
  if (fg_ElemTypes == NULL) {
    printf("Memory Error");
    return -1;
  }
  status = xfReadElemTypes(xGroupId, fg_nElems, fg_ElemTypes);
  if (status < 0) {
    return -1;
  }
 
  // Nodes in each element
  fg_NodesInElem  = new int[fg_nElems*fg_nNodesPerElem];
  xfReadElemNodeIds(xGroupId, fg_nElems, fg_nNodesPerElem, fg_NodesInElem);
 
  // NodeLocations
  fg_XNodeLocs = new double[fg_nNodes];
  fg_YNodeLocs = new double[fg_nNodes];
  fg_ZNodeLocs = new double[fg_nNodes];
  if (fg_XNodeLocs == NULL || fg_YNodeLocs == NULL || fg_ZNodeLocs == NULL) {
    if (fg_XNodeLocs != NULL) {
      delete fg_XNodeLocs;
      fg_XNodeLocs = NULL;
    }
    if (fg_YNodeLocs != NULL) {
      delete fg_YNodeLocs;
      fg_YNodeLocs = NULL;
    }
    if (fg_ZNodeLocs != NULL) {
      delete fg_ZNodeLocs;
      fg_ZNodeLocs = NULL;
    }
    printf("Memory Error!");
    return -1;
  }
 
  status = xfReadXNodeLocations(xGroupId, fg_nNodes, fg_XNodeLocs);
  if (status >= 0) {
    status = xfReadYNodeLocations(xGroupId, fg_nNodes, fg_YNodeLocs);
    if (status >= 0) {
      status = xfReadZNodeLocations(xGroupId, fg_nNodes, fg_ZNodeLocs);
    }
    else {
      return -1;
    }
  }
  else {
    return -1;
  }
}

FORTRAN
INTEGER   fg_nElems
INTEGER   fg_nNodes
INTEGER   fg_nNodesPerElem
INTEGER, ALLOCATABLE :: fg_ElemTypes
REAL(DOUBLE), ALLOCATABLE :: fg_XNodeLocs(:), fg_YNodeLocs(:), fg_ZNodeLocs(:)
INTEGER, ALLOCATABLE :: fg_NodesInElem(:)
 
SUBROUTINE READ_MESH (Filename, PathToMesh, error)
CHARACTER(LEN=*), INTENT(IN) :: Filename, PathToMesh
INTEGER, INTENT(OUT)       :: error
INTEGER(HID_T)  xFileId, xGroupId
INTEGER         nElemType, nNodeId
 
! Open the file and group
call XF_OPEN_FILE(Filename, XTRUE, xFileId, error)
if (error .LT. 0) then
  return
endif
 
call XF_OPEN_GROUP(xFileId, PathToMesh, xGroupId, error)
if (error .LT. 0) then
  return
endif
 
! Get the number of elements, nodes, and Maximum number of nodes per element
call XF_GET_NUMBER_OF_ELEMENTS (xGroupId, fg_nElems, error)
if (error >= 0) then
  call XF_GET_NUMBER_OF_NODES (xGroupId, fg_nNodes, error)
  if (error >= 0) then
    call XF_GET_MAX_NODES_IN_ELEM (xGroupId, fg_nNodesPerElem, error)
  endif
endif
 
if (error < 0) then
  return
endif
 
  ! Element types
allocate (fg_ElemTypes(fg_nElems))
 
call XF_READ_ELEM_TYPES (xGroupId, fg_nElems, fg_ElemTypes, error)
if (error < 0) then
  return
endif
 
  ! Nodes in each element
allocate (fg_NodesInElem(fg_nElems*fg_nNodesPerElem))
call XF_READ_ELEM_NODE_IDS (xGroupId, fg_nElems, fg_nNodesPerElem, &
                            fg_NodesInElem, error)
 
  ! NodeLocations
allocate (fg_XNodeLocs(fg_nNodes))
allocate (fg_YNodeLocs(fg_nNodes))
allocate (fg_ZNodeLocs(fg_nNodes))
 
call XF_READ_X_NODE_LOCATIONS (xGroupId, fg_nNodes, fg_XNodeLocs, error)
if (status >= 0) then
  call XF_READ_Y_NODE_LOCATIONS (xGroupId, fg_nNodes, fg_YNodeLocs, error)
  if (status >= 0) then
    call XF_READ_Z_NODE_LOCATIONS (xGroupId, fg_nNodes, fg_ZNodeLocs, error)
  endif
endif
 
error = TRUE
return
 
END SUBROUTINE

Generated on Wed Jun 2 11:55:32 2010 for XMDF by  doxygen 1.5.6