Salome HOME
Documentation reorganization
[modules/med.git] / doc / tutorial / medloader_advancedAPI1_fr.rst
1
2 Lecture, écriture d'un fichier MED grâce à l'API avancée de MEDLoader
3 ---------------------------------------------------------------------
4
5 L'API avancée de MEDLoader est représentée par les classes ``MEDFile*`` de la bibliothèque MEDLoader.
6
7 * Au plus haut niveau, pour l'ensemble du fichier: ``MEDFileData``,
8 * Pour l'ensemble des maillages du fichier : ``MEDFileMeshes``,
9 * Pour chacun des maillages : ``MEDFileMeshMultiTS``, ``MEDFileMesh``, ``MEDFileUMesh``, ``MEDFileCMesh``,  
10 * Pour l'ensemble des champs du fichier : ``MEDFileFields``, ``MEDFileFieldGlobs``, 
11 * Et enfin pour chacun des champs : ``MEDFileField1TS``, ``MEDFileFieldMultiTS``
12
13
14 Objectif
15 ~~~~~~~~
16
17 Ecrire un maillage et un champ à partir de rien, les relire et comparer les résultats.
18
19 Points abordés : en utilisant l'API avancée de MEDLoader,
20
21 * Ecrire un fichier 
22 * Lire un fichier
23
24 Début d'implémentation
25 ~~~~~~~~~~~~~~~~~~~~~~
26
27 Cet exercice repose comme tous les autres sur le language de script Python. On charge 
28 le module Python ``MEDLoader``.
29
30 Pour information, le module ``MEDCoupling`` complet est inclus dans ``MEDLoader``. Pas besoin de l'importer
31 si ``MEDLoader`` a été chargé. ::
32
33         import MEDLoader as ml
34         from MEDLoader import MEDLoader
35
36 Lecture, écriture d'un maillage
37 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38
39 Nous créons tout d'abord le même maillage ``targetMesh`` que pour l'API simple. ::
40
41         targetCoords = [-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]
42         targetConn = [0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
43         targetMesh = ml.MEDCouplingUMesh("MyMesh",2)
44         targetMesh.allocateCells(5)
45         targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[4:7])
46         targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[7:10])
47         targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[0:4])
48         targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[10:14])
49         targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[14:18])
50         targetMesh.finishInsertingCells()
51         myCoords = ml.DataArrayDouble(targetCoords,9,2)
52         myCoords.setInfoOnComponents(["X [km]","YY [mm]"])
53         targetMesh.setCoords(myCoords)        
54
55 .. note:: Le maillage ``targetMesh`` est ordonné par type géométrique.
56
57 Nous construisons ensuite ``targetMesh1`` représentant les sous-constituants (*faces*) du maillage
58 ``targetMesh`` reduits aux cellules [3,4,7,8]. Cela peut par exemple représenter un ensemble d'intérêt pour un calcul : ::
59
60         targetMeshConsti, _, _, _, _ = targetMesh.buildDescendingConnectivity()
61         targetMesh1 = targetMeshConsti[[3,4,7,8]]
62         targetMesh1.setName(targetMesh.getName())
63
64 .. note:: En Python, le underscore ``_`` signifie que l'on attend une valeur de retour, mais qu'on n'en aura pas l'usage 
65         (on ne la *bind* pas).
66 .. note:: ``targetMesh1`` sera sauvé comme étant une partie du même maillage global dans le fichier MED. 
67         Il doit donc avoir le même nom. C'est là qu'on voit qu'un maillage au sens MED fichier peut mélanger les dimensions. 
68
69 On peut alors écrire les deux maillages dans le fichier "TargetMesh2.med". ::
70
71         meshMEDFile = ml.MEDFileUMesh()
72         meshMEDFile.setMeshAtLevel(0,targetMesh)
73         meshMEDFile.setMeshAtLevel(-1,targetMesh1)
74         meshMEDFile.write("TargetMesh2.med",2)         # 2 stands for 'write from scratch'
75
76 Lecture, écriture de groupes de mailles
77 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
78
79 Créons deux groupes de cellules sur le maillage 2D, c'est à dire au niveau relatif 0 (ici, le niveau relatif 0 correspond
80 à la 2D, le niveau -1 
81 correspond à la 1D,  etc ...). Le premier groupe ``grp0_Lev0`` contient les cellules [0,1,3] 
82 le second ``grp1_Lev0`` les cellules [1,2,3,4] : ::
83
84         grp0_0 = ml.DataArrayInt([0,1,3]) 
85         grp0_0.setName("grp0_Lev0")
86         grp1_0 = ml.DataArrayInt([1,2,3,4])
87         grp1_0.setName("grp1_Lev0")
88         meshMEDFile.setGroupsAtLevel(0, [grp0_0,grp1_0])
89
90 .. note:: On voit évidemment ici l'importance de nommer les tableaux : c'est le nom qui sera utilisé pour le groupe. 
91
92 Créons trois groupes de niveau -1, c'est à dire des groupes de faces. Le premier appelé 
93 ``grp0_LevM1`` aux cellules [0,1], le second appelé ``grp1_LevM1`` aux cellules [0,1,2], et le 3ème ``grp2_LevM1``
94 aux cellules [1,2,3] : ::
95
96         grp0_M1 = ml.DataArrayInt([0,1])
97         grp0_M1.setName("grp0_LevM1")
98         grp1_M1 = ml.DataArrayInt([0,1,2])
99         grp1_M1.setName("grp1_LevM1")
100         grp2_M1 = ml.DataArrayInt([1,2,3])
101         grp2_M1.setName("grp2_LevM1")
102         meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1])
103         
104 Ecrivons le tout : ::
105         
106         meshMEDFile.write("TargetMesh2.med",2)         # 2 stands for 'write from scratch'
107         
108 Nous pouvons ensuite re-lire le fichier MED : ::
109
110         meshMEDFileRead = ml.MEDFileMesh.New("TargetMesh2.med") # a new is needed because it returns a MEDFileUMesh (MEDFileMesh is abstract)
111         meshRead0 = meshMEDFileRead.getMeshAtLevel(0)
112         meshRead1 = meshMEDFileRead.getMeshAtLevel(-1)
113         print "Is level 0 in the file equal to 'targetMesh'?", meshRead0.isEqual(targetMesh,1e-12)
114         print "Is level 0 in the file equal to 'targetMesh1'?", meshRead1.isEqual(targetMesh1,1e-12)
115
116 Affichons les niveaux disponibles pour le groupe ``grp0_Lev0`` : ::
117
118         print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0")
119
120 Et récupérons enfin les identifiants de cellules contenus dans le groupe ``grp0_Lev0`` : ::
121
122         grp0_0_read = meshMEDFileRead.getGroupArr(0,"grp0_Lev0")
123         print "Is group 'grp0_Lev0' equal to what is read in the file?" , grp0_0_read.isEqual(grp0_0)
124
125 Lire/écrire des champs avec l'API avancée
126 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127
128 Créons un champ de vecteurs simple, aux cellules (P0), avec un seul pas de temps, appelé ``f``. ::
129
130         f = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME)
131         f.setTime(5.6,7,8)
132         f.setArray(targetMesh.getBarycenterAndOwner())
133         f.setMesh(targetMesh)
134         f.setName("AFieldName")
135
136 Stocker ``f`` dans un object ``MEDFileField1TS`` (un champ avec un seul pas de temps -- *one time-step, 1TS*) 
137 pour préparer l'écriture MED ::
138
139         fMEDFile = ml.MEDFileField1TS()
140         fMEDFile.setFieldNoProfileSBT(f)     # No profile desired on the field, Sort By Type
141
142 Ajouter le champ au fichier "TargetMesh2.med" ::
143
144         fMEDFile.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file
145
146 .. note:: Noter l'utilisation du 0 pour indiquer que nous désirons ajouter au fichier existant.
147
148 Lire le champ : ::
149
150         fMEDFileRead = ml.MEDFileField1TS("TargetMesh2.med",f.getName(),7,8)
151         fRead1 = fMEDFileRead.getFieldOnMeshAtLevel(ml.ON_CELLS,0,meshMEDFileRead) # Quickest way, not re-reading mesh in the file.
152         fRead2 = fMEDFileRead.getFieldAtLevel(ml.ON_CELLS,0)                       # Like above, but this time the mesh is read!
153         print "Does the field remain OK with the quick method?", fRead1.isEqual(f,1e-12,1e-12)
154         print "Does the field remain OK with the slow method?", fRead2.isEqual(f,1e-12,1e-12)
155         
156 Lire/écrire un champ sur un "profil"
157 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158
159 Nous allons maintenant voir un concept avancé des fichiers MED, à savoir la possibilité d'écrire un champ sur seulement
160 une *partie* du maillage. La technique habituellement utilisée est plutôt de mettre des valeurs particulières (e.g. +infinity
161 soit 1e+300) sur les zones où le champ n'a pas de sens, permettant ainsi de repérer en plus des bugs éventuels lors du calcul.
162
163 Le mode de fonctionnement avec les profils reste donc peu courant.
164
165 Construisons une réduction aux cellules [1,2,3] de ``f`` et appelons la ``fPart`` : ::
166
167         pfl = ml.DataArrayInt([1,2,3]) 
168         pfl.setName("My1stPfl")
169         fPart = f.buildSubPart(pfl)
170         fPart.setName("fPart")
171
172 La stocker dans la structure ``MEDFileField1TS`` et invoquer ``setFieldProfile()``. ::
173
174         fMEDFile2 = ml.MEDFileField1TS()
175         fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) # 0 is the relative level (here 0 means 2D)
176         fMEDFile2.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file
177
178 Lire le champ ``fPart`` du fichier "TargetMesh2.med" et les identifiants de cellules correspondant. ::
179
180         fMEDFileRead2 = ml.MEDFileField1TS("TargetMesh2.med",fPart.getName(),7,8)
181         fPartRead, pflRead = fMEDFileRead2.getFieldWithProfile(ml.ON_CELLS,0,meshMEDFileRead)
182         print "Is the partial field correclty read?", fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12)
183         print "Is the list of cell identifiers matching?", pflRead.isEqualWithoutConsideringStr(pfl)
184
185 Solution
186 ~~~~~~~~
187
188 :ref:`python_testMEDLoaderAdvancedAPI1_solution`
189