Skip to content
Ondrej Meca edited this page Apr 22, 2021 · 4 revisions

Loading an input mesh database

Loading of an input mesh is based on the algorithm described here. The algorithm can reconstruct an unstructured mesh databases in the distributed memory of supercomputers that allows for efficient parallel loading and processing of databases even if they were not designed for parallel reading. The algorithm is divided into two part: (a) parsing of an input database that must be tailored for a particular database format and (b) reconstruction process that builds a mesh from arbitrary scattered data across processes.

The reconstructed mesh has several properties that are assured by the algorithm. Let the figure below describe a mesh with 2 bodies (2 non-connected parts), 3 regions of elements (red, blue, green), 1 region of boundary elements (elements 11, 24, 68, 40, 92, 15), and 1 region of nodes (blue nodes). Note that IDs of nodes and elements are irrelevant as same as their particular order within the database.

A possible output of the algorithm is depicted in the following picture. The mesh is decomposed into 3 parts (to 3 MPI processes). Nodes and elements are re-indexed to offsets (in order to allow simple querying). All boundary elements are on the same processes as their parents (e.g., element with ID=11 is stored on the process as element with ID=9). In addition, each process has information about the total number of nodes and elements of a particular type and their offset respect to other processes (see the listing at the end of this page to get more insight).

# MPI 0

# ------------------------------------- #
# nodes ordered according to:
#  1. the holder (the first MPI process that hold a given node)
#  2. node IDs
  IDS = { 1, 2, 3, 11, 18, 24, 36, 40, 53, 67 }
  COORDINATES = { (x, y, z), (x, y, z), ...}

  # occurence on MPI processes
  RANKS = { (0), (0, 1), (0), (0), (0, 1), (0), (0), (0), (0, 1), (0) }

  # the number of nodes held by the lower MPI ranks
  nhalo = 0

  # the offset of the first node that a given MPI process holds
  offset = 0

  # the number of nodes held by this process (and total number)
  size = 10
  totalsize = 31

  # total offset (order) of a node among nodes of all other processes
  POSITION = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }

# ------------------------------------- #
# elements
  PROC_NODES = { (6, 2, 0, 7), (9, 4, 8), (2, 9, 8, 0), ...}
  BODY = { 0, 0, 0, 0, 0, 0 }
  REGIONS = { (0), (1), (0), (1), (0), (0) }

  # offset of the first element among elements of all other processes
  offset = 0
  size = 6
  totalsize = 19

  # offset of a particular element type
  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  # total number of elements with a particular type
  COUNTER(triangle3) = 8
  COUNTER(square4) = 11

  # face neighbors in the predefined order (in offsets; -1 if there is no neighbor)
  NEIGHS = { (-1, 4, 2, -1), (2, 3, 9), (0, 5, 1, -1), ... }

# ------------------------------------- #
# regions of elements

## RED
  ELEMENTS = { 0, 2, 4, 5 }
  NODES = { 0, 1, 2, 3, 5, 6, 7, 8, 9 }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  COUNTER(triangle3) = 0
  COUNTER(square4) = 4

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 9
  totalsize = 9

## BLUE
  ELEMENTS = { 1, 3 }
  NODES = { 1, 4, 8, 9 }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  COUNTER(triangle3) = 8
  COUNTER(square4) = 0

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 4
  totalsize = 9

## GREEN
  ELEMENTS = {  }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  COUNTER(triangle3) = 0
  COUNTER(square4) = 7

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 0
  totalsize = 16

# ------------------------------------- #
# regions of boundary elements

## UNKNOW BOUNDARY REGION
  PROC_NODES = { }
  NODES = { 1, 8 } # even there is no boundary element, these nodes are held by this process
  PARENTS = { }

  OFFSET(line2) = 0
  COUNTER(line2) = 6

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 2
  totalsize = 7

  # position of nodes held by this process withing the region
  POSITION = { 0, 1 }

# ------------------------------------- #
# regions of nodes

## UNKNOW NODE REGION
  NODES = {  }
  POSITION  = { }

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 0
  totalsize = 10
# MPI 1

# ------------------------------------- #
# nodes ordered according to:
#  1. the holder (the first MPI process that hold a given node)
#  2. node IDs
  IDS = { 2, 18, 53, 5, 6, 9, 34, 41 }
  COORDINATES = { (x, y, z), (x, y, z), ...}

  # occurence on MPI processes
  RANKS = { (0, 1), (0, 1), (0, 1), (1), (1), (1), (1), (1) }

  # the number of nodes held by the lower MPI ranks
  nhalo = 3

  # the offset of the first node that a given MPI process holds
  offset = 10

  # the number of nodes held by this process (and total number)
  size = 8
  totalsize = 31

  # total offset (order) of a node among nodes of all other processes
  POSITION = { 1, 4, 8, 10, 11, 12, 13, 14 }

# ------------------------------------- #
# elements
  PROC_NODES = { (7, 4, 5), (1, 7, 5), (1, 5, 2), ...}
  BODY = { 0, 0, 0, 0, 0, 0 }
  REGIONS = { (1), (1), (1), (1), (1), (1) }

  # offset of the first element among elements of all other processes
  offset = 6
  size = 6
  totalsize = 19

  # offset of a particular element type
  OFFSET(triangle3) = 2
  OFFSET(square4) = 0

  # total number of elements with a particular type
  COUNTER(triangle3) = 8
  COUNTER(square4) = 11

  # face neighbors in the predefined order (in offsets; -1 if there is no neighbor)
  NEIGHS = { (-1, -1, 7), (9, 6, 8), (7, -1, 1), ... }

# ------------------------------------- #
# regions of elements

## RED
  ELEMENTS = {  }
  NODES = {  }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  COUNTER(triangle3) = 0
  COUNTER(square4) = 4

  # node statistics with this region
  nhalo = 0
  offset = 9
  size = 0
  totalsize = 9

## BLUE
  ELEMENTS = { 0, 1, 2, 3, 4, 5 }
  NODES = { 0, 1, 2, 3, 4, 5, 6, 7 }

  OFFSET(triangle3) = 2
  OFFSET(square4) = 0

  COUNTER(triangle3) = 8
  COUNTER(square4) = 0

  # node statistics with this region
  nhalo = 3
  offset = 4
  size = 5
  totalsize = 9

## GREEN
  ELEMENTS = {  }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  COUNTER(triangle3) = 0
  COUNTER(square4) = 7

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 0
  totalsize = 16

# ------------------------------------- #
# regions of boundary elements

## UNKNOW BOUNDARY REGION
  PROC_NODES = { (5, 2), (0, 6), (4, 5), ..}
  NODES = { 0, 2, 3, 4, 5, 6, 7 }
  PARENTS = { 2, 4, 0, 5, 0, 5 }

  OFFSET(line2) = 0
  COUNTER(line2) = 6

  # node statistics with this region
  nhalo = 2
  offset = 2
  size = 5
  totalsize = 7

  # position of nodes held by this process withing the region
  POSITION = { 0, 1, 2, 3, 4, 5, 6 }

# ------------------------------------- #
# regions of nodes

## UNKNOW NODE REGION
  NODES = {  }
  POSITION  = { }

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 0
  totalsize = 10
# MPI 2

# ------------------------------------- #
# nodes ordered according to:
#  1. the holder (the first MPI process that hold a given node)
#  2. node IDs
  IDS = { 4, 10, 14, 16, 21, 30, 25, 28, 29, 33, 35, 51, 52, 54, 55, 76 }
  COORDINATES = { (x, y, z), (x, y, z), ...}

  # occurence on MPI processes
  RANKS = { (2), (2), (2), ... }

  # the number of nodes held by the lower MPI ranks
  nhalo = 0

  # the offset of the first node that a given MPI process holds
  offset = 15

  # the number of nodes held by this process (and total number)
  size = 16
  totalsize = 31

  # total offset (order) of a node among nodes of all other processes
  POSITION = { 15, 16, 17, ..., 30 }

# ------------------------------------- #
# elements
  PROC_NODES = { (5, 12, 13, 14), 1, 5, 14, 11), (4, 7, 12, 5), ...}
  BODY = { 1, 1, 1, 1, 1, 1, 1 }
  REGIONS = { (2), (2), (2), (2), (2), (2), (2) }

  # offset of the first element among elements of all other processes
  offset = 12
  size = 7
  totalsize = 19

  # offset of a particular element type
  OFFSET(triangle3) = 8
  OFFSET(square4) = 4

  # total number of elements with a particular type
  COUNTER(triangle3) = 8
  COUNTER(square4) = 11

  # face neighbors in the predefined order (in offsets; -1 if there is no neighbor)
  NEIGHS = { (16, 17, -1, -1), (-1, -1, 15, -1), (-1, 19, -1, 15), ... }

# ------------------------------------- #
# regions of elements

## RED
  ELEMENTS = {  }
  NODES = { }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 4

  COUNTER(triangle3) = 0
  COUNTER(square4) = 4

  # node statistics with this region
  nhalo = 0
  offset = 9
  size = 0
  totalsize = 9

## BLUE
  ELEMENTS = {  }
  NODES = {  }

  OFFSET(triangle3) = 8
  OFFSET(square4) = 0

  COUNTER(triangle3) = 8
  COUNTER(square4) = 0

  # node statistics with this region
  nhalo = 0
  offset = 9
  size = 0
  totalsize = 9

## GREEN
  ELEMENTS = { 0, 1, 2, 3, 4, 5, 6 }

  OFFSET(triangle3) = 0
  OFFSET(square4) = 0

  COUNTER(triangle3) = 0
  COUNTER(square4) = 7

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 16
  totalsize = 16

# ------------------------------------- #
# regions of boundary elements

## UNKNOW BOUNDARY REGION
  PROC_NODES = { }
  NODES = { }
  PARENTS = { }

  OFFSET(line2) = 6
  COUNTER(line2) = 6

  # node statistics with this region
  nhalo = 0
  offset = 7
  size = 0
  totalsize = 7

  # position of nodes held by this process withing the region
  POSITION = { }

# ------------------------------------- #
# regions of nodes

## UNKNOW NODE REGION
  NODES = { 0, 2, 6, 7, 9, 11, 12, 13, 14, 15 }
  POSITION  = { 0, 1, 2, ..., 9}

  # node statistics with this region
  nhalo = 0
  offset = 0
  size = 16
  totalsize = 10
Clone this wiki locally