Je souhaite instancier un modèle complexe en tant que paramètre dans un autre modèle et l'initialiser dans la section d'équation initiale, comme je peux le faire avec n'importe quel paramètre Real. Pour un simple paramètre Real, j'écrirais simplement
class FixedTests.RefactoredFlatModel parameter Real x = 4.0; parameter Real y(fixed = false); Real z; parameter Real mStatic.x(fixed = false); parameter Real mStatic.y(fixed = false); Real mDynamic.x(fixed = false); Real mDynamic.y(fixed = false); initial equation mStatic.x = x; y = mStatic.y; equation mStatic.y ^ 2.0 = mStatic.x; mDynamic.y ^ 2.0 = mDynamic.x; mDynamic.x = 4.0 * x; z = mDynamic.y; end FixedTests.RefactoredFlatModel;
indiquant que y
doit être calculé au moment de l'initialisation en utilisant les équations initiales (à définir ...). Mais je ne peux pas faire cela pour un modèle complexe, c'est-à-dire que
model RefactoredFlatModel parameter Real x = 4; parameter Real y(fixed = false); Real z; parameter ComplexModel mStatic; ComplexModel mDynamic; initial equation mStatic.x = x; y = mStatic.y; equation mDynamic.x = 4*x; z = mDynamic.y; end RefactoredFlatModel;
ne compile pas. Prenons par exemple le modèle plat suivant
model ComplexModel Real x(fixed = false); Real y(fixed = false); equation y * y = x; end ComplexModel;
Ici la solution implicite y = 2 est calculée au moment de l'initialisation alors que la solution z = 4 est calculée de manière dépendante du temps (au moins en principe, malgré les optimisations possibles ...). Mais les deux représentent fondamentalement la même relation quadratique, donc je veux encapsuler cette équation dans un modèle séparé (notez que tous ces systèmes d'équations ne sont pas aussi simples que dans cet exemple):
model FlatModel parameter Real x = 4; parameter Real y(fixed = false); Real z; // ... + many other model elements initial equation y*y = x; // ... + many other equations equation z*z = 4*x; end FlatModel;
et essayez de l'utiliser de cette façon:
parameter ComplexModel m(fixed = true);
Mais cela ne semble pas fonctionner (le compilateur signale un système overdermined). La vérification du modèle aplati par le compilateur montre pourquoi:
parameter Real y(fixed = true);
Donc mStatic.y ^ 2.0 = mStatic.x
est mis à (dépendant du temps) section d'équation au lieu de la section d'équation initiale, où je voulais qu'elle soit. Il est clair que le modèle est surdéterminé car il essaie de résoudre mStatic.y dans le temps bien que mStatic.y soit un paramètre et donc invariant dans le temps.
Existe-t-il un moyen de dire au compilateur modelica équations en équations initiales pour les instances de paramètres? Car sinon, il n'est pas possible de définir implicitement des instances de paramètres de modèles complexes.
3 Réponses :
Modifier (30/02/2019): N'utilisez pas cette "solution". Selon la réponse de tbeu, cela enfreint la norme linguistique. OpenModelica le permet, mais il ne devrait pas.
J'ai enfin trouvé une solution partielle. Si je déclare ComplexModel
en utilisant des conditions dans les sections équation initiale
et équation
, je peux le faire fonctionner - en quelque sorte.
class AdvancedMultiBody.FixedTests.RefactoredFlatModel parameter Real x = 4.0; parameter Real y(fixed = false); Real z; parameter Boolean mStatic.fixed = false; parameter Real mStatic.x(fixed = false); parameter Real mStatic.y(fixed = false); parameter Boolean mDynamic.fixed = true; Real mDynamic.x(fixed = false); Real mDynamic.y(fixed = false); initial equation mStatic.y ^ 2.0 = mStatic.x; mStatic.x = x; y = mStatic.y; equation mDynamic.y ^ 2.0 = mDynamic.x; mDynamic.x = 4.0 * x; z = mDynamic.y; end AdvancedMultiBody.FixedTests.RefactoredFlatModel;
En remplaçant dans le modèle RefactoredFlatModel
(de la question) la ligne
parameter ComplexModel mStatic (fixed = false);
par
XXX
le modèle plat résultant devient finalement
parameter ComplexModel mStatic;
ie J'ai jonglé avec succès entre l'équation de mStatic.y
et la section équation initiale
d'une manière qui peut être contrôlée de l'extérieur. La bonne chose est que le ComplexModel est maintenant entièrement encapsulé et peut être assigné à l'attribut fixed = false, comme demandé dans ma question.
Le problème est que je dois écrire l'équation sous-jacente y * y = x
deux fois dans ComplexModel
. Dans le cas de systèmes d'équations plus sophistiqués, cela pourrait être une source d'erreur. Et: je pense que la syntaxe pourrait être abusée si quelqu'un écrit fixed = false
pour une instance sans paramètre de ComplexModel (fait disparaître l'équation dépendant du temps, ce qui est assez différent de ce que fixed = false signifie pour atomic types de données).
D'une manière ou d'une autre, j'aurais aimé qu'il y ait une fonctionnalité de langage qui fasse tout cela automatiquement et systématiquement, mais il ne semble pas y en avoir.
Depuis la spécification Modelica v3.4, ce n'est pas Modelica, car le préfixe paramètre
ne doit pas être utilisé avec la classe spécialisée model
.
Il existe des propositions pour améliorer ce comportement (et répondre à vos besoins), voir https: / /github.com/modelica/ModelicaSpecification/issues/2311 et sa source https: / /github.com/modelica/ModelicaStandardLibrary/issues/1860 .
Êtes-vous en train de dire que l'instauration de modèles en tant que paramètres est illégale en général (indépendamment d'un attribut hypothétique «fixe»)? Ensuite, je trouve assez déroutant qu'OpenModelica (comme l'implémentation de référence pour ainsi dire) le permette.
Et si vous me permettez ce petit reproche: il est difficile de comprendre, pourquoi vous pouvez parfaitement exprimer un concept assez basique (résoudre un système statique d'équations) parfaitement bien en flat modelica (l'existence et l'unicité de solutions statiques non linéaires est un problème, mais il est également en flat modelica), mais vous ne pouvez pas y utiliser l'orientation objet. C'est comme si Modelica n'était allé qu'à mi-chemin vers l'orientation objet.
Oui, il est illégal Modelica et doit être rejeté par OpenModelica.
Le code que vous avez suggéré dans votre question fonctionne presque. Il vous suffit d'omettre le préfixe de paramètre pour mStatic et d'affecter ses variables dans la section d'équation régulière.
model RefactoredFlatModel parameter Real x=4; parameter Real y(fixed=false); Real z; ComplexModel mStatic; ComplexModel mDynamic; initial equation y = mStatic.y; equation // The assignment is needed to have enough equations, even though its static mStatic.x = x; mDynamic.x = 4*x; z = mDynamic.y; end RefactoredFlatModel;
Les paramètres peuvent également être affectés dans les sections d'équations initiales à partir de variables régulières. Vous n'avez donc pas besoin du préfixe de paramètre pour le modèle mStatic.
Cependant, les équations de mStatic doivent également être définies dans la section de temps continu, nous devons donc déplacer l'équation mStatic.x = x
vers la section d'équation.
l'intention derrière l'utilisation du préfixe de paramètre sur la variable était de permettre à l'interface utilisateur d'afficher la variable dans la boîte de dialogue de paramétrage. Lorsque vous travaillez uniquement avec des modèles textuels, cela peut sembler hors de propos, mais pour moi, c'est important. Je ne sais pas si votre proposition fonctionne ou non ...
Vous voulez donc afficher ComplexModel mStatic dans l'interface graphique? Vous pouvez provoquer cela en ajoutant une annotation (Dialog)
(mais dans OpenModelica ce n'est pas d'une grande utilité, car il ne montre qu'une zone de texte pour cela. Dans Dymola, vous obtenez un sous-menu pour définir tout ses paramètres). Ou souhaitez-vous simplement transmettre des paramètres à mStatic? Vous pouvez le faire comme toujours.