2 Lecture, écriture d'un fichier MED grâce à l'API avancée de MEDLoader
3 ---------------------------------------------------------------------
5 L'API avancée de MEDLoader est représentée par les classes ``MEDFile*`` de la bibliothèque MEDLoader.
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``
17 Ecrire un maillage et un champ à partir de rien, les relire et comparer les résultats.
19 Points abordés : en utilisant l'API avancée de MEDLoader,
24 Début d'implémentation
25 ~~~~~~~~~~~~~~~~~~~~~~
27 Cet exercice repose comme tous les autres sur le language de script Python. On charge
28 le module Python ``MEDLoader``.
30 Pour information, le module ``MEDCoupling`` complet est inclus dans ``MEDLoader``. Pas besoin de l'importer
31 si ``MEDLoader`` a été chargé. ::
33 import MEDLoader as ml
34 from MEDLoader import MEDLoader
36 Lecture, écriture d'un maillage
37 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39 Nous créons tout d'abord le même maillage ``targetMesh`` que pour l'API simple. ::
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 myCoords = ml.DataArrayDouble(targetCoords,9,2)
51 myCoords.setInfoOnComponents(["X [km]","YY [mm]"])
52 targetMesh.setCoords(myCoords)
54 .. note:: Le maillage ``targetMesh`` est ordonné par type géométrique.
56 Nous construisons ensuite ``targetMesh1`` représentant les sous-constituants (*faces*) du maillage
57 ``targetMesh``, et nous en extrayons seulement les cellules (donc ici des surfaces) [3,4,7,8].
58 Pour plus de détails sur la connectivité descendante,
59 consulter la section :ref:`exo-umesh-desc-connec` du deuxième exercise.
60 Cet ensemble peut par exemple représenter un ensemble d'intérêt pour un calcul : ::
62 targetMeshConsti, _, _, _, _ = targetMesh.buildDescendingConnectivity()
63 targetMesh1 = targetMeshConsti[[3,4,7,8]]
64 targetMesh1.setName(targetMesh.getName())
66 .. note:: En Python, le underscore ``_`` signifie que l'on attend une valeur de retour, mais qu'on n'en aura pas l'usage
67 (on ne la *bind* pas).
68 .. note:: ``targetMesh1`` sera sauvé comme étant une partie du même maillage global dans le fichier MED.
69 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.
71 On peut alors écrire les deux maillages dans le fichier "TargetMesh2.med". ::
73 meshMEDFile = ml.MEDFileUMesh()
74 meshMEDFile.setMeshAtLevel(0,targetMesh)
75 meshMEDFile.setMeshAtLevel(-1,targetMesh1)
76 meshMEDFile.write("TargetMesh2.med",2) # 2 stands for 'write from scratch'
78 Lecture, écriture de groupes de mailles
79 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81 Créons deux groupes de cellules sur le maillage 2D, c'est à dire au niveau relatif 0 (ici, le niveau relatif 0 correspond
83 correspond à la 1D, etc ...). Le premier groupe ``grp0_Lev0`` contient les cellules [0,1,3]
84 le second ``grp1_Lev0`` les cellules [1,2,3,4] : ::
86 grp0_0 = ml.DataArrayInt([0,1,3])
87 grp0_0.setName("grp0_Lev0")
88 grp1_0 = ml.DataArrayInt([1,2,3,4])
89 grp1_0.setName("grp1_Lev0")
90 meshMEDFile.setGroupsAtLevel(0, [grp0_0,grp1_0])
92 .. note:: On voit évidemment ici l'importance de nommer les tableaux : c'est le nom qui sera utilisé pour le groupe.
94 Créons trois groupes de niveau -1, c'est à dire des groupes de faces. Le premier appelé
95 ``grp0_LevM1`` aux cellules [0,1], le second appelé ``grp1_LevM1`` aux cellules [0,1,2], et le 3ème ``grp2_LevM1``
96 aux cellules [1,2,3] : ::
98 grp0_M1 = ml.DataArrayInt([0,1])
99 grp0_M1.setName("grp0_LevM1")
100 grp1_M1 = ml.DataArrayInt([0,1,2])
101 grp1_M1.setName("grp1_LevM1")
102 grp2_M1 = ml.DataArrayInt([1,2,3])
103 grp2_M1.setName("grp2_LevM1")
104 meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1])
106 Ecrivons le tout : ::
108 meshMEDFile.write("TargetMesh2.med",2) # 2 stands for 'write from scratch'
110 Nous pouvons ensuite re-lire le fichier MED : ::
112 meshMEDFileRead = ml.MEDFileMesh.New("TargetMesh2.med") # a new is needed because it returns a MEDFileUMesh (MEDFileMesh is abstract)
113 meshRead0 = meshMEDFileRead.getMeshAtLevel(0)
114 meshRead1 = meshMEDFileRead.getMeshAtLevel(-1)
115 print "Is level 0 in the file equal to 'targetMesh'?", meshRead0.isEqual(targetMesh,1e-12)
116 print "Is level 0 in the file equal to 'targetMesh1'?", meshRead1.isEqual(targetMesh1,1e-12)
118 Affichons les niveaux disponibles pour le groupe ``grp0_Lev0`` : ::
120 print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0")
122 Et récupérons enfin les identifiants de cellules contenus dans le groupe ``grp0_Lev0`` : ::
124 grp0_0_read = meshMEDFileRead.getGroupArr(0,"grp0_Lev0")
125 print "Is group 'grp0_Lev0' equal to what is read in the file?" , grp0_0_read.isEqual(grp0_0)
127 Lire/écrire des champs avec l'API avancée
128 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130 Créons un champ de vecteurs simple, aux cellules (P0), avec un seul pas de temps, appelé ``f``. ::
132 f = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME)
134 f.setArray(targetMesh.getBarycenterAndOwner())
135 f.setMesh(targetMesh)
136 f.setName("AFieldName")
138 Stocker ``f`` dans un object ``MEDFileField1TS`` (un champ avec un seul pas de temps -- *one time-step, 1TS*)
139 pour préparer l'écriture MED ::
141 fMEDFile = ml.MEDFileField1TS()
142 fMEDFile.setFieldNoProfileSBT(f) # No profile desired on the field, Sort By Type
144 Ajouter le champ au fichier "TargetMesh2.med" ::
146 fMEDFile.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file
148 .. note:: Noter l'utilisation du 0 pour indiquer que nous désirons ajouter au fichier existant.
152 fMEDFileRead = ml.MEDFileField1TS("TargetMesh2.med",f.getName(),7,8)
153 fRead1 = fMEDFileRead.getFieldOnMeshAtLevel(ml.ON_CELLS,0,meshMEDFileRead) # Quickest way, not re-reading mesh in the file.
154 fRead2 = fMEDFileRead.getFieldAtLevel(ml.ON_CELLS,0) # Like above, but this time the mesh is read!
155 print "Does the field remain OK with the quick method?", fRead1.isEqual(f,1e-12,1e-12)
156 print "Does the field remain OK with the slow method?", fRead2.isEqual(f,1e-12,1e-12)
158 Lire/écrire un champ sur un "profil"
159 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161 Nous allons maintenant voir un concept avancé des fichiers MED, à savoir la possibilité d'écrire un champ sur seulement
162 une *partie* du maillage. La technique habituellement utilisée est plutôt de mettre des valeurs particulières (e.g. +infinity
163 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.
165 Le mode de fonctionnement avec les profils reste donc peu courant.
167 Construisons une réduction aux cellules [1,2,3] de ``f`` et appelons la ``fPart`` : ::
169 pfl = ml.DataArrayInt([1,2,3])
170 pfl.setName("My1stPfl")
171 fPart = f.buildSubPart(pfl)
172 fPart.setName("fPart")
174 La stocker dans la structure ``MEDFileField1TS`` et invoquer ``setFieldProfile()``. ::
176 fMEDFile2 = ml.MEDFileField1TS()
177 fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) # 0 is the relative level (here 0 means 2D)
178 fMEDFile2.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file
180 Lire le champ ``fPart`` du fichier "TargetMesh2.med" et les identifiants de cellules correspondant. ::
182 fMEDFileRead2 = ml.MEDFileField1TS("TargetMesh2.med",fPart.getName(),7,8)
183 fPartRead, pflRead = fMEDFileRead2.getFieldWithProfile(ml.ON_CELLS,0,meshMEDFileRead)
184 print "Is the partial field correclty read?", fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12)
185 print "Is the list of cell identifiers matching?", pflRead.isEqualWithoutConsideringStr(pfl)
190 :ref:`python_testMEDLoaderAdvancedAPI1_solution`