WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

ODE solver - jede 6. min Wert benötigt

 

RomanBT
Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 02.11.14
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 13.03.2015, 16:03     Titel: ODE solver - jede 6. min Wert benötigt
  Antworten mit Zitat      
Hallo,
ich möchte diverse ODE's lösen und brauche zu jeder 6. Minute eine Lösung. Ich brauche diese Lösung während der Iteration, da mit der Lösung im gleichen ode Function-File weitergerechnet wird. Deswegen ist eine spätere Interpolation der Daten nicht möglich.
Ich dachte ich könnte über odeset events definieren. Leider hab ich noch nie mit events gearbeitet und das ganze funktioniert nicht.

Code:
%% Simulation

Glycerol_odefun = @(t,x) Glycerol_mod (t, x, pk, 1);
options = odeset('Events',@(t,x)event(t,x));
[tsim, xsim, te, xe, ie] = ode45(Glycerol_odefun, ti, x0, options);
 


Code:
function [value,isterminal,direction] = event(t,x)
% value = eval(sprintf('%.4f',sin(pi*t/0.1)));
value = floor(t/0.1)-t/0.1
isterminal = 0;
direction = 0;
end
 


Ich hatte erst versucht über einen sinus(pi*t/0.1) alle 6 min (0.1h) einen Iterationswert zu erhalten. Zu Beginn klappt das nicht gegen Ende der Zeit erfolgt tatsächlich zu jeder 6 min eine Iteration.
Die zweite Variante mit value = floor(t/0.1)-t/0.1 funktioniert noch weniger.

Ist das was ich machen möchte über events überhaupt möglich? Was mache ich falsch?

Gibt es vielleicht eine einfachere/bessere Methode für mein Problem?

Wie gesagt, ich brauch den Wert alle 6 Minuten. Nach 6 Minuten jeweils abzuwarten bis ein neuer Wert geschreiben wird geht leider auch nicht. Dann hätte ich z.B. Werte bei 6,02 oder 6,4 oder 7 min.

Danke schon mal für eure Hilfe.
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 13.03.2015, 17:50     Titel:
  Antworten mit Zitat      
Hallo,

wäre es in dem Fall eine Alternative, in einer Schleife immer jeweils 6 Minuten zu simulieren?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
RomanBT
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 02.11.14
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 13.03.2015, 21:18     Titel:
  Antworten mit Zitat      
Hey,

das hab ich noch nie gemacht. Ich könnte es versuchen, aber auf den ersten Blick finde ich das relativ kompliziert. Ich denke die Umsetzung ist nicht so schwer, aber ich habe Bedenken, dass ich mir so nur noch weitere Baustellen schaufel.

Bin ich den mit events über odeset ganz auf dem falschen Weg? Ich hatte es eig so verstanden, dass man damit verhindert, dass der solver auf Grund der Schrittweise über ein Event hinweg läuft. Mein Event wäre eben einfach jede 6. Minute. Ansatzweise hatte ich das ja mittels Sinus hin bekommen. Ich hatte gehofft nur die events Funktion nicht ganz richtig verwendet oder verstanden zu haben.

Gruß
Roman
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 13.03.2015, 22:24     Titel:
  Antworten mit Zitat      
Hallo,

deine Beschreibungen wie "funktioniert nicht" und "funktioniert nicht weniger" sind leider nicht hilfreich.
Je genauer du beschreibst, was du machst und warum es nicht funktioniert, desto eher kann man dir helfen.
Was ist denn die Grundeinheit deiner Zeitskala?
Wie genau verwendest du den Wert zu jeder 6. Minute denn in der Funktion?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
RomanBT
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 02.11.14
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 14.03.2015, 21:23     Titel:
  Antworten mit Zitat      
Hey,

sorry wenn ich nicht so präzise war.
Ich poste erstmal nochmal den gesamten Code, ich weiß nicht obs nötig ist, aber bei Bedarf hat man ihn dann:

Code:
%% Clear the workspace, close the figures, clear the command window

clear all;
close all;
clc;

%% Define Parameters, time range and initial values

pk(1)  = 0.23;     % µmax   [1/h]
pk(2)  = 0.65;     % yX/S   [-]
pk(3)  = 0.02;     % qX/Xm  [1/h]
pk(4)  = 0.1;      % FRop   [l/h]
pk(5)  = 0.080;    % FRmax  [l/h]
pk(6)  = 0;        % FRmin  [l/h]
pk(7)  = 995;      % cSR1   [g/l]
pk(8)  = 10;       % KR     [l/h]
pk(9)  = 0.02;     % TI     [h]
pk(10) = 1;        % TD     [h]
pk(11) = 10;       % VLmin  [l]
pk(12) = 0.1;      % delta t raman [h]
pk(13) = 10;       % cSLw   [g/l]
pk(14) = 0.134;    % kS     [g/l]

pk(31) = 0;       % t0     [h]
pk(32) = 15;      % tend   [h]
pk(33) = 2000;     % Anzahl berechneter Werte
pk(34) = (pk(32) - pk(31))/pk(33); % Stepwidth

% Zeitvektor
ti    = pk(31):pk(34):pk(32);

x0(1) = 2;        % cXL0   [g/l]
x0(2) = 20;       % cSL0   [g/l]
x0(3) = 10;       % VL0    [l]
x0(4) = 0;        % yI0    [l/(hh)]


%% Simulation

Glycerol_odefun = @(t,x) Glycerol_mod (t, x, pk, 1);
options = odeset('Events',@(t,x)event(t,x));
[tsim, xsim, te, xe, ie] = ode45(Glycerol_odefun, ti, x0, options);

for i=1:length(tsim)
    ysim(i,:) = Glycerol_mod (tsim(i,1), xsim(i,:), pk, 2);
end

display ('create plot...')

hold on
plot(tsim,xsim(:,1),'k-')
plot(tsim,xsim(:,2),'g-')
plot(tsim,ysim(:,3),'c:')
plot(tsim,ysim(:,9)*100,'r-')
plot(tsim,xsim(:,3),'b-')

legend('c_{XL}(t)','c_{SL}(t)','c_{SLraman}(t)','F_R(t)','V_L(t)','Location','NorthEast');
axis([tsim(1) tsim(end) -5 40]);
xlabel ('t [min]')
ylabel ('c_{XL}, c_{SL}, c_{SLraman}')
grid on;
 


Function file für ode:

Code:

function out = Glycerol_mod (t, x, p, flag)

%qX/X(t) = µmax * cSL(t) / (kS  + cSL(t))
y(1)     = p(1) * x(2)   / (p(14) + x(2)) ;

%qS/X(t) = qX/X(t) / yX/S
y(2)     = y(1)    / p(2);

%cSLraman = cSL(t%6=0) = x(t)
% hier soll später alle 6 min der Wert übergeben werden. Über global würde ich diese dann bis zur nächsten Übergaben speichern

% cSLw(t)=w(t)
y(4) = p(13);

%Vergleichsstelle
%e(t) = w(t)  - x(t)
y(5) = y(4) - y(3);

% P-Anteil
%yP(t) = KR   * e(t)
y(6)   = p(8)* y(5);

% PI
% y(t)  = yP(t) + yI(t)
y(7)    = y(6) + x(4);
 
% % PID
% y(Cool =

%FR soll falls außerhalb seiner Grenzen auf min bzw. max gesetzt werden
% FR(t) = y(t);
y(9)    = y(7);
if y(7)<=p(6);
y(9)    = p(6);
elseif y(7)>=p(5)
    y(9)=p(5);
end

%%Differantial equations

% cXL.(t) = (qX/X(t) - FR(t)/VL(t)) * cXL(t)
  dx(1)   = (y(1)    - y(9) /x(3))  * x(1);
 
% cSL.(t) = FR(t)/VL(t) * (cSR1 - cSL(t)) - qS/X(t) * cXL(t)
  dx(2)   = y(9) /x(3)  * (p(7) - x(2)  ) - y(2)    * x(1);
 
  % wenn cSL negativ ist und die Änderung von cSL negativ ist
  if x(2) <= 0 && dx(2)<0
  % dann soll die Änderung von cSL Null sein
     dx(2)= 0;
   end
 
% VL.(t)  = FR(t)
  dx(3)   = y(9);
 
% I-Anteil  
% Wenn die Stellgröße inerhalb der Grenzen für FR
if p(6)<= (y(6) + x(4)) && y(6) + x(4) <= p(5)

% dann soll der I Anteil berechnet werden    
% yI.(t)  = KR   /TI   * e(t)
  dx(4)   = p(8) /p(9) * y(5);

%ansonsten wird der I Anteil ausgestellt
else
    dx(4)=0;
end
 
  if flag==1
    out = dx';
  elseif flag==2
      out=y;
  end
end


Der programmierte PI Regelalgorithmus ist noch nicht fertig/richtig. Ist aber für mein momentanes Problem auch nicht wichtig denke ich.

Hier das function file für events bei odeset:

Code:
function [value,isterminal,direction] = event(t,x)
%value = floor(t/0.1)-t/0.1
value = eval(sprintf('%.4f',sin(pi*t/0.2)));
isterminal = 0;
direction = 0;
end
 


value = floor(t/0.1)-t/0.1 führt dazu das nur zu 2 Zeitevents auch eine Iteration sattfindet: te = [ 5,55111512312578e-17; 15 ]
Mit werden mehr Events erkannt, jedoch auch nicht alle und die meisten doppelt: te = [1,59154943160541e-06; 0,299998408450586; 0,300001591549439; 1,99999840845057; 2,00000159154945; 3,49999840845062; 3,50000159154952; ...; 14,0000015915496; 14,8999984084507]

Bzw. stelle ich momentan fest, das in dem Vektor te zwar glatte Zahlen (z.B. 0,3000) angezeigt werden, jedoch aber eig Zeiten kurz bzw nach z.B. 0,3 gespeichert werden. Vielleicht bekommt Matlab die glatten Zahlen nicht hin. Hab ich erst jetzt festgestellt, dass nach Kopieren Einfügen die 0,3000 zur 0,299998408450586 wird.

Ich hoffe damit ist klar was ich mache.
Zeiteinheit ist Stunden. Das heißt die 6. Minute ist die 0.1 Stunde.
Der Wert der dann jede 6. Minute iteriert wird (bzw werden soll) soll dann in einer globaelen Variablen gespeichert werden und dann 6 Minuten lang verwendet werden. Dann käme der nächste Wert.

Um ganz genau zu sein, geht es um eine Simulation einer Konzentrationsregelung. Die Messung liefert aber nur alle 6 Minuten einen Wert der Konzentration.

Schönen Gruß
Roman
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 14.03.2015, 22:15     Titel:
  Antworten mit Zitat      
Hallo,

das gewünschte klappt bei mir mit:
Code:
options = odeset('Events',@(t,x)event(t,x), 'MaxStep', 0.1);


Eventfunktion:
Code:
value = sign( round(t*5)-t*5 );


Zitat:
Der Wert der dann jede 6. Minute iteriert wird (bzw werden soll) soll dann in einer globaelen Variablen gespeichert werden

Globale Variablen würde ich grundsätzlich vermeiden. Ich glaube, dass mein Vorschlag, die Simulation alle 6 Minuten neu zu starten, deutlich leichter umzusetzen und zu debuggen wäre und zudem übersichtlicher.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
RomanBT
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 02.11.14
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 16.03.2015, 09:52     Titel:
  Antworten mit Zitat      
Hey,
vielen Dank für deine Hilfe.
Wahrscheinlich hast du recht und die Lösung per Schleife ist die beste Möglichkeit. Ich werde das mal versuchen.

Wieso sollte man globale Variablen möglichst vermeiden?

Gruß
Roman
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 16.03.2015, 10:06     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Wieso sollte man globale Variablen möglichst vermeiden?

Weil so die Trennung der Workspaces umgangen wird und der Code somit schwer nachvollziehbar und zu debuggen ist. Siehe z.B. hier:
http://blogs.mathworks.com/videos/2.....actices-that-make-me-cry/

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
RomanBT
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 8
Anmeldedatum: 02.11.14
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 16.03.2015, 14:58     Titel:
  Antworten mit Zitat      
Die Programmierung mit Schleife funktioniert. Vielen Dank.

Code:
%% Simulation

% Ergebnismatritzen
tsim=[];
xsim=[];
ysim=[];

%   i = 1:tend  /delta t
for i = 1:pk(32)/pk(12)

% Zeitvektor mit länge delta t    
ti = [(i-1)*pk(12), i*pk(12)];

% cSLrman
pk(15) = x0(2);

% Ode Solver Aufruf
Glycerol_odefun = @(t,x) Glycerol_mod (t, x, pk, 1);
[tsimi, xsimi] = ode45(Glycerol_odefun, ti, x0);

% Algebraische Ergebnisse
for n=1:length(tsimi)
    ysimi(n,:) = Glycerol_mod (tsimi(n,1), xsimi(n,:), pk, 2);
end

% Startwerte für ode Solver ändern sich für jeden Schleifendurchgang und
% werden neu übergeben
x0(1) = xsimi(end,1);       % cXL0   [g/l]
x0(2) = xsimi(end,2);       % cSL0   [g/l]
x0(3) = xsimi(end,3);       % VL0    [l]
x0(4) = xsimi(end,4);       % yI0    [l/(hh)]

% Für alle Schleifendurchgänge außer dem letzten wird die unterste
% Ergebniszeile gelöscht
if i<pk(32)/pk(12)
tsimi(end)=[];
xsimi(end,:)=[];
ysimi(end,:)=[];
end

% gesamte Ergebnismatritzen
tsim = [tsim; tsimi];
xsim = [xsim; xsimi];
ysim = [ysim; ysimi];

% Hilfsmatritzen müssen nach jedem Durchgang geleert werden da deren größen
% variabel sind
tsimi=[];
xsimi=[];
ysimi=[];

end


Vielleicht ist der Code auch mal für jmd. hilfreich der ein ähnliches Problem hat.

Gruß Roman
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.