Transfer module

The maia.transfer contains functions that exchange data between the partitioned and distributed meshes.

Fields transfer

High level APIs allow to exchange data at CGNS Tree or Zone level. All the provided functions take similar parameters: a distributed tree (resp. zone), the corresponding partitioned tree (resp. list of zones), the MPI communicator and optionally a filtering parameter.

The following kind of data are supported: FlowSolution_t, DiscreteData_t, ZoneSubRegion_t and BCDataSet_t.

When transferring from distributed meshes to partitioned meshes, fields are supposed to be known on the source mesh across all the ranks (according to disttree definition). Geometric patches (such as ZoneSubRegion or BCDataSet) must exists on the relevant partitions, meaning that only fields are transfered.

When transferring from partitioned meshes to distributed meshes, geometric patches may or may not exist on the distributed zone: they will be created if needed. This allows to transfer fields that have been created on the partitioned meshes. It is however assumed that global data (e.g. FlowSolution) are defined on every partition.

Tree level

All the functions of this section operate inplace and require the following parameters:

  • dist_tree (CGNSTree) – Distributed CGNS Tree

  • part_tree (CGNSTree) – Corresponding partitioned CGNS Tree

  • comm (MPIComm) – MPI communicator

dist_tree_to_part_tree_all(dist_tree, part_tree, comm)

Transfer all the data fields from a distributed tree to the corresponding partitioned tree.

Example

from mpi4py import MPI
import os
import maia
import maia.pytree as PT
from   maia.utils.test_utils import sample_mesh_dir

filename = os.path.join(sample_mesh_dir, 'quarter_crown_square_8.yaml')
dist_tree = maia.io.file_to_dist_tree(filename, MPI.COMM_WORLD)
part_tree = maia.factory.partition_dist_tree(dist_tree, MPI.COMM_WORLD)
maia.transfer.dist_tree_to_part_tree_all(dist_tree, part_tree, MPI.COMM_WORLD)

zone = PT.get_all_Zone_t(part_tree)[0]
assert PT.get_node_from_path(zone, 'FlowSolution/DataX') is not None
assert PT.get_node_from_path(zone, 'ZoneSubRegion/Tata') is not None
assert PT.get_node_from_path(zone, 'ZoneBC/Bnd2/BCDataSet/DirichletData/TutuZ') is not None
part_tree_to_dist_tree_all(dist_tree, part_tree, comm)

Transfer all the data fields from a partitioned tree to the corresponding distributed tree.

In addition, the next two methods expect the parameter labels (list of str) which allow to pick one or more kind of data to transfer from the supported labels.

dist_tree_to_part_tree_only_labels(dist_tree, part_tree, labels, comm)

Transfer all the data fields of the specified labels from a distributed tree to the corresponding partitioned tree.

Example

from mpi4py import MPI
import os
import maia
import maia.pytree as PT
from   maia.utils.test_utils import sample_mesh_dir

comm = MPI.COMM_WORLD
filename = os.path.join(sample_mesh_dir, 'quarter_crown_square_8.yaml')

dist_tree = maia.io.file_to_dist_tree(filename, comm)
part_tree = maia.factory.partition_dist_tree(dist_tree, comm)
maia.transfer.dist_tree_to_part_tree_only_labels(dist_tree, part_tree, ['FlowSolution_t', 'ZoneSubRegion_t'], comm)

zone = PT.get_all_Zone_t(part_tree)[0]
assert PT.get_node_from_path(zone, 'FlowSolution/DataX') is not None
assert PT.get_node_from_path(zone, 'ZoneSubRegion/Tata') is not None
assert PT.get_node_from_path(zone, 'ZoneBC/Bnd2/BCDataSet/DirichletData/TutuZ') is None

maia.transfer.dist_tree_to_part_tree_only_labels(dist_tree, part_tree, ['BCDataSet_t'], comm)
assert PT.get_node_from_path(zone, 'ZoneBC/Bnd2/BCDataSet/DirichletData/TutuZ') is not None
part_tree_to_dist_tree_only_labels(dist_tree, part_tree, labels, comm)

Transfer all the data fields of the specified labels from a partitioned tree to the corresponding distributed tree.

Zone level

All the functions of this section operate inplace and require the following parameters:

  • dist_zone (CGNSTree) – Distributed CGNS Zone

  • part_zones (list of CGNSTree) – Corresponding partitioned CGNS Zones

  • comm (MPIComm) – MPI communicator

In addition, filtering is possible with the use of the include_dict or exclude_dict dictionaries. These dictionaries map each supported label to a list of cgns paths to include (or exclude). Paths starts from the Zone_t node and ends at the targeted DataArray_t node. Wildcard * are allowed in paths : for example, considering the following tree structure,

Zone (Zone_t)
├── FirstSolution (FlowSolution_t)
│   ├── Pressure (DataArray_t)
│   ├── MomentumX (DataArray_t)
│   └── MomentumY (DataArray_t)
├── SecondSolution (FlowSolution_t)
│   ├── Pressure (DataArray_t)
│   ├── MomentumX (DataArray_t)
│   └── MomentumY (DataArray_t)
└── SpecialSolution (FlowSolution_t)
    ├── Density (DataArray_t)
    └── MomentumZ (DataArray_t)
"FirstSolution/Momentum*" maps to ["FirstSolution/MomentumX", "FirstSolution/MomentumY"],
"*/Pressure maps to ["FirstSolution/Pressure", "SecondSolution/Pressure"], and
"S*/M*" maps to ["SecondSolution/MomentumX", "SecondSolution/MomentumY", "SpecialSolution/MomentumZ"].

For convenience, we also provide the magic path ['*'] meaning “everything related to this label”.

Lastly, we use the following rules to manage missing label keys in dictionaries:

  • For _only functions, we do not transfer any field related to the missing labels;

  • For _all functions, we do transfer all the fields related to the missing labels.

dist_zone_to_part_zones_only(dist_zone, part_zones, comm, include_dict)

Transfer the data fields specified in include_dict from a distributed zone to the corresponding partitioned zones.

Example

from mpi4py import MPI
import os
import maia
import maia.pytree as PT
from   maia.utils.test_utils import sample_mesh_dir

comm = MPI.COMM_WORLD
filename = os.path.join(sample_mesh_dir, 'quarter_crown_square_8.yaml')

dist_tree = maia.io.file_to_dist_tree(filename, comm)
dist_zone = PT.get_all_Zone_t(dist_tree)[0]
part_tree = maia.factory.partition_dist_tree(dist_tree, comm)
part_zones = PT.get_all_Zone_t(part_tree)

include_dict = {'FlowSolution_t' : ['FlowSolution/DataX', 'FlowSolution/DataZ'],
                'BCDataSet_t'    : ['*']}
maia.transfer.dist_zone_to_part_zones_only(dist_zone, part_zones, comm, include_dict)

for zone in part_zones:
  assert PT.get_node_from_path(zone, 'FlowSolution/DataX') is not None
  assert PT.get_node_from_path(zone, 'ZoneSubRegion/Tata') is     None
  assert PT.get_node_from_path(zone, 'ZoneBC/Bnd2/BCDataSet/DirichletData/TutuZ') is not None
part_zones_to_dist_zone_only(dist_zone, part_zones, comm, include_dict)

Transfer the data fields specified in include_dict from the partitioned zones to the corresponding distributed zone.

dist_zone_to_part_zones_all(dist_zone, part_zones, comm, exclude_dict={})

Transfer all the data fields, excepted those specified in exclude_dict, from a distributed zone to the corresponding partitioned zones.

Example

from mpi4py import MPI
import os
import maia
import maia.pytree as PT
from   maia.utils.test_utils import sample_mesh_dir

comm = MPI.COMM_WORLD
filename = os.path.join(sample_mesh_dir, 'quarter_crown_square_8.yaml')

dist_tree = maia.io.file_to_dist_tree(filename, comm)
dist_zone = PT.get_all_Zone_t(dist_tree)[0]
part_tree = maia.factory.partition_dist_tree(dist_tree, comm)
part_zones = PT.get_all_Zone_t(part_tree)

exclude_dict = {'FlowSolution_t' : ['FlowSolution/DataX', 'FlowSolution/DataZ'],
                'BCDataSet_t'    : ['*']}
maia.transfer.dist_zone_to_part_zones_all(dist_zone, part_zones, comm, exclude_dict)

for zone in part_zones:
  assert PT.get_node_from_path(zone, 'FlowSolution/DataX') is     None
  assert PT.get_node_from_path(zone, 'FlowSolution/DataY') is not None
  assert PT.get_node_from_path(zone, 'ZoneSubRegion/Tata') is not None
  assert PT.get_node_from_path(zone, 'ZoneBC/Bnd2/BCDataSet/DirichletData/TutuZ') is None
part_zones_to_dist_zone_all(dist_zone, part_zones, comm, exclude_dict={})

Transfer all the data fields, excepted those specified in exclude_dict, from the partitioned zone to the corresponding distributed zone.