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

Weiterrechnen mit einem Ergebnis innerhalb einer Schleife

 

eh27
Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 31.03.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 13.04.2016, 12:37     Titel: Weiterrechnen mit einem Ergebnis innerhalb einer Schleife
  Antworten mit Zitat      
Ich möchte gern das nach elseif der p_Z1(k) weiterberechnet wird mit dem letzten Wert aus dem elseif Bereich. Es soll also im else Bereich (Zeile 61) gelten:

p_Z1(k)=[das letzte Ergebnis aus der vorhergehenden elseif Schleife (Zeile 56) von p_Z1(k)]/((V_Z1(k)/V_max)^kappa);

Wie lässt sich das umsetzen?

Und gibt es für diesen Code allgemeine Verbesserungsvorschläge? Wenn ich diesen mit mehr als 50 oder 100 Arbeitsspielen rechne lasse wird ewig gerechnet, bei einem Test mit 1000 war der Speicher voll Sad



Das ist der aktuelle Code.
Code:

ainput=input(['\n\n Anzahl Arbeitsspiele']);
kolbenwegmax=2*pi*0.057;
b_Z1=0.03;
h_Z1=0.03;
A_kolben=b_Z1*h_Z1;
V_max=kolbenwegmax*A_kolben;
p_Umg=101325; %Umgebungsdruck in pascal
T_Umg=293.75; %Umgebungstemperatur in Kelvin
kappa=1.4;
c_p=1005; %
c_v=718; %
R=287; %

T_w=50; %50 Kelvin ist T_Wand erhöht
VE_Z1_offen=330; %Ventil Zylinder 1->2 auf
VE_Z1_zu=350; %Ventil Zylinder 1 zu
A_VE1=0.00005; % Ventilquerschnitt in m^2
dt=1/(6*2400*100); % dt=1/6n * 100 für 1/100°KW


if isempty(ainput)
    ainput=10;
end
alphai=0:0.01:(ainput*360);
kw = zeros(size(alphai));

for k = 1:numel(alphai)
    if alphai(k)>360
        kw_ungerundet=alphai(k)/360;
        kw(k)=alphai(k)-(floor(kw_ungerundet)*360);
        VE_Z1_o(k)=VE_Z1_offen+VE_Z1_offen*(floor(kw_ungerundet));
        VE_Z1_z(k)=VE_Z1_zu+VE_Z1_zu*(floor(kw_ungerundet));
    else
        kw(k)=alphai(k);
        VE_Z1_o(k)=VE_Z1_offen;
        VE_Z1_z(k)=VE_Z1_zu;
    end
    s_k(k)=kolbenwegmax*(kw(k)/360); %Kolbenweg
   
    if k > 32001
        s_k2(k)=(kolbenwegmax*((kw(k-32000))/360)); %Kolbenweg 2
    else
        s_k2(k)=0.5;
    end
    V_Z1(k)=A_kolben*(s_k(k)-kolbenwegmax)*(-1);
    V_Z2(k)=A_kolben*(s_k2(k));
   
    dV_Z1=-8.953539062722324e-09; %diff(V_Z1);
    dV_Z2=8.953539062722324e-09;
    if alphai(k)<VE_Z1_offen
        p_Z1(k)=p_Umg/((V_Z1(k)/V_max)^kappa);
        T_Z1(k)=T_Umg/((p_Umg/p_Z1(k))^((kappa-1)/kappa));
        p_Z2(k)=101325;
        T_Z2(k)=293.15;
    elseif alphai(k)>=VE_Z1_o(k) && alphai(k)<=VE_Z1_z(k)
        p_Z1(k)=p_Z1(k-1)+dp_Z1(k-1);  % Zeile 56
        T_Z1(k)=T_Z1(k-1)+dT_Z1(k-1);
        p_Z2(k)=p_Z2(k-1)+dp_Z2(k-1);
        T_Z2(k)=T_Z2(k-1)+dT_Z2(k-1);
    else
        p_Z1(k)=100000; % Zeile 61
        T_Z1(k)=800;
        p_Z2(k)=50000;
        T_Z2(k)=600;
    end
    pi_druck(k)=p_Z2(k)/p_Z1(k);
        if pi_druck(k)<0.52
           pi_druck(k)=0.52;
        end
    c_s(k)=sqrt(2*c_p*T_Z1(k)*(1-(pi_druck(k)^((kappa-1)/kappa)))); %Schallgeschwindigkeit
    rho_1(k)=p_Z1(k)/(T_Z1(k)*R); % Dichte 1
    rho_2(k)=p_Z2(k)/(T_Z2(k)*R); % Dichte 2
    rho(k)=rho_1(k)*(pi_druck(k)^(1/kappa)); %Dichte Strömung 1->2
    m1(k)=rho_1(k)*V_Z1(k); %Masse im Zylinder 1
    m2(k)=rho_2(k)*V_Z2(k); %Masse im Zylinder 2
    m_punkt(k)=c_s(k)*rho(k)*A_VE1;
    dW_Z1(k)=dV_Z1*p_Z1(k); %Volumenänderungsarbeit Z1
    dW_Z2(k)=dV_Z2*p_Z2(k); %Volumenänderungsarbeit Z2
    dm(k)=m_punkt(k)*dt; %Masseveränderung 1->2
    dH(k)=dm(k)*T_Z1(k)*c_p; %Enthalpieänderung
    alpha_w(k)=127.93*(0.03^(-0.2))*((p_Z1(k)*10^-5)^0.8)*(T_Z1(k)^(-0.53))*(41.408^.8);
    alpha_w2(k)=127.93*(0.03^(-0.2))*((p_Z2(k)*10^-5)^0.8)*(T_Z2(k)^(-0.53))*(41.408^.8);
    dQw_Z1(k)=(2*b_Z1*h_Z1+4*b_Z1*(kolbenwegmax-s_k(k)))*alpha_w(k)*(273.15+T_w-T_Z1(k))*dt; %Wandwärmeverluste
    dQw_Z2(k)=(2*b_Z1*h_Z1+4*b_Z1*(s_k2(k)))*alpha_w2(k)*(273.15+T_w-T_Z2(k))*dt; %Wandwärmeverluste
    dT_Z1(k)=-(dH(k)+(c_v*T_Z1(k)*(-dm(k)))+dW_Z1(k)-dQw_Z1(k))/(m1(k)*c_v); %Temperaturänderung
    dp_Z1(k)=((m1(k)*R*dT_Z1(k))+(R*T_Z1(k)*(-dm(k)))-dW_Z1(k))/V_Z1(k); %Druckänderung
    dT_Z2(k)=(dH(k)-(c_v*T_Z2(k)*dm(k))-dW_Z2(k)+dQw_Z2(k))/(m2(k)*c_v);
    dp_Z2(k)=((m2(k)*R*dT_Z2(k))+(R*T_Z2(k)*dm(k))-dW_Z2(k))/V_Z2(k); %Druckänderung
   
end
 
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 13.04.2016, 16:12     Titel: Re: Weiterrechnen mit einem Ergebnis innerhalb einer Schleif
  Antworten mit Zitat      
Hallo eh27,

Zitat:
Ich möchte gern das nach elseif der p_Z1(k) weiterberechnet wird mit dem letzten Wert aus dem elseif Bereich.

Es ist schwieirg die Frage im Detail nachvollziehen zu können. Vermutlich musst Du den letzten Wert einfach nur in einer Variablen speicherN: "temp = ..." und kannst sie dann wie gewünscht verwenden.

Zitat:
Und gibt es für diesen Code allgemeine Verbesserungsvorschläge?

Der Profiler verrät Dir, wo die meiste Zeit im Code benötigt wird. Wann immer man Laufzeitprobleme bekommt, ist er deshalb das erste Tool der Wahl.
Ich vermute aber, dass Du bereits im Editor Warn-Hinweise bekommst, da z.B. p_Z1 nicht pre-alloziert ist. Wenn ein Array in jeder Iteration wächst, verbraucht das verblüffend viele Resourcen. Ein Beispiel:
Code:
a = [];
for k = 1:1000
  a(k) = rand;
end

Jetzt wird in jeder Iteration ein neues Array für A im Speicher alloziert und die vorherigen Werte kopiert. Im Endeffekt hast Du also nicht 1000*8 Byte vom OS angefordert, sondern sum(1:1000)*8 . Der Speicher wird zwar bei Gegelegenheit wieder freigegeben, aber das ist trotzdem (in jeder Programmiersprache) eine ernste Schwachstelle.

Wie Du die etwas unpraktische Rundung per rem direkt hinbekommst, hatte ich Dir schon in einem anderen Thread erklärt.

10^-5 ist eine teure Berechnung, 1e-5 eine sehr billige Konstante.

Leerzeichen um die Operatoren machen den Code lesbar und debugbar.
Bei einem solchen Block bekomme ich akute Augenschmerzen:

Code:
   alpha_w(k)=127.93*(0.03^(-0.2))*((p_Z1(k)*10^-5)^0.8)*(T_Z1(k)^(-0.53))*(41.408^.8);
    alpha_w2(k)=127.93*(0.03^(-0.2))*((p_Z2(k)*10^-5)^0.8)*(T_Z2(k)^(-0.53))*(41.408^.8);
    dQw_Z1(k)=(2*b_Z1*h_Z1+4*b_Z1*(kolbenwegmax-s_k(k)))*alpha_w(k)*(273.15+T_w-T_Z1(k))*dt; %Wandwärmeverluste
    dQw_Z2(k)=(2*b_Z1*h_Z1+4*b_Z1*(s_k2(k)))*alpha_w2(k)*(273.15+T_w-T_Z2(k))*dt; %Wandwärmeverluste
    dT_Z1(k)=-(dH(k)+(c_v*T_Z1(k)*(-dm(k)))+dW_Z1(k)-dQw_Z1(k))/(m1(k)*c_v); %Temperaturänderung
    dp_Z1(k)=((m1(k)*R*dT_Z1(k))+(R*T_Z1(k)*(-dm(k)))-dW_Z1(k))/V_Z1(k); %Druckänderung
    dT_Z2(k)=(dH(k)-(c_v*T_Z2(k)*dm(k))-dW_Z2(k)+dQw_Z2(k))/(m2(k)*c_v);
    dp_Z2(k)=((m2(k)*R*dT_Z2(k))+(R*T_Z2(k)*dm(k))-dW_Z2(k))/V_Z2(k); %Druckänderung


Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
eh27
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 31.03.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.04.2016, 14:28     Titel:
  Antworten mit Zitat      
Hallo Jan,
vielen Dank für deine Hilfe. Das mit der rem Funktion habe ich gemacht.

Wie kann ich den letzten Wert in der elseif als Variable speichern? Und wird dieser dann jedes mal, wenn die elseif erneut durchlaufen wird wieder überschrieben mit dem neuen letzten Wert?

Den Profiler schau ich mir an.

Gruß Eric
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 14.04.2016, 17:43     Titel:
  Antworten mit Zitat      
Hallo eh27,

Gerne!

Ich kann nicht erraten, was genau "der letzte Wert" bedeutet.
Wenn Du in dem elseif-Teil schreibst:
Code:
temp = <der letzte Wert>

(was auch immer "der letzte Wert" bedeutet) wird temp immer dort gesetzt und gilt im Rest des Codes. Das ist zwar unübersichtlich, funktioniert aber zuverlässig.

Zitat:
Und wird dieser dann jedes mal, wenn die elseif erneut durchlaufen wird wieder überschrieben mit dem neuen letzten Wert?

Na klar, was sonst? Am besten probierst Du es einfach aus. Setze doch einen Breakpoint in diese Zeile und gehe dann Zeile für Zeile durch den Code. Dann siehst Du ja, was wo wie definiert ist.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
eh27
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 12
Anmeldedatum: 31.03.16
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.04.2016, 19:10     Titel:
  Antworten mit Zitat      
Hallo Jan,
Zum besser nachvollziehen. Das ganze soll ein Kreisprozess sein. Im Bereich if startet der Prozess und findet im geschlossenen Raum1 statt. Im elseif Bereich wird ein Ventil geöffnet, womit der Raum1 mit Raum2 verbunden wird. Es findet ein Ausgleich statt. Deshalb die dTs und dps. Im Raum aus sinkt damit T und p. Anschließend schließt das Ventil wieder, damit ist Raum 1 wieder geschlossen und T und P sind höher als am Anfang ( p_Umg, T_Umg ) aber niedriger, als zu Beginn im elseif Bereich. Jetzt soll statt T_Umg, p_Umg die neuen Werte zur Verdichtung genommen werden. Also der neue Startwert soll der letzte Wert aus der elseif von T und p sein.

Also der letzte wert soll im Prinzip beim ersten Arbeitsspiel wenn das Ventil bei 320 grad öffnet und 350 grad schließt T und p von 350 grad sein. In der Berechnung sind es bei 320 grad kw ca. 33 bar und bei 350 grad kw ca 26 bar, jetzt soll der Prozess im geschlossenen Raum mit 26 bar als Startwert fortgesetzt werden. Im nächsten Arbeitsspiel steigt der Druck weiter, und sollte dann im nächsten wiederum mit dem Wert aus dem letzten als Start weitermachen.

Vielen Dank für deine Hilfe!
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.