Version: 6.3.1

MEDCoupling Arrays

Introduction

This page will try to describe data arrays in MEDCoupling. Presently, in MEDCoupling it exists two types of arrays :

Basics concepts

It will be presented in this section common concept shared by the two classes to DataArrayDouble and DataArrayInt.

  • The first thing is that an array has a name (stored as a C++ string). This name is often ignored in MEDCoupling algorithm when arrays are aggregated (field array, connectivity, coordinates). The reason is that name is stored by the aggregating object. But it can be very usefull for arrays not aggregated in bigger MEDCoupling object for groups ids and families ids for example.
  • The second thing is the data storage. For obvious reason, MEDCoupling DataArray stores data in a contiguous way in memory like std::vector does.
  • The third thing is linked to previous point. Data arrays are able to store vectorized data. It is usefull to store the data of a vectorial field. That's why MEDCoupling arrays uses the concepts of components. To store an array for a vector field on cell with 3 components lying on a mesh having 5 cells. The array will contain 5*3=15 values grouped by 3. The 5 groups containing each 3 elements are called tuples.
    Number of values stored in an array is equal to number of tuples multiplied by number of components.
    Generally speaking, except for vector field arrays, and array for nodes coordinates, the number of components is equal to one.
  • The fourth thing is linked to point 2 and 3 as MEDCoupling is developped in C++ the values of arrays are stored tuples by tuples, that is to say in full interlace mode.
    That is to say, the 15 values in the example in point 3 will be stored like this :
    $ x_0,y_0,z_0,x_1,y_1,z_1,x_2,y_2,z_2,x_3,y_3,z_3,x_4,y_4,z_4 $ where x stands for component #0, y for component #1 and z for component #2 As consequence all algorithms in ParaMEDMEM are working in full interlace mode.
  • The fifth thing is that each components of an array has info stored in a string. If a unit is desired to be added on components the following convention should be used "MY_COMPO_INFO [MYUNIT]".
    Unit should be put between "[" and "]" after info and one space character.
  • The sixth thing is that MEDCoupling arrays inherits from TimeLabel class. It means that the time stamp attached to array indicates if yes or no the array has been modified. In C++ if the access of data is direct using non const getPointer method it is the reponsability to the use to notify the possible modification. Inversely if setIJ method is used to modify an array, take care of the fact that the time stamp of the array is modified on each call to setIJ. If huge amount of call to setIJ is required it is better to use setIJSilent instead and call notifyNew right after instead.

Building an array from scratch in Python

arrayDouble=DataArrayDouble.New();
dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.]
arrayDouble.setValues(dataDouble,5,3);# 5 tuples containing each 3 components
#####
arrayInt=DataArrayInt.New();
dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24]
arrayInt.setValues(dataInt,5,3);# 5 tuples containing each 3 components

Building an array from scratch in C++

All of exemples given here make the assumption that the ParaMEDMEM namespace is visible ( by calling for example using namespace ParaMEDMEM; ).

Here a description of typical usages to use MEDCoupling arrays.
In this example we will create arrays with 12 tuples constituted each of 3 components. These arrays will be created using different ways.

The following code is only based using DataArrayDouble but the use of DataArrayInt is strictly equivalent.

const int nbOfNodes=12;
double coords[3*nbOfNodes]={ ... };

DataArrayDouble *myCoords=0;
double *tmp=0;
  • no copy no ownership
    myCoords=DataArrayDouble::New();
    myCoords->useArray(coords,false,CPP_DEALLOC,nbOfNodes,3);
    //now use myCoords as you need
    ...
    //myCoords is no more usefully here : release it
    myCoords->decrRef();
    
  • no copy and ownership C++
    myCoords=DataArrayDouble::New();
    tmp=new double[3*nbOfNodes];
    std::copy(coords,coords+3*nbOfNodes,tmp);
    myCoords->useArray(tmp,true,CPP_DEALLOC,nbOfNodes,3);
    //now use myCoords as you need
    ...
    //myCoords is no more usefully, release it
    myCoords->decrRef();
    
  • no copy and ownership C
    myCoords=DataArrayDouble::New();
    tmp=(double *)malloc(3*nbOfNodes*sizeof(double));
    std::copy(coords,coords+3*nbOfNodes,tmp);
    myCoords->useArray(tmp,true,C_DEALLOC,nbOfNodes,3);
    //now use myCoords as you need
    ...
    //myCoords is no more usefully here : release it
    myCoords->decrRef();
    
  • copy
    myCoords=DataArrayDouble::New();
    myCoords->alloc(nbOfNodes,3);
    tmp=myCoords->getPointer();
    std::copy(coords,coords+3*nbOfNodes,tmp);
    myCoords->declareAsNew();//you have modified data pointed by internal pointer notify object
    //now use myCoords as you need
    ...
    //myCoords is no more usefully here : release it
    myCoords->decrRef();
    

Array renumbering

Here is presented all it is necessary to know concerning renumbering. Renumbering is intensely required in MEDLoader in ParaMEDMEM. One of the user of renumbering is MED file for I/O where cells are sorted by type. But it is also used on operations of node cell merging. It is also used in parallel mode when splitting of mesh is needed...

Formally a renumbering is a mathematical application that can be surjective, injective or bijective. This application is defined using an instance of DataArrayInt. There are different ways to define this application.

Old to new mode

The old to new mode is particulary recommanded for surjective and bijective application. This is typically the case of MEDCouplingUMesh::mergeNodes method. Let's consider a call to mergeNodes that reduces the number of nodes from 5 nodes to 3 nodes.
In old to new mode the array MySurjection that specifies this surjection will have 5 tuples and 1 component. The content of the 5*1 values will be in {0,1,2}.

If MySujection equals [2,1,0,1,2], it means that :

  • old id #0 will have new id equal to 2
  • old id #1 will have new id equal to 1
  • old id #2 will have new id equal to 0
  • old id #3 will have new id equal to 1 like old id #1
  • old id #4 will have new id equal to 2 like old id #0

This is the most common mode of renumbering in MEDCoupling because there is more methods implying renumbering that reduce the number of entities than method that increase number of entities.

Method in old to new mode that works on bijective applications :

Method in old to new mode that works on surjective applications :

Sometimes the format old to new for sujections can be replaced by another format with 2 arrays. Less compact in memory. The DataArrayInt::changeSurjectiveFormat method performs that.

New to old mode

The new to old mode is particulary recommanded for strictly injective and bijective permutations. This is particulary usefull for methods that increase the number of entities like for example MEDCouplingUMesh::simplexize.
All non static methods in DataArrayDouble or DataArrayInt having as last letter R (meaning Reversed) in capital works with the mode new to old. Let's consider a call to simplexize that increases the number of cell from 4 cells to 6 cells.
In new to old mode the array MyInjection that specifies this injection will have 6 tuples and 1 component. The content of the 5*1 values will be in {0,1,2,3}.
If MyInjection equals [2,0,1,1,3,0] it means that :

  • new id #0 comes from old id 2
  • new id #1 comes from old id 0
  • new id #2 comes from old id 1
  • new id #3 comes from old id 1
  • new id #4 comes from old id 3
  • new id #5 comes from old id 0

Method in new to old mode that works on bijective applications :

Method in new to old mode that works on surjective applications :

Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS