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