/*! \page medloader MEDLoader [TOC] \section MEDLoaderIntro Introduction \ref medloader "MEDLoader" is a package in charge of loading from a file or write to a file in MED format a \ref medcoupling data structure. The fact that these functionalities are not merged in \ref medcoupling is explained by a willingness of reducing as much as possible the dependancies of \ref medcoupling libraries. As a MED file can combine several \ref medcoupling aspects in one (for exemple meshes in MED file on different mesh dimension with families and groups) the API of \ref medloader "MEDLoader" is much more rich than simply read and write. \ref MEDCouplingMeshesPage "MEDCoupling mesh" is \b not as rich as a MED file mesh, and a \ref MEDCouplingFieldsPage "MEDCoupling field" is \b not as rich as a MED file field. But it is possible to emulate with a very good fidelity a MED file mesh and a MED file field with a collection of MEDCoupling instances for each. \section MEDLoader2Approaches Two approaches are available in MEDLoader : Advanced API, Basic API \ref medloader "MEDLoader" module offers two different approaches to perform Read/Write from/to MED file. - \ref MEDLoaderAdvApproach "advanced API approach" - \ref MEDLoaderBasicApproach "basic API apprach" Whatever the approach(es) you choose, it is advisable to know main concepts of MED files \ref MEDLoaderMainC "that are quickly reminded here." \subsection MEDLoaderAdvApproach Advanced API approach \subpage MEDLoaderAdvancedAPIPage "A specific page dedicated to the advanced API is available here". This approach is the most close to MED file. By using this advanced API approach the user will manipulates classes that represents MED file concepts. It implies that the user should be informed about the \ref MEDLoaderMainC "MED file concepts", that do not exist in \ref medcoupling "MEDCoupling". For example : - group/family in meshes - profiles in fields This is typically the case for a user that wants to precisely set/get mesh/group/family groups set on different level. *That's why a set of classes representing a memory representation of MED file concepts are proposed by advanced API approach.* *So All information contained in file is represented in advanced API class instances.* The level of coherency check is variable across methods, to let to the user the maximal capacity of modification of its MED file data in memory. This API is particulary recommended : 1. For users that want to repare a MED file (invalid family ids, invalid mesh dimension, mismatch of family ids, numbering cells/nodes array modification) 2. For users that want to operate directly on complex MED file objects (split of MED files for example, duplication of nodes). \subsection MEDLoaderBasicApproach Basic API approach \subpage MEDLoaderBasicAPIPage "A specific page dedicated to the basic API is available here". This approach is less close to MED file concepts, but closer to \ref MEDCouplingMainConc "MEDCoupling concepts". So, basic API, is simpler as show method MEDLoader::WriteUMesh that needs no special knowledge needed of MED file concepts to interact with MED files. This API is in the form of a list of public static methods a class ParaMEDMEM::MEDLoader. This simplicity has a cost, the I/O are not (cannot be) optimized. As MED file concepts are more complex than MEDCoupling concepts, this approach is not the most relevant for specific MED file objects read/write. - Manipulation of multi level MED file mesh is not easy to manipulate with basic approach - Manipulation of partial fields in not easy to manipulate too with basic approach \subsection MEDLoaderCohabitationApproach Cohabitation of the two approaches The two approaches are \b NOT opposed, they are compatible each other so it is possible to mix them. Typically it it is possible to read rich information of a complex MED file using advanced API in read mode, and write a simpler MED file model coming from a post treatement of the complex input MED file data to a simple output MED file using basic API for writing. \section MEDLoaderMainC Main concepts of MED files Here we will describes some of basic concepts of MED files in order to use the best methods proposed by \ref medloader "MEDLoader API". \subsection BasicMEDLoaderAPIGen Basics in MED files First of all **MEDLoader will not read MED files whose version is strictly lower than 2.2.** For new comers in MED file world some of basics principles are recalled in the following graphic : \image html MEDFileConcepts.png "Resumed MED file concepts" Inside the parenthesis, there is multiplicity : - + stands for [1,inf) - * stands for [0,inf) - ? stands for 0 or 1 Each box are **independant in MED file format during read write session.** **Boxes instances are linked each other only by red arrows using string as discriminating key.** It implies that empty names in basic concepts objects of MED file are forbidden. There can be as many instance of boxes as wanted in a MED file. **As it can be seen in MED file world, fields and meshes are sorted by geometric type**. This specificity leads to a constraint during writing phase because some mesh operations may modify significantly the organization of geometric types during mesh/field operations. \n Here some of operation that can alter the geometric type order of cells : - aggregation of meshes - aggregation of fields - extraction of a part of meshes - extraction of a part of fields - partial polyhedrization of meshes - unpolyhedronization of meshes \section MEDLoaderCommonVoc Vocabulary used in MEDLoader \subsection MEDLoaderCommonVocRelMeshDimMesh Relative mesh dimension in meshes As it has been seen \ref BasicMEDLoaderAPIGen "above", all big arrays in fields and meshes (execpted coordinates) are sorted by geometric type, without any awareness of the dimension. For example an unstructured mesh in MED file world can lie simultaneously on MED_TRI3, MED_POINT1, MED_POLYHED, MED_TETRA4..., \ref MEDCouplingMeshes "which is impossible in MEDCoupling" for manipulation reasons. To connect the MED file world to the MEDLoader/MEDCoupling world the notion of **relative mesh dimension** has been introduced in \ref medloader "MEDLoader". This concept of **relative mesh dimension** is used frequently in the \ref medloader "MEDLoader both APIs" ( \ref MEDLoaderBasicAPIPage "basic" and \ref MEDLoaderAdvancedAPIPage "advanced"). To explain the semantic of **relative mesh dimension** let's take the example of a mesh called \a myMesh in a MED file, containing MED_TRI3, MED_POINT1, MED_POLYHED, MED_TETRA4. For each geometric type on which \a myMesh is defined the mesh dimension are : - MED_TRI3 -> mesh dimension=2 - MED_POINT1 -> mesh dimension=0 - MED_POLYHED -> mesh dimension=3 - MED_TETRA4 -> mesh dimension=3 The mesh dimension of \a myMesh is equal to 3 ( \f max(2,0,3,3) ). The **relative mesh dimension** is equal to the difference between mesh dimension of geometic type and the mesh dimension of the whole MED file dimension. It leads to the following **relative mesh dimension** : - MED_TRI3 -> **relative mesh dimension** = -1 - MED_POINT1 -> **relative mesh dimension** = -3 - MED_POLYHED -> **relative mesh dimension** = 0 - MED_TETRA4 -> **relative mesh dimension** = 0 In \ref medloader "MEDLoader" all geometric information are then grouped relative dimension per relative dimension. It leads to the following geometric sorting of MED file data structure of \a myMesh : - Level 0 - MED_TETRA4 - MED_POLYHED - Level -1 - MED_TRI3 - Level -2 - nothing -> level **not** available for \a myMesh - Level -3 - MED_POINT1 The mesh dimension of \a myMesh is 3. The relative mesh dimensions available are 0, -1 and -3. \subsection MEDLoaderCommonVocRelMeshDimField Relative mesh dimension in fields As it has been seen previously in \ref MEDLoaderCommonVocRelMeshDimMesh "for meshes", the values of fields are sorted by levels too. The principle is the same than those explained for meshes. The only difference is in the fact that it is possible for fields on cell and fields on gauss points that mesh dimension of underlying mesh of a field is not always (but very often) equal to the dimension of geometric types on which this field is defined. So it is advised, to compare the non empty level of a field **and** of its underlying mesh before trying to request heavy data from a MED file. \subsection MEDLoaderCommonVocIterationOrder Iteration and order in MED file As seen \ref BasicMEDLoaderAPIGen "above", fields in MED file can be defined on different time steps. But there is a **major difference** with \ref medcoupling MEDCoupling concept in time steps. \ref medcoupling MEDCoupling is focused to the float value of time for interpolation reason. \ref medloader MEDLoader and MED file are focused on pair of integer to precise a specific time steps. This difference of point of view can be seen in the API where the order of returned parameters in python differs from MEDCouplingFieldDouble::getTime to MEDFileField1TS::getTime. In MED file and so in \ref medloader MEDLoader the time steps are identified by a pair of integers called : - iteration - order Order refers to sub iteration id, that is by default set to -1 in case of non use. A physical time with float type is attached to this pair of integer. */ /*! \page MEDLoaderBasicAPIPage Basic MEDLoader API. [TOC] The aim of this page is to present basic API of MEDLoader. The goal of this basic API is to perform a read or a write in one shot without any internal state. That's why the basic API of MEDLoader offers \b only \b static methods whose method names have the first character in capital. You are intended to use these methods. The following chapters will try to describe in details some of important ones. The basic idea of MEDLoader is to exploite as much as possible MED file capabilities to store MEDCoupling data file in a MED file and reversely to load from a MED file into a MEDCoupling data structure. Basically, the info on components of ParaMEDMEM::DataArrayDouble instances are stores into components and units into MED files. The name of meshes and fields are used by MEDLoader to use it as this into MED file. A field f with \ref ParaMEDMEM::MEDCouplingTimeDiscretization "time discretization" set to ONE_TIME, the value of \c f->getTime(time,iteration,order) are used by MEDLoader to store to identify the field into MED file. All strings used by MEDLoader to use it into MED file should fulfill the rules of MED file where length are limited. That's why the user should be aware of these constaints when trying to read/write a MED file using MEDLoader. MEDLoader tries to manage that by protecting the user by throwing exceptions when the rules are not followed. \section BasicMEDLoaderBasicAPIGlobalInfo Retrieving tiny global information from MED files using basic API The MEDLoader::CheckFileForRead method will perform the check of that before any attempt of read. A field is also discriminated by its name. The method MEDLoader::GetCellFieldNamesOnMesh and MEDLoader::GetNodeFieldNamesOnMesh are available to know all fields respectively on cells and on nodes lying on a specified mesh. A field is defined by several time steps discriminated by a pair of int (iteration,order). It is \b not possible to store 2 time steps of a same field having the same iteration and order number. The floatting point value attached on this couple of ids (iteration,order) is only present for information. Static methods MEDLoader::GetCellFieldIterations and MEDLoader::GetNodeFieldIterations return a vector of pair containing each respectively iteration and order. A time step of a field lyies on one \b or \b more mesh(es) specified by its \b or \b their name. A time step of a field in MED file could be defined on point \b and on cell \b and, \b or on gauss points \b and, \b or on point per element. This recalled specificities of MED file explains that it is necessary to specify each time, at field-read time, the type of field, the iteration and order number the mesh you are interested in. Let's recall basic principles that explains some of the aspect of MEDLoade API. \anchor MEDLoaderMeshNameConstraint MED file can contain several meshes. These meshes are discriminated by their names (two meshes could not have the same names). By the same way a MED file can contain several fields in MED. So MEDLoader propose to you the MEDLoader::GetMeshNames method to discover all the mesh names contained in your file. \section BasicMEDLoaderBasicAPIMesh Reading and writing meshes in MED files using basic API In MED file meshes could combine in one unstructured mesh cells that have different dimension. For example it is possible to mix MED_TETRA4, MED_TRIA6, MED_SEG2, MED_POINT1, MED_POLYGON, MED_POLYHEDRA in a same mesh. In MEDCouplingUMesh such a mix is not allowed as described \ref MEDCouplingUMeshes "here". So to \b read such mesh it is important to know which meshdimension you are interested to. In API the parameter \b meshDimRelToMax discreminates the meshdim you are interested to relatively to the maximal dimension of cells contained in the mesh in file. Let's take 2 examples : - If you have a mesh called "MyMesh" in file "file1.med" with MED_POLYGON, MED_TRI3, MED_SEG2 and MED_SEG3 : The max dimension of cells is 2 (for MED_POLYGON and MED_TRI3). So if you want exclusively cells with type MED_POLYGON and MED_TRI3 you should use : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_9 If you are interested in MED_SEG2 and MED_SEG3 you should use : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_10 The method MEDLoader::ReadUMeshDimFromFile could help you to have this mesh dimension. \anchor MEDLoaderExample2 - Consider an another mesh called "Example2" in file "file2.med" containing MED_POLYHEDRA, MED_TETRA4, MED_QUAD8, MED_TRI6, MED_SEG2 and MED_POINT1. In this case you will have : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_8 To get 3D cells (MED_POLYHEDRA and MED_TETRA4) you should type : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_7 To get 2D cells (MED_TRI6 and MED_QUAD8) you should type : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_4 To get 1D cells (MED_SEG2) you should type : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_5 And finally for 0D cells (MED_POINT1) you will write : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_6 To finish this subsection, it is important to know that MEDLoader takes into account of the cell numbers stored in a mesh of a med file. This renumbering allows MEDLoader to conserve the order of MEDCoupling cells into the file. So if the renumbering of cells in MED file is not correct an exception will be thrown. \subsection BasicMEDLoaderAPIPoMesh Part of meshes in MED files A mesh contains one or more families on nodes and/or on cells. A family is a partition (mathematical sense) of the mesh it lies to. A family can be described by an integer field on \b all nodes and on \b all cells of a same mesh. All cells and nodes having the same ids defines this family. This id is called the familyId. A family is discriminated by its id. MED file attach a name to its id to be more userfriendly. So by construction, 2 different families could not share anything. The user can retrieve all the families names available on a mesh with the static method MEDLoader::GetMeshFamiliesNames. A group is a set of families. So groups can overlap each other, contrary to families. Groups are also discriminated by a name. As for families the static method to retrieves the groups of a specified mesh is MEDLoader::GetMeshGroupsNames. MEDLoader allows you to retrieve the corresponding "part of meshes" thanks to static methods MEDLoader::ReadUMeshFromFamilies and MEDLoader::ReadUMeshFromGroups. This method allows you to combine several families and groups in the same returned mesh. \subsection BasicMEDLoaderAPIField Reading a field at one time step in MED files A field at one time step on one mesh, with one entity (cell, node) lies on all mesh on on a part of it. In this last case a definition of a profile is needed. Even if the notions of profile on mesh and group on mesh could appear close, these two concepts are totally disconnected in MED file. The aspect of profile is managed by MEDLoader, thats why this aspect does not appear in the MEDLoader API. So to retrieve a field on 3D cell called "F1Cell" in example file \ref MEDLoaderExample2 "file2.med (seen in meshes section)" on a mesh "Example2" on time step defined by iteration number 2 and iteration 3 the request will be : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_12 To retrive the same field (same iteration) on 2D cells only the call will be : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_13 \subsection MEDLoaderMEDFieldsRead Reading several field time steps at a time in MED files It is possible with MEDLoader to read several time steps of a field at a time. The advantage with this approach is to avoid to read and load several time a same mesh. This is typically recommanded to use the following code when you desire to load all time steps of a field on cell "myField" lying on same mesh "mesh1" in one shot : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_11 \section MEDLoaderWriteMain Writing a MED file with MEDLoader As MED file does, MEDLoader write process separates clearly meshes from fields. The reason is that a common use case in write mode is to write in a first time a mesh and then writes several time steps of a same field in appended mode. The fact that the write process is rarely in a one shot put a constraint on API to precise to MEDLoader if you intend to append data to an existing file, or if you want to create a new file from scratch. This explains the presence of boolean parameter \b writeFromScratch in API of MEDLoader starting with \b MEDLoader::Write* . If \b writeFromScratch parameter is set to \b true and if the file already exists the file will be crashed and replaced by the new corresponding data. If \b writeFromScratch parameter is set to \b false and if the file does \b not \b exist the new file is created, but if the file exists MEDLoader will enter in appended mode. Two classes of MEDLoader write methods exists when \b writeFromScratch is set to \b false : - Methods \b MEDLoader::Write*Dep : The write operation is performed without any question in file. The responsability is let to the user because the MED file could be corrupted. The advantage of this method is that it is faster because no check is done. - Methods \b MEDLoader::Write* : MEDLoader will not corrupt your file by always trying to append data. The consequence of that is that a read of part (and data processing) of MED file could be needed before any attempt of writing. So these methods could be in some cases much time and memory consuming. The behaviour of MEDLoader when \b writeFromScratch is set to false will be precised for each \b MEDLoader::Write* methods is the next subsections. \subsection MEDLoaderWriteMesh Writing one mesh in a MED file with MEDLoader The first think to know is that MEDLoader is using the \b meshName in ParaMEDMEM::MEDCouplingMesh instance to put it in MED file. As explained in previous section \ref MEDLoaderMeshNameConstraint "here", a mesh in MED file is discriminated by a name, so the \b meshName \b should \b be \b non \b empty. If it is the case an INTERP_KERNEL::Exception will be thrown. To write one mesh \b myMesh with name \b "myMeshName" in a MED file \b "wfile1.med" the following code should be typed : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_1 With the previous code, if "wFile1.med" file existed the file is crashed and will contain after the call only the content of myMesh instance. If you desire to append a mesh in "wFile1.med" you should type : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_2 With the previous code, if the "wFile1.med" had already a mesh called "myMeshName" an INTERP_KERNEL::Exception will be thrown. \subsection MEDLoaderWriteMeshes Writing several meshes in a MED file with MEDLoader It could be interesting to write several meshes in one shot. Two possiblities are possible : - Write several instances of ParaMEDMEM::MEDCouplingUMesh lying \b on \b same \b coords \b with \b different \b mesh \b dimension. In this case the use of MEDLoader::WriteUMeshes is the method you should use. Typically this method should be used to write such of file defined \ref MEDLoaderExample2 "here". This method first checks that all instances share the same ParaMEDMEM::DataArrayDouble instance as coords. If not an INTERP_KERNEL::Exception will be thrown and an invocation on ParaMEDMEM::MEDCouplingPointSet::tryToShareSameCoords will be necessary. - Write a partition of meshes having \b same \b mesh \b dimension, that is to say a set of groups and families from given meshes. As in the previous case the check of same coords will be done (if not an INTERP_KERNEL::Exception is thrown). After this step this method will merge (by concerving the order in input) and will simplify the merged mesh. After this operation, the groups will be constituted by assigning the groups names with the conresponding names of instance. That's why all meshes have to have a not empty name and different each other. The method to use in this case is MEDLoader::WriteUMeshesPartition. For these 2 described methods the semantic of \b writeFromScratch when \b false is the same, that is to say : no writing (INTERP_KERNEL::Exception thrown) will be done if the file already exists and contains already a mesh with name 'meshName' for MEDLoader::WriteUMeshesPartition method and the name of the first of the vector of unstructured meshes passed as first parameter of MEDLoader::WriteUMeshes. \subsection MEDLoaderWriteField Writing one time step of a field in a MED file with MEDLoader To write \b one \b time \b step of a field from scratch with MEDLoader is to use MEDLoader::WriteField method. The behviour of this method depends on the value of the \b writeFromScratch paramter : - When \b writeFromScratch equals to \b true, this method performs two things, it writes the underlying mesh and write the specified time step on it. - When \b writeFromScatch equals to \b false, this method looks that the underlying mesh exists (by looking the content of \c field->getMesh()->getName() ) in file. If not, the behaviour is the same that previous case with \b writeFromScratch parameter set to \b true. If the mesh already exists, MEDLoader reads the field and tries to apply field on it. This operation could be rather time consuming because a read operation is performed and a reorder operation too. If the file already contains the same field at the same time step (iteration and order ids) the corresponding time step will be replaced by the field passed in parameter. \subsection MEDLoaderWriteFields Writing several time steps of a field in a MED file with MEDLoader To write a serie of time steps in a "file3.med" file lying on the same unstructured mesh the typical code to write is the following : \snippet MEDLoaderExamplesTest.py PySnippetMeshAdvAPI1_3 In the previous code, it is important to note that the values of pair (iteration,order) should be different between two calls to avoid that a call to MEDLoader::WriteFieldUsingAlreadyWrittenMesh overwrites a previous call. An another important thing is the fact that \c f->getMesh() does not be modified. This method of writing presents the big advantage to be fast, because no check neither read is performed by this method. That's why contrary to other MEDLoader::Write* method the parameter of \b writeFromScratch is not needed here. */ /*! \page MEDLoaderAdvancedAPIPage Advanced MEDLoader API. [TOC] This method is much closer to MED file organization than \ref MEDLoaderBasicAPI "basic MEDLoader API". All MED file concepts are exposed to the user. As a consequence, this advanced API is lead to change with MED file data model enhancement. In reading mode, the user can scan entirely and directly the content of its MED file as it is organized in its MED file. Inversely, in writing mode, the user can describe its data in the same way that MED file does. \section AdvMEDLoaderBasics Some of basics of advanced API - Like basic %MEDLoader API there is a notion of \c meshDimRelToMax. Each time This parameter appears in API, it will have the semantic explain here. The value of the parameter \c meshDimRelToMax is at most in {0,-1,-2,-3}. This relative value specifies a level relative to value returned by ParaMEDMEM::MEDFileMesh::getMeshDimension(). A mesh containing MED_TETRA4, MED_TRI3, MED_QUAD4 and MED_POINT1 has a meshDimension equal to 3. For \c meshDimRelToMax equal to 0 the user will deal with cells whose type has a dimension equal to 3+0, that is to say here MED_TETRA4. For \c meshDimRelToMax equal to -1 the user will deal with cells witch dimension equal to 3-1 that is to say MED_TRI3 and MED_QUAD4. An important method is ParaMEDMEM::MEDFileUMesh::getNonEmptyLevels() method. It returns all non empty levels available. In the previous example, this method will return {0,-1,-3}. -2 does not appear because no cells with dimension equal to 1 (3-2) appear in MED file mesh (no MED_SEG2 not MED_SEG3). - Besides notion of \c meshDimRelToMax there is notion of \c meshDimRelToMaxExt. \c meshDimRelToMaxExt is simply an extension of \c meshDimRelToMax for nodes. The parameter of \c meshDimRelToMaxExt appears in \ref ParaMEDMEM::MEDFileUMesh "umesh advanced API" of %MEDLoader with the following semantics. Some of MED file concepts are available both for cells and nodes, (for example families, groups, numbering ) that's why for a simpler API this concept has been introduced. \c meshDimRelToMaxExt parameter can take a value in at most {1,0,-1,-2,-3}. 1 stands for node and 0,-1,-2,-3 has exactly the same semantic than those described in \c meshDimRelToMax decribed before. - A parameter that also often appears in advanced %MEDLoader API is \c renum. This parameter by default in advanced %MEDLoader API is set to \c true. This parameter indicates if the user intend to take into account of the renumbering array of cells of the current MED file mesh. If no renumbering array is defined, this parameter is ignored by %MEDLoader. If such renumbering exists and the \c renum parameter is set to \c true, then the renumbering is taken into account. This is exactly the behaviour of \ref MEDLoader::ReadUMeshFromFile "basic MEDLoader API". If the user expects to ignore this renumbering even in case of presence of renumbering array, false should be passed to \c renum parameter. \b The \b parameter \b renum \b should \b be \b set \b with \b cauton \b for \b users \b concerned \b by \b cells \b orders. - A laster important parameter is the \c mode during writing. The available values for the parameter \c mode are : - 2 : for a write from scratch. If file already exists, file will be erased and replace by the content of the instance on which \c write method has been calles. - 1 : If the file does not exists equivalent to 2. If file already exists, the write is done on APPEND mode. That is to say that no data loss will occur. But in case that an element with same ids than current instance already exists, the content is not written and an exception is thrown. - 0 : If the file does not exists equivalent to 2. If file already exists write without any question. If an element with same ids existed previously the content is overwritten by the content of the current instance, that can lead to a file corruption. \section AdvMEDLoaderAPIMeshesRW Dealing with Meshes with advanced API. Contrary to the basic %MEDLoader API, here after reading process, the user has to deal with a new instance of class that fits the MED file model. To access to a MEDCoupling mesh the user should request this class instance. \subsection AdvMEDLoaderAPIMeshReading Reading a mesh. The class that incarnates Read/Write mesh in MED file is ParaMEDMEM::MEDFileUMesh. First of all, like basic %MEDLoader API, only MEDfile files whose version >= 2.2 are able to be read with advanced API. To read a mesh having the name \c meshName in file \c fileName the following simple code has to be written : \code MEDFileUMesh *myMedMesh=MEDFileUMesh::New(fileName,meshName); \endcode If the user do not know the name of the mesh inside MED file 'fileName' the following code should be written : \code MEDFileUMesh *myMedMesh=MEDFileUMesh::New(fileName); \endcode In this case the first mesh (in MED file sense) found in \c fileName file will be loaded. Now the user can ask for mesh dimension of of \c myMedMesh instance by calling \c myMedMesh->getMeshDimension(). This method returns the highest level of present cell in MED file mesh \c myMedMesh. This returned integer is computed and \b not those contained in MED file that can be invalid. \n - Retrieving a mesh at a specified relative level \c meshDimRelToMax=mdrm : simply call - \c myMedMesh->getMeshAtLevel(mdrm) - or \c myMedMesh->getLevel0Mesh() or \c myMedMesh->getLevelM1Mesh(), or \c myMedMesh->getLevelM2Mesh() depending on the value of mdrm - Retrieving a family at a specified level : - Either an array of node/cell id - \c getFamilyArr method or \c getFamiliesArr - Or on \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" form by calling - \c getFamily method or \c getFamilies - Retrieving a group at a specified level : - Either an array of node/cell id - \c getGroupArr method or \c getGroupsArr - Or on \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" form by calling - \c getGroup method or \c getGroups - Retrieving family field array : Method \c getFamilyFieldAtLevel retrieves for a specified extended level the family id of each cell or node. - Retrieving renumbering array : Method \c getNumberFieldAtLevel returns, if it exists for a specified extended level, the family id of each cell or node. If it does not exist an exception will be thrown. An important point is that families and groups are \b not sorted in MED file. No sort is stored in MED file explicitely for Groups and Families. Advanced %MEDLoader API, uses the same order than underlying mesh at specified level. \subsection AdvMEDLoaderAPIMeshReadingSampl Sample of reading a mesh. Here a typical use of \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" instance. \code const char fileName[]=...; const char meshName[]=...; MEDFileUMesh *medmesh=MEDFileUMesh::New(fileName,meshName); std::vector nel=medmesh->getNonEmptyLevels(); if(nel.size()<1) throw INTERP_KERNEL::Exception("The test is not good for my file ! Expecting a multi level mesh to play with !"); MEDCouplingUMesh *m0=medmesh->getMeshAtLevel(nel[1],false); MEDCouplingUMesh *g1=medmesh->getGroup(nel[1],"mesh2",false); DataArrayInt *dag1=medmesh->getGroupArr(nel[1],"mesh2",false); MEDCouplingUMesh *g1bis=m0->buildPartOfMySelf(dag1->getConstPointer(),dag1->getConstPointer()+dag1->getNbOfElems()); g1bis->setName(dag1->getName()); if(!g1->isEqual(g1bis,1e-12)) throw INTERP_KERNEL::Exception("hmmmm :g1 and g1bis should be equal..."); // dag1->decrRef(); g1->decrRef(); m0->decrRef(); medmesh->decrRef(); \endcode \subsection AdvMEDLoaderAPIMeshWriting Writing a mesh. The use is very symetric to reading part. It is possible to either build a \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance from scratch, or to work with an existing instance coming from a loading from a file. One important point is that coordinates of a mesh are shared by all cells whatever their level. That's why the \ref ParaMEDMEM::DataArrayDouble "DataArrayDouble" instance should be shared by all \ref ParaMEDMEM::MEDCouplingUMesh "MEDCouplingUMesh" used in input parameter of set* methods. If the user intend to build a \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance from scratch, a call to \c setCoords should be done first. Generally speaking traduce get* methods with set* methods have corresponding write semantic. Some differences still exist : - \c setMeshAtLevel, \c setMeshAtLevelOld simply call \c setMeshAtLevelGen with repectively \c newOrOld parameter set to true and false. These method specifies if a renumbering computation is needed or not. \c setMeshAtLevelOld is faster than \c setMeshAtLevel because no renumbering computation is done. If the user is not warranty about the order of its meshes to enter it is better to use \c setMeshAtLevel method. - Groups definition : Groups constitution is time consuming because of the stored mode chosen by MED file to store them. Groups definition lead to a partition computation which is time/mem consuming that's why groups should be defined at once and not with addGroup one by one that will lead to compute a partition for each appended group. One important point to note is that DataArrayInt instance given in input to define groups should have its name set to the desired group name. If not an exception will be thrown, because MED file does not support groups with no name. \subsection AdvMEDLoaderAPIMeshWritingSampl Sample of writing a mesh. \code MEDCouplingUMesh *m=...; //m is a mesh with meshDim=2 spaceDim=2 MEDCouplingUMesh *m1=...; //m1 is a mesh with meshDim=1 spaceDim=2 same coords than m MEDCouplingUMesh *m2=...; //m2 is a mesh with meshDim=0 spaceDim=2 same coords than m MEDFileUMesh *mm=MEDFileUMesh::New(); mm->setName("mm");//name needed to be non empty mm->setDescription("Description mm"); mm->setCoords(m1->getCoords()); mm->setMeshAtLevel(-1,m1,false); mm->setMeshAtLevel(0,m,false); mm->setMeshAtLevel(-2,m2,false); DataArrayInt *g1=DataArrayInt::New(); g1->alloc(2,1); g1->setName("G1"); const int val1[2]={1,3}; std::copy(val1,val1+2,g1->getPointer()); DataArrayInt *g2=DataArrayInt::New(); g2->alloc(3,1); g2->setName("G2"); const int val2[3]={1,2,3}; std::copy(val2,val2+3,g2->getPointer()); // std::vector grps(2); grps[0]=g1; grps[1]=g2; mm->setGroupsAtLevel(0,grps,false); // g2->decrRef(); g1->decrRef(); // mm->write(2); \endcode \section AdvMEDLoaderAPIFieldRW Dealing with Fields with advanced API. In advanced API fields have been developed using divide and conquer pattern to reproduce with the maximal fidelity the MED file field concept \ref BasicMEDLoaderAPIGen "seen here". Here the list of classes in %MEDLoader advanced API top down sorted : - Level 0 : ParaMEDMEM::MEDFileFields - Level -1 : ParaMEDMEM::MEDFileFieldMultiTSWithoutSDA - Level -2 : ParaMEDMEM::MEDFileField1TSWithoutSDA - Level -3 : ParaMEDMEM::MEDFileFieldPerMesh (present only for backward compatibility MED file 2.2) - Level -4 : ParaMEDMEM::MEDFileFieldPerMeshPerType - Level -5 : ParaMEDMEM::MEDFileFieldPerMeshPerTypePerDisc In each level in tree of the the cyan box of field is represented by a class. The only difference is that values are grouped in a single big array located in level -2 (ParaMEDMEM::MEDFileField1TSWithoutSDA) in which each leaves (level -5) of MED file field point to using a range [\a start, \a end). As different time steps of a same field and different field inside a MED file can shared or not profiles (yellow box) and Locatization (red box) a manipulable field classes instance (ParaMEDMEM::MEDFileField1TS and ParaMEDMEM::MEDFileFieldMultiTS) in advanced API are the result of a subclass of a data class (respectively ParaMEDMEM::MEDFileField1TSWithoutSDA, ParaMEDMEM::MEDFileFieldMultiTSWithoutSDA) and a instance of ParaMEDMEM::MEDFileFieldGlobsReal representing the shared data arrays (SDA) at a specified scope inside the MED file. \subsection AdvMEDLoaderAPIFieldR Reading a field \subsubsection AdvMEDLoaderAPIFieldRC Reading a field defined on all entity Fields defined on all entity are the most used and common fields in MED file world. In this mode the user do **not** want to retrieve the entity ids of the constituting subsupport of the whole mesh because it has no sense. Let's read a field on all entity called \a fieldName lying on a mesh called \a meshName in a MED file called \a fname at a iteration defined on time step defined by \a iteration and \a order. \snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_1 To read it there are 3 main approaches : - Use ParaMEDMEM::MEDFileField1TS class : \snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_3 - Use ParaMEDMEM::MEDFileFieldMultiTS class : \snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_4 - Use iteration ParaMEDMEM::MEDFileFieldMultiTS class : \snippet MEDLoaderExamplesTest.py PySnippetReadFieldOnAllEntity1_5 \subsubsection AdvMEDLoaderAPIFieldRP Reading a partial field Let's read a partial field called \a fieldName lying on a mesh called \a meshName in a MED file called \a fname at a iteration defined on time step defined by \a iteration and \a order. \snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_1 Fields defined partially on a meshes can been read using 2 main approaches : - Either the user wants to retreave it's field in %MEDCoupling sense, that is to say for interpolation, to evaluate such field on different points... \n In this mode the link with the whole mesh is not useful for the user \snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_3 - Or the user wants to retrieve the binding (cell ids or node ids) with the whole mesh on which the partial field lies partially on. \snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_4 \ref medcoupling "MEDCoupling" allows to make bridges between the approaches. For example \a pfl \ref ParaMEDMEM::DataArrayInt "DataArrayInt instance" retrieved directly from the file in the second approach can be retrived starting from first approach. Starting from mesh \a firstApproachMesh of read field in first approach \a fread, whith the whole mesh \a wholeMesh the profile \a pflComputed can be computed : \snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_5 Inversely, it is possible to rebuild field obtained in first apprach starting from second approach : \snippet MEDLoaderExamplesTest.py PySnippetReadFieldPartial1_6 \subsection AdvMEDLoaderAPIFieldW Writing a field \subsubsection AdvMEDLoaderAPIFieldWC Writing a field defined on all entity Fields defined on all entity are the most used and common fields in MED file world. In this mode the user do **not** want to retrieve the entity ids of the constituting subsupport of the whole mesh because it has no sense. Let's write a cell field on all entity called \a fieldName lying on a mesh called \a meshName in a MED file called \a fname at a iteration defined on time step defined by \a iteration and \a order. \snippet MEDLoaderExamplesTest.py PySnippetWriteFieldOnAllEntity1_2 We can see here that the necessity to deal with both mesh and field to write a field is exposed by the API. The mesh write mode is 2 to tell to MED file that is file already exists to scratch it. The mode of write is 0 to simply add to the file the field specific part. \subsubsection AdvMEDLoaderAPIFieldWP Writing a partial field \snippet MEDLoaderExamplesTest.py PySnippetWriteFieldPartial1_2 To write a partial field \a f can have a **null mesh**, because the link with mesh is made given the entry of \a mm MEDFileField1TS::setFieldProfile method. */