What Is MED?
The purpose of the MED
module is to provide a standard for storing and recovering computer
data associated to numerical meshes and fields, and to facilitate the
exchange between codes and solvers.
The persistent data storage is based upon HDF format (like CGNS, a standard developed by Boeing and NASA in the area of Computational Fluid Dynamic).
MED also provides structures to hold data on meshes and fields. These structures are exchanged between solvers, hide the communication level (CORBA or MPI), and offer persistence (read/write in .med files).
The main benefit of a common exchange format is reduced complexity of code coupling. It also allows sharing such high level functionalities as computation of nodal connectivity of sub-elements (faces and edges), arithmetic operations on fields, entity location functionalities, and interpolation toolkit.
MED Data Model
The MED data model defines in a logical way the data structures exchanged by codes. The modeled data concern meshes (structured and unstructured) and the resulting fields that can be defined on nodes, elements or Gauss points of meshes. MED supports eight element shapes: point, line, triangle, quadrangle, tetrahedron, pyramid, hexahedron, polygon and polyhedron. Each element may have a different number of nodes, depending on whether linear or quadratic interpolation is used. Since the nodes inside each element could be ordered in multiple ways, MED defines numbering conventions, which are detailed in the MED documentation.
Different MED APIs
There are three different MED APIs, also detailed in MED documentation.
The first level (called “Med File”) is a C and Fortran API that implements mesh and field persistence (read/write). The produced files are based on hdf format, and have the “.med” extension.
The second-level library is called “Med Memory”, which is a C++ and python API that allows creating mesh and field objects in memory. Mesh creation can be done from scratch using set functions, or by loading a file with a driver. Fields are also created using drivers, or by initialization with a user-defined analytic function. The following file formats are supported: .med, .sauv (persistent format of the CASTEM code), .vtk (only in write mode), and porflow (fluid flow and heat transfer code). Med Memory was developed to allow the exchange of mesh and field objects in memory between solvers. It can also be used as an internal data structure for new solvers. The last purpose was to gather in the same place the existing algorithms and services working with meshes and fields.
Finally there is a third-level API called MED Corba, written to facilitate distributed computation inside SALOME. This API defines CORBA interfaces for the main MED objects (FIELD, SUPPORT, MESH) and proposes methods that allow distant users to access data. It is implemented by CORBA servants that encapsulate C++ Med Memory objects.
In view of the difficult usage of CORBA API, client-side proxy classes called “MEDClient” have been designed to facilitate and optimize interaction of distant MED CORBA objects with local solvers. The Corba API is completely hidden to clients, it inherits the MED memory C++ API, thus facilitating re-use of the existing code that uses C++ API. Data is transferred only on demand, the transfer is optimized: duplication is avoided on server side, and transfer protocol may be switched during the compilation (for example to MPI on a parallel machine), without any modification of the client code. Memory is managed automatically.
How to Bring MED in your code?
The MED memory structures can be used as an internal data model for meshes and fields in new codes. As for the existing solvers with native data models, the integration of MED consists in reading and/or writing MED structures and converting into the native structures. The approach may be the following:
- Choose between MED file and MED memory API: if you only need the persistence services, use MED file API, if you plan to use other services (supervision, exchange of data), consider the MED memory API.
- Analyze the data you want to exchange: element shapes, mode (read/write), then define an interface and implement it. If the internal data model is compatible with MED (the same numbering conventions), the implementation essentially consists in copying arrays, otherwise it requires conversion.