Mémo
Upgrade de Metafor
(branche 2003_01_21 vers 2003_08_27)
Introduction
Pourquoi cet upgrade?
Difficultés rencontrées - tâches effectuées
Conclusions
Introduction
Cette page regroupe les infos concernant la mise à jour de Metafor
sur la version courante d'Oofelie
(Septembre 2003).
J'écris cette page principalement pour moi-même parce que je sais
que je pourrai ainsi m'y référer dans le futur. Je pense aussi
que ça sera très utile à tous les utilisateurs Oofelie
qui comptent développer des grandes extensions telles que Metafor pour
Oofelie (on sait jamais, ça peut arriver).
L'idéal serait que OE la lise et tienne compte de mes remarques qui
ont un but constructif. Comme dit Igor: "Tu ne scieras
point la branche sur laquelle tu es assis!" (Allélouïa). Ici,
je scie pas, je remarque les fissures, c'est différent (c'est comme l'autosécurité
avec les voitures). Pour rappel, je suis un des premiers défenseurs d'Oofelie
et j'encourage tout le monde à l'utiliser. J'ai bossé 12h par
jour depuis la création de la nouvelle branche pour effectuer ce boulot.
Je regrette cependant le peu d'objectivité d'OE envers son produit (ce
qui les fait passer pour des menteurs / naïfs / incompétants dès
la première inspection sérieuse des sources). Dommage.
Sur ces bonnes paroles, je m'en vais lancer la batterie de Metafor en un coup
dans l'interpréteur, il parait que ça va pas exploser :p
Pourquoi cet upgrade?
On pourrait se demander pourquoi on passe à la nouvelle version d'Oofelie
vu le peu de modifications (de fond) nous concernant. Voici les raisons:
- On aimerait garder contact avec OE.
- Beaucoup de modifications de forme ont été faites (création
d'un namespace pour les classes mathématiques).
- L'interpreteur a été partiellement débugué et
présente des nouvelles fonctionnalités intéressantes
(commande "else", passage des arguments "scalar"
par reference, etc).
- Simplification de la gestion des I_.
- Modification de la gestion des matériaux, des éléments
et des propriétés s'y rapportant. C'est fait de manière
(incroyablement) plus sale en interne mais ça permet d'éliminer
un élément ou un matériau en supprimant simplement du
projet le .cpp s'y rapportant
- Corrections de bugs divers (dans le sloan par noeud que j'avais programmé).
- Utilisation de Metis
possible (on va essayer).
Difficultés rencontrées - tâches effectuées
- La difficulté majeure a été d'adapter l'interface
des éléments, matériaux et propriétés associées.
- Les routines d'Igor sont très loin d'être finalisées
(complètement illisibles - est-ce volontaire? je ne sais pas).
- Le plus surprenant est la présence de cast implicites un peu
partout. En quelques mots, toutes les nouvelles classes d'Igor peuvent
se caster en plus ou moins n'importe quoi si bien que le typage est
très faible et que les erreurs se retrouvent non pas à
la compilation mais plutôt à l'exécution.
- Igor a également toujours la manie de commencer ses tableaux
à 1 et d'utiliser l'élément 0 pour une autre fonction.
Ceci est fait sans passer par une fonction si bien qu'on a du mal a comprendre
ce qui se passe au premier coup d'oeil.
- La grande erreur d'Igor a été de vouloir tout initialiser
dans les appels de constructeurs statiques. Ces constructeurs sont bien
sûr appelés dans une ordre aléatoire (quand ils sont
appelés... - c'est d'ailleurs un problème discuté
plus loin), ce qui rend la tâche très difficile. Ces objets
sont beaucoup trop gros et dépendent les uns des autres.
- Pour moi, il aurait été plus simple de se limiter, lors
de cette phase d'initialisation de variables statiques, à remplir
une liste de fonctions d'initialisation (d'éléments et de
matériaux). On pourrait alors ainsi contôler l'ordre d'initialisation
manuellement dans la routine Init_Static().
- Un exemple : à l'heure actuelle, si un élément
s'initialise avant une propriété d'élément
qu'il utilise; une propriété à moitié construite
est crée et celle-ci sera remplie lors de l'initialisation de celle-ci.
Imaginez le nombre de tests à utiliser (si vous y arrivez pas,
regardez la classe ValidCodeList)
- Certaines classes de Metafor sont maintenant dupliquées dans
Oofelie (le terme "dupliquées" n'est pas choisi
par hasard - cfr la fct GeneralSet::vectorSize() par exemple qui,
d'ailleurs, n'existe plus chez nous depuis le nettoyage)
- La solution choisie ici est d'utiliser les namespace pour s'en sortir.
Pour éviter des conflits dans le futur, le nom du namespace est
"mt + 3 lettres caractéristiques" (par exemple mtGeo
au lieu de oo_geo).
- Les fichiers ont dû être renommés pour ne pas avoir
de conflits lorsque les deux objets sont inclus dans le même fichier
.cpp. La règle définissant le nom de fichier
a donc dû être modifiée et nous avons choisi d'inclure
le namespace dans le nom de fichier. Par exemple, la classe Point
est vue de l'extérieur comme mtGeo::Point, déclarée
dans mtGeoPoint.h et implémentée dans mtGeoPoint.inl
et mtGeoPoint.cpp.
- Les classes I_ suivent la même règle et ont
dû être incluses dans le namespace pour la même raison
(ça conforte donc l'idée - abandonnée par OE mais
conservée par nous - que les répertoires i_ doivent
être des sous répertoires du répertoire d'une librairie).
Pour être cohérant avec la nouvelle règle de nom,
I_Point.cpp a été renommé mtGeoI_Point.cpp
puisqu'il implémente la classe mtGeo::I_Point).
- Les fichiers "patch" ont été modifiés
pour qu'ils interceptent mieux les appels de fonctions membres dans Oofelie.
Par exemple, la fonction I_::new_child_from_po() qui crée
un objet de bon type lorsqu'on lui passe un identifiant de Physet,
peut maintenant créer un mtGeo::Point si on a compilé
avec Metafor et un Point d'Oofelie sinon. La conséquence
directe est qu'il n'est plus possible d'utiliser la géométrie
Oofelie (dans l'interpréteur uniquement - puisqu'en compilé,
on peut se débrouiller avec les namespace) quand on a compilé
avec Metafor. A l'heure actuelle, ce n'est pas un problème. Dans
le futur, si certains développements OE pouvaient être utiles
(imaginons un mailleur par exemple), il serait simple de créer
un Adapter qui se chargerait de la conversion
des données. Ajoutons à ça que la tendance actuelle
des développements est de privilégier l'interpréteur
uniquement pour les opérations de pré/post processing (les
algorithmes interprétés vont bientôt être supprimés,
pour des raisons de vitesse d'exécution, de consomation mémoire
et de difficultés de synchronisation avec les versions compilées).
- Les variables statiques s'initialisent mal dans une librairie sous
Windows.
- Ca c'est plutot une (mauvaise) surprise puisque le but du travail d'Igor
sur les matériaux et les éléments était justement
de créer des librairies d'éléments et de matériaux.
Bref, c'est pas possible sans bidouiller avec le linker microsoft (ce
que je n'ai pas encore fait). Remarquons que ce n'est pas étonnant
puisque même le concept de librairie est foireux dans ce cas-ci:
les éléments pourront faire partie d'une vraie librairie
lorsque le kernel sera sous forme de librairie (ce qui est prévu...
certainement à la fin du mois prochain - faudra que je demande
à Igor).
- La solution est relativement simple: le répertoire oo_element
et oo_material d'Oofelie doit être déplacé
dans le projet Metafor. le plus simple est alors de ne pas compiler ces
répertoires sauf elorot.cpp qui est utilisé dans
le kernel pour "spinner all your elements").
- Problème de construction des matériaux possédant
une classe de base virtuelle.
- Ben oui, c'est pas bien expliqué dans le Stroustrup (1 page et
un exemple un peu débile) mais la construction d'une classe possédant
une base virtuelle n'est pas simple, surtout lorsque le constructeur de
la classe de base virtuelle n'a pas de constructeur sans argument. Les
modifications de constructeurs ont été effectuées
dans tous les éléments et matériaux.
- Les classes Hardening/HardeningSet, couper-coller sauvage
de Material/Materset (on attend le template unifiant
les matériaux et éléments dans Oofelie), ne fonctionne
plus.
- J'ai recréé de nouvelles classes en m'appuyant sur Material.
- Des problèmes sont apparus suite au typage faible du code d'Igor
: vu que Material_Id est un typedef de int et que,
pour créer les classes similaires à MaterialType,
on utilise un typedef aussi (ElementType = typedef MaterialType),
on a des conflits dans la définitions des fonctions statiques (on
n'en a pas entre éléments et matériaux vu que Element_Id
est une enum). J'ai donc du créer une classe MaterialLaw_Id
(qui cache un bête int) et faire la chasse aux casts implicites
d'Igor.
- Les nouveaux matériaux ne sont plus des Physets
(raison inconnue)
- C'est plutot embetant puisque nous faisons des get_properties()
dans les Materiaux (pour des raisons d'efficacité principalement).
Le problème, c'est que OE n'a pas encore abordé ce sujet
et suppose que, chaque fois qu'on a besoin d'un paramètre, on va
le rechercher et qu'on l'évalue via un State. De plus,
si on veut avoir accès au pas de temps (dt), on a besoin de questionner
l'analyse vu que le State contient pas ça et donc de faire un get_properties()
qq part.
- Le MetaMaterial (classe de base des matériaux Metafor,
abandonnant l'interface Oofelie et ajoutant la notre) doit donc dériver
de Material (pour des raison de construction uniquement) mais
aussi Physet (pour ne pas donner raison aux défenseurs
du Fortran sur l'efficacité du C++).
- Solution trouvée: créer un nouveau Materset,
appelé MetaMaterialSet. Ce set permet est créé
en court-circuitant les appels exactement comme on l'a fait pour les objets
géométriques. Le Materset::define est devenu virtuel
et la nouvelle classe se charge de créer le lien manquant via un
cast contôlé.
- Modification du constructeur de Propelem
- Vu que le contôle des propriétés d'éléments
ne fonctionnaient pas avant, créer un Propelem s'accompagnait
souvent de l'identifiacteur ALL_ELEMENT. Cet identificateur
n'existe plus et il faut être plus précis (c'est pas plus
mal). Ca nécessite de modifier tous les fichiers .e
et z-mesh.
- La commande "q;" n'existe plus : manière
élégante de supprimer le bug de l'interpréteur: "int
q;" qui faisait sortir l'utilisateur d'Oofelie).
- La dénomination des éléments et matériaux
n'est pas uniforme: les éléments se voient attribuer
un suffixe _E alors que les éléments, non.
- J'ai redéfini la macro correspondante dans Metafor pour éviter
la création de ce suffixe (en suivant la règle de l'effort
minimal) qui n'apporte rien dans notre cas vu les chouettes noms d'éléments
qu'on a choisis (Tm2Volume2x2Gp3DMetaElement par exemple).
- Macro non portable.
- Les macros utilisées pour définir les éléments
et matériaux n'est pas portable (problèmes sous Linux) si
elle est utilisée pour des templates (j'ai dû la diviser
en 2 pour que le template soit instancié après la surdéfinition
des fonctions)
- La fonction solve a changé d'interface.
- Les commentaires à la Matlab "%" ont été
supprimés : ils ont été remplacés par
des commentaires du genre shell Unix "#".
- La version ne compilait et ne linkait plus sous Irix.
- Maintenant, elle compile mais ne linke toujours pas. En effet, des instanciations
de templates manquent dans les librairies.
- Mise à jour du projet et des Makefiles
- Mise à jour de la doc (merci à Ludo)
- ...
Conclusions
Cette mise à jour montre que:
- Travailler avec une branche est possible (c'était quand même
le premier essai et c'était pas gagné d'avance).
- Il faudrait se mettre à jour plus souvent. Ceci montre qu'une stratégie
de commit et upgrade plus régulière doit être mise en
place au service MCT. C'est faisable grâce au boulot de Pascal chez
OE concernant la vérification de la version courante.
Grâce à ce travail de mise à jour, nous pouvons continuer
à travailler "en collaboration" avec OE ([censure]). Je pense
que si nous n'avions pas fait cette mise à jour à l'heure actuelle,
nous aurions dû nous figer définitivement sur la version de Janvier
passé.
J'ai l'impression que la plupart des difficultés possibles ont été
rencontrées (je suis naïf, non?) et résolues puisque cette
mise à jour nous permet d'avoir des classes du même nom que celle
d'Oofelie (ou, plus généralement, les mêmes qu'une autre
librairie). Il est donc possible de:
- gérer d'éventuels conflits lorsque OE crée des classes
déjà existantes dans Metafor (cas de Point, PointSet,
... et I_ associés - mais certainement dans le futur Mesher,
Loading, RungeKutta, FourthOrderTensor, ...).
- créer des classes dérivées plus complètes que
celles d'Oofelie (cas de MetaMaterialSet, MetaElement,
MetaMaterial, ...).
Je terminerai ce mémo en parlant dans le vide (enfin, encore un peu
plus) en énonçant quelques trucs que OE pourrait faire pour améliorer
Oofelie (mis à part le PiezoElectroMecanoThermoFluidoElement que tout
le monde attend, surtout le .cpp) :
- Retravailler l'initialisation des classes matériaux et éléments.
- Supprimer les casts implicites et les trop gros objets (Lire à ce
sujet le bouquin de Refactoring
de Martin Fawler).
- Faire des libs (!)
- Corriger le bug suivant : "debug(8); status;" (bcp
trop de variables)
Ouf !
(C) RoBo September 4, 2003
__
Page modified on September 4, 2003