Rien

Rien
Nouvelles courbes
Généraliser les courbes n'était pas une chose facile:
en effet, Oofelie ne possède pas de système général
pour accéder de manière uniforme à l'ensemble des données.
Ainsi, accéder à un une valeur lissée, à une résultante,
à la base de donnée ou à une valeur globale (le temps par
exemple) demandent des mécanismes très différents.
Jusqu'à présent, nous utilisions la classe ToMatlab
(ancienne classe qui a été écrite très rapidement
au début de la migration vers le C++. ToMatlab a de nombreux
défauts. Par exemple:
- ToMatlab et Metafor ne sont pas indépendant.
Une certaine partie du travail est effectuée par meatfor, l'autre par
la classe ToMatlab.
- ToMatlab a entrainé la dégradation de l'enum smooth_type.
Cette enum, initialement utilisée pour désigner des valeurs
aux points de Gauss, a rapidement été étendue pour désigner
tout ce qui posait problème. Par exemple, smooth_type possède
des codes pour des valeurs aux noeuds, des valeurs de groupes et même
des valeurs globales non liées au maillage (énergie potentielle,
etc).
- ToMatlab n'utilise pas la géométrie.
- Il faut par utiliser le numéro de Positset lorsqu'on désigne
un noeud (pas facile à connaître).
- Les résultantes sont accessibles uniquement sur des groupes de noeuds.
Incompatible pour un futur remaillage en cours de calcul.
- Des résultantes partielles telles que les forces de contact sur les
matrices rigides sont inaccessibles.
- ToMatlab contient sa propre dénomination pour les grandeurs
exportées. Ces dénominations ne sont pas exportables dans une
autre partie du code.
- Il n'est pas possible de relire des courbes (pour faire un restart par exemple).
- Ces courbes ne sont pas visualisable dans VizWin.
- Introduire un nouveau type de donnée nécessite des modifications
profondes du code.
Pour corriger ces problèmes et obtenir un truc fiable (et surtout réutilisable),
j'ai essayé d'appliquer quelques patterns définis dans le bouquin
Design Patterns
de Gamma, un bouquin que tout le monde devrait lire.
- Création de la classe SmoothField : c'est un Singleton
permettant un accès unifié aux valeurs désignées
par l'enum smooth_type. La gestion est optimisée par une
hash table. SmoothField ne reprend évidemment pas les "faux"
smooth_fields tels que les valeurs de groupes (GR_*)
et les valeurs totales (TOT_*). Ces valeurs n'ont plus raison d'être
mais sont toujours présentes pour pouvoir utiliser l'ancien système
de courbes. Indispensable pour créer les noms de fichiers des courbes.
SmoothField est un outil indépendant du système de
courbes et pourra être utilisé ailleurs (par exemple pour désigner
des valeurs aux points de Gauss dans l'élément).
- Création d'une classe PhysetData : c'est un Singleton
permettant d'accéder globalement à l'ensemble des Physets.
Il est par exemple très simple de connaitre le nom d'un Physet
via son identifiant et inversement via cette classe. Indispensable pour créer
les noms de fichiers des courbes. Cette classe est tout à fait générale
et comble les lacunes du Brain d'Oofelie.
- Création de la classe LockData : idem à PhysetData
(Singleton), pour les Locks de base
(TX, TY, GF, ...). Cette classe permet, entre
autres, d'imprimer des Locks à l'écran. Ainsi la
Lock TX|GF|I2 s'affiche TX_GF_I2. Indispensable pour
créer les noms de fichiers des courbes. Cette classe est générale
et utilisable partout.
- Ajout de la classe VectorOnFile : c'est un std::vector
qui utilise le disque pour limiter sa consomation mémoire. Cela permet
donc la gestion de très grands vecteurs. Le format utilisé est
binaire. Une exportation ascii et matlab est utilisable. Cette classe est
concue selon de pattern Subject/Observer ; elle
peut donc informer d'autres classes lorsqu'elle modifie son état. C'est
essentiel pour la mise à jour de l'affichage (la classe Dr_MetaFunct
est un VectorOnFileObserver). Cette classe est indépendante
d'Oofelie (ce n'est même pas un Physet)
- Ajout de la classe ValueExtractor et dérivées
: permet un accès unifié aux données de Oofelie (et oui,
tout n'est pas dans la DB). le pattern utilisé ici est nommé
Command. L'utilisation se fait au travers de
l'interface de ValueExtractor via la fonction extract().
Citons les classes dérivées actuelles (pourra être enrichi
à l'infini) :
- ValueExtractor_db : extrait des données de la DB à
partir d'un objet géométrique ou non (accès direct).
si l'objet possède plusieurs entrées DB, une somme est faite
(résultante), si l'objet possède plusieurs composantes,
la résultante est vectorielle (norme vectorielle).
- ValueExtractor_int : extrait des données relatives aux
Interactions. Pour l'instant, résultante des forces
externes uniquement. Permet le calcul des forces de contact sur les matrices
rigides.
- ValueExtractor_misc : extrait des valeurs globales (temps,
pas de temps courant, nombre d'ités actuels, etc).
- Ajout de la classe ValuesManager : cette classe permet
de définir les courbes à calculer et se charge de les remplir
via la fonction fill_now(). C'est une Facade
pour l'utilisation des objets précedemment cités. Autrement
dit, l'utilisateur ne manipûle que cet unique objet pour créer
des courbes. Un objet de ce type est accessible dans l'analyse Metafor
via metafor.curves().
- Modification des algorithmes : meta_qs.e et
fin_step.e pour l'écriture des courbes.
Exemples:
Refer curves(metafor.curves()); |
crée une référence vers le ValuesManager
de Metafor. |
curves.define(1, NODE_PO, 5, TX|RE); |
courbe 1 = déplacement du noeud 5 |
curves.define(3, NODE_PO, 1, SMOOTH_EPL); |
courbe 3 = défo plastique lissée au noeud 1 |
curves.define_t(6); |
courbe 6 = le temps |
curves.define(5, CURVE_PO, 2, GF|TY|I2); |
courbe 5 = comp verticale de la force sur la ligne 2 |
curves.define(10, INTERACTION_PO, 1, TY); |
courbe 10 = force verticale sur la matrice de contact 1 |
curves.define(12, CURVE_PO, 2, GF|TX|TY|I2); |
courbe 12 = amplitude de la force sur la courbe 2 |
Les fichiers .v sont les fichiers binaires, les .m sont les fichiers matlab.
Visualisation des courbes
Pour visauliser les courbes, il fallait créer un objet "courbe"
et le drawable associé. Il fallait aussi étendre BWin
pour pouvoir configurer plusieurs fenêtres en même temps. Le nombre
de threads augmentant, il a fallu rendre plus robuste les interactions entre
ceux-ci.
Les modifs faites sont:
- Ajout d'une classe MetaFunct : permet de définir
l'abscisse et l'ordonnée à tracer. Il est possible de tracer
plusieurs courbes sur le même graphe.
- Ajout du drawable Dr_MetaFunct : permettant de tracer des
fonctions 2D dans VizWin.
- Ajout de la classe WinGeneric : classe mère de VizWin
et BWin regroupant les fonctions communes (open(), close(),
update())
- Utilisation des mutex et semaphores : pour la stabilisation
des threads graphiques. Les fonctions wait_init() ne sont plus
nécessaires. Les fenêtres devraient être plus rapides et
plus stables. Il reste cependant encore des cas où les fenêtres
graphiques plantent. Deux cas de plantage ont été observés
et ne sont pas encore résolus:
- Plantage Qt : provient certainement des appels à BWinDialogImpl::update()
dans les slots Qt de cette classe. Cette fonction de devrait jamais être
appelée en dehors de BWin.
- Plantage VTK : lors de la relecture de la cache des fontes
OpenGL.
- Modification de BWin pour paramétrer les DrawableMetaFunct
(onglet XYPlot)
- Modification de BWin pour gérer plusieurs fenêtres
VizWin : un onglet supplémentaire nommé "target"
permet de sécectionner la fenêtre courante. Il est possible d'ouvrir
une fenêtre BWin sans aucun VizWin et ajouter
des fenêtres par BWin::add(VizWin)
- Ajout de la classe PlotXYOptions : permettant de paramétrer
les courbes (structure contenant l'ensemble des paramètres et valeurs
par défaut).
- Modification de l'interface Drawable::get_actor() : pour
pouvoir gérer les vtkActor2D.
- Modification de la palette (VizPalette) : c'est maintenant
un Singleton gérant une std::map.
Résoud les problèmes d'initialisation. Permet de choisir les
couleurs d'affichage dans BWin.
Exemples :
MetaFunct gcurve1; |
création d'une MetaFunct |
gcurve1.set_ord(curves, 5, 10); |
courbe 5 comme ordonnée de la fonction numéro 10 (numéro
utilisateur au choix) |
gcurve1.set_abs(curves, 6, 10); |
courbe 6 comme abscisse de la fonction numéro 10 |
gcurve1.set_ord(curves, 8, 20); |
courbe 8 comme ordonnée de la fonction numéro 20 |
gcurve1.set_abs(curves, 6, 20); |
courbe 6 comme abscisse de la fonction numéro 20 |
VizWin winc; |
création d'une fenêtre |
winc.add(gcurve1); |
ajout de la MetaFunct à la fenêtre |
metafor.add_win(winc); |
ajout de la fenêtre à l'analyse |
|
|
MetaFunct gcurve2; |
création d'une fenêtre |
gcurve2.set_ord(curves, 8); |
courbe 8 comme ordonnée de la fonction |
gcurve2.set_abs(curves, 6); |
courbe 6 comme abscisse de la fonction |
VizWin winc2; |
création d'une fenêtre |
winc2.add(gcurve2); |
ajout de la MetaFunct à la fenêtre |
metafor.add_win(winc2); |
ajout de la fenêtre à l'analyse |
Remarques
Tout n'est pas parfait : voici les choses à ajouter dans la suite
- Ajouter les commandes d'écriture de courbes dans les algorithmes
autres que meta_qs.e
- Tester le restart
- Ecrire un script d'écriture de courbes à partir de metafacs
- Chargement de courbes au format ascii et matlab
- ...
Documentation "vulgarisée"
Une documentation pour utilisateur est disponible dans la doc officielle de
Metafor sur ce même site : doc courbes.
(C) RoBo 2003