J'utilise PyOMO pour modéliser une réaction semi-discontinue.Inclure le temps en tant que variable explicite dans une contrainte dans un modèle Pyomo
Considérons un système d'ODE qui décrit un réacteur semi-discontinu où l'un des réactifs est alimenté à un débit volumique donné pour t1 unités de temps, la réaction se poursuit jusqu'à t fin, et évidemment t1 < t fin.
Pour spécifier l'arrêt dans le flux, je peux soit utiliser une règle conditionnelle (on suppose t1 = 3,5 * 60):
def _vol_flow_in_schedule(mod,t):
if t<=3.5*60:
return mod.vol_flow_in[t] == (12.3/1000)/(3.5*60)
else:
return mod.vol_flow_in[t] == 0
m1.vol_flow_in_schedule = Constraint(m1.time,rule=_vol_flow_in_schedule)
qui va créer une discontinuité (et mon modèle ne converge pas). Ce que je veux faire est d'utiliser une fonction sigmoïdale qui va faire passer le flux à zéro sans discontinuité.
Pour implémenter le sigmoïde, j'ai besoin de me référer à la variable de temps elle-même.
Le ci-dessous un code Matlab me donne le résultat que je veux:
t=[0:1:500];
acc=2; %Acceleration parameter, higher values yields sharper change.
time_of_step=3.5*60;
init_value = (12.3/1000)/(3.5*60);
end_value = 0;
sigmoidal=(init_value+(end_value-init_value)/2)...
+((end_value-init_value)/2)*atan((t-time_of_step)*acc)/atan(max(t));
Cette mise en œuvre doit cependant la variable temps explicitement dans la fonction. Comment puis-je accéder à la variable de temps à l'intérieur de la règle PyOMO? J'ai essayé le ci-dessous, mais je reçois un « ne peut pas traiter la composante scalaire « t_of_step » comme un tableau » Erreur:
m1.init_value = Param(initialize = (12.3/1000)/(3.5*60))
m1.end_value = Param(initialize = 0)
m1.t_of_step = Param(initialize = 210)
m1.acc = Param(initialize = 5)
.
.
def _vol_flow_sigmoidal (mod,t):
return mod.vol_flow_in[t] == (mod.init_value+(mod.end_value-mod.init_value)/2)+((mod.end_value-mod.init_value)/2)*atan((t-mod.t_of_step)*mod.acc)/atan(1500)
m1.vol_flow_sigmoidal = Constraint(m1.time,rule=_vol_flow_sigmoidal)
Espérons que je viens de décrire clearlyt ce que je suis après. Tous les conseils sont les bienvenus,
Merci! Sal
Merci John, je delcare m1.time comme un ensemble continu _m1.time = ContinuousSet (bounds = (0,1500)) - Je n'utilise pas numpy –
Ensuite, je suis plus confus. Avec 'm1.time = ContinuousSet (bounds = (0,1500))', je ne reçois aucune erreur (j'ai testé sur Pyomo 4.3.11388 et 4.4.1). Il y a 2 choses qui pourraient aider à diagnostiquer les choses: 1) la trace de pile complète que Python crache quand elle génère l'erreur, et 2) un exemple complet qui démontre l'erreur. – jsiirola
Je peux vous obtenir le fichier complet, email? –