Lecture, Êcriture d'un fichier MED grâce à l'API avancÊe de MEDLoader --------------------------------------------------------------------- L'API avancÊe de MEDLoader est reprÊsentÊe par les classes ``MEDFile*`` de la bibliothèque MEDLoader. * Au plus haut niveau, pour l'ensemble du fichier: ``MEDFileData``, * Pour l'ensemble des maillages du fichier : ``MEDFileMeshes``, * Pour chacun des maillages : ``MEDFileMeshMultiTS``, ``MEDFileMesh``, ``MEDFileUMesh``, ``MEDFileCMesh``, * Pour l'ensemble des champs du fichier : ``MEDFileFields``, ``MEDFileFieldGlobs``, * Et enfin pour chacun des champs : ``MEDFileField1TS``, ``MEDFileFieldMultiTS`` Objectif ~~~~~~~~ Ecrire un maillage et un champ à partir de rien, les relire et comparer les rÊsultats. Points abordÊs : en utilisant l'API avancÊe de MEDLoader, * Ecrire un fichier * Lire un fichier DÊbut d'implÊmentation ~~~~~~~~~~~~~~~~~~~~~~ Cet exercice repose comme tous les autres sur le language de script Python. On charge le module Python ``MEDLoader``. Pour information, le module ``MEDCoupling`` complet est inclus dans ``MEDLoader``. Pas besoin de l'importer si ``MEDLoader`` a ÊtÊ chargÊ. :: import MEDLoader as ml Lecture, Êcriture d'un maillage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nous crÊons tout d'abord le même maillage ``targetMesh`` que pour l'API simple. :: 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 ] targetConn = [0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] targetMesh = ml.MEDCouplingUMesh("MyMesh",2) targetMesh.allocateCells(5) targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[4:7]) targetMesh.insertNextCell(ml.NORM_TRI3,3,targetConn[7:10]) targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[0:4]) targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[10:14]) targetMesh.insertNextCell(ml.NORM_QUAD4,4,targetConn[14:18]) myCoords = ml.DataArrayDouble(targetCoords,9,2) myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) targetMesh.setCoords(myCoords) .. note:: Le maillage ``targetMesh`` est ordonnÊ par type gÊomÊtrique. Nous construisons ensuite ``targetMesh1`` reprÊsentant les sous-constituants (*faces*) du maillage ``targetMesh``, et nous en extrayons seulement les cellules (donc ici des surfaces) [3,4,7,8]. Pour plus de dÊtails sur la connectivitÊ descendante, consulter la section :ref:`exo-umesh-desc-connec` du deuxième exercise. Cet ensemble peut par exemple reprÊsenter un ensemble d'intÊrêt pour un calcul : :: targetMeshConsti, _, _, _, _ = targetMesh.buildDescendingConnectivity() targetMesh1 = targetMeshConsti[[3,4,7,8]] targetMesh1.setName(targetMesh.getName()) .. note:: En Python, le underscore ``_`` signifie que l'on attend une valeur de retour, mais qu'on n'en aura pas l'usage (on ne la *bind* pas). .. note:: ``targetMesh1`` sera sauvÊ comme Êtant une partie du même maillage global dans le fichier MED. 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. On peut alors Êcrire les deux maillages dans le fichier "TargetMesh2.med". :: meshMEDFile = ml.MEDFileUMesh() meshMEDFile.setMeshAtLevel(0,targetMesh) meshMEDFile.setMeshAtLevel(-1,targetMesh1) meshMEDFile.write("TargetMesh2.med",2) # 2 stands for 'write from scratch' Lecture, Êcriture de groupes de mailles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CrÊons deux groupes de cellules sur le maillage 2D, c'est à dire au niveau relatif 0 (ici, le niveau relatif 0 correspond à la 2D, le niveau -1 correspond à la 1D, etc ...). Le premier groupe ``grp0_Lev0`` contient les cellules [0,1,3] le second ``grp1_Lev0`` les cellules [1,2,3,4] : :: grp0_0 = ml.DataArrayInt([0,1,3]) grp0_0.setName("grp0_Lev0") grp1_0 = ml.DataArrayInt([1,2,3,4]) grp1_0.setName("grp1_Lev0") meshMEDFile.setGroupsAtLevel(0, [grp0_0,grp1_0]) .. note:: On voit Êvidemment ici l'importance de nommer les tableaux : c'est le nom qui sera utilisÊ pour le groupe. CrÊons trois groupes de niveau -1, c'est à dire des groupes de faces. Le premier appelÊ ``grp0_LevM1`` aux cellules [0,1], le second appelÊ ``grp1_LevM1`` aux cellules [0,1,2], et le 3ème ``grp2_LevM1`` aux cellules [1,2,3] : :: grp0_M1 = ml.DataArrayInt([0,1]) grp0_M1.setName("grp0_LevM1") grp1_M1 = ml.DataArrayInt([0,1,2]) grp1_M1.setName("grp1_LevM1") grp2_M1 = ml.DataArrayInt([1,2,3]) grp2_M1.setName("grp2_LevM1") meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) Ecrivons le tout : :: meshMEDFile.write("TargetMesh2.med",2) # 2 stands for 'write from scratch' Nous pouvons ensuite re-lire le fichier MED : :: meshMEDFileRead = ml.MEDFileMesh.New("TargetMesh2.med") # a new is needed because it returns a MEDFileUMesh (MEDFileMesh is abstract) meshRead0 = meshMEDFileRead.getMeshAtLevel(0) meshRead1 = meshMEDFileRead.getMeshAtLevel(-1) print "Is level 0 in the file equal to 'targetMesh'?", meshRead0.isEqual(targetMesh,1e-12) print "Is level 0 in the file equal to 'targetMesh1'?", meshRead1.isEqual(targetMesh1,1e-12) Affichons les niveaux disponibles pour le groupe ``grp0_Lev0`` : :: print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") Et rÊcupÊrons enfin les identifiants de cellules contenus dans le groupe ``grp0_Lev0`` : :: grp0_0_read = meshMEDFileRead.getGroupArr(0,"grp0_Lev0") print "Is group 'grp0_Lev0' equal to what is read in the file?" , grp0_0_read.isEqual(grp0_0) Lire/Êcrire des champs avec l'API avancÊe ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CrÊons un champ de vecteurs simple, aux cellules (P0), avec un seul pas de temps, appelÊ ``f``. :: f = ml.MEDCouplingFieldDouble(ml.ON_CELLS, ml.ONE_TIME) f.setTime(5.6,7,8) f.setArray(targetMesh.computeCellCenterOfMass()) f.setMesh(targetMesh) f.setName("AFieldName") Stocker ``f`` dans un object ``MEDFileField1TS`` (un champ avec un seul pas de temps -- *one time-step, 1TS*) pour prÊparer l'Êcriture MED :: fMEDFile = ml.MEDFileField1TS() fMEDFile.setFieldNoProfileSBT(f) # No profile desired on the field, Sort By Type Ajouter le champ au fichier "TargetMesh2.med" :: fMEDFile.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file .. note:: Noter l'utilisation du 0 pour indiquer que nous dÊsirons ajouter au fichier existant. Lire le champ : :: fMEDFileRead = ml.MEDFileField1TS("TargetMesh2.med",f.getName(),7,8) fRead1 = fMEDFileRead.getFieldOnMeshAtLevel(ml.ON_CELLS,0,meshMEDFileRead) # Quickest way, not re-reading mesh in the file. fRead2 = fMEDFileRead.getFieldAtLevel(ml.ON_CELLS,0) # Like above, but this time the mesh is read! print "Does the field remain OK with the quick method?", fRead1.isEqual(f,1e-12,1e-12) print "Does the field remain OK with the slow method?", fRead2.isEqual(f,1e-12,1e-12) Lire/Êcrire un champ sur un "profil" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Nous allons maintenant voir un concept avancÊ des fichiers MED, à savoir la possibilitÊ d'Êcrire un champ sur seulement une *partie* du maillage. La technique habituellement utilisÊe est plutôt de mettre des valeurs particulières (e.g. +infinity 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. Le mode de fonctionnement avec les profils reste donc peu courant. Construisons une rÊduction aux cellules [1,2,3] de ``f`` et appelons la ``fPart`` : :: pfl = ml.DataArrayInt([1,2,3]) pfl.setName("My1stPfl") fPart = f.buildSubPart(pfl) fPart.setName("fPart") La stocker dans la structure ``MEDFileField1TS`` et invoquer ``setFieldProfile()``. :: fMEDFile2 = ml.MEDFileField1TS() fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) # 0 is the relative level (here 0 means 2D) fMEDFile2.write("TargetMesh2.med",0) # 0 is paramount to indicate that we *append* (and no overwrite) to the MED file Lire le champ ``fPart`` du fichier "TargetMesh2.med" et les identifiants de cellules correspondant. :: fMEDFileRead2 = ml.MEDFileField1TS("TargetMesh2.med",fPart.getName(),7,8) fPartRead, pflRead = fMEDFileRead2.getFieldWithProfile(ml.ON_CELLS,0,meshMEDFileRead) print "Is the partial field correclty read?", fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) print "Is the list of cell identifiers matching?", pflRead.isEqualWithoutConsideringStr(pfl) Solution ~~~~~~~~ :ref:`python_testMEDLoaderAdvancedAPI1_solution`