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

Matlab Function Block erzeugt kein kontinuierliches Signal

 

kaktus018

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 25.02.2016, 19:19     Titel: Matlab Function Block erzeugt kein kontinuierliches Signal
  Antworten mit Zitat      
Hallo,
ich habe ein Modell, in welchem ich eine Matlab Function verwende. Diese hat als Eingangsgröße u.A. eine Clock. Nun habe ich das Problem, dass die Matlab Function anscheinend nicht für jeden Zeitschritt ausgeführt wird, was ein "sprunghaftes" Signal erzeugt. Dieses Signal wird im weiteren Verlauf integriert, was bedingt durch dessen starke Unstetigkeit den Solver in die Knie zwingt (selbst die impliziten Löser brauchen ewig).
Wenn ich dieses Signal zuerst integriere und dann wieder differenziere erscheint es glatt. Zum Vergleich befindet sich ein Screenshot des Signals im Anhang. Oben das integrierte und differenzierte und unten ein zweites (originales) Signal.
Im Anhang ist auch ein Screenshot des entsprechenden Subsystems (es geht um sTh1).
Weiß jemand, warum dieses Signal solche Sprünge aufweißt? Ich würde ja auf die Clock tippen, aber lt. Dokumentation erzeugt diese eine Ausgabe für jeden Schritt in der Simulation. Für Hilfe wäre ich also dankbar!

Hier nocht der Code der Matlab Function:
Code:
function [T,TTF,sTh] = fcn(Ttau,l,lRB,lambdaSt,lambdaRB,cSt,cRB,rhoSt,rhoRB,alphaThSt,alphaThRB,hAk,nyRB,nySt,qR,TAk,TRef,T22tau,deltaXi2O,lambda2O,deltat)
 
 % Größe des Temperaturfelds deklarieren
 T=Ttau;

 % FDM für t>0 - sonst werden die Anfangsbedingungen zurück gegeben
 if deltat>0
     
    % Gitterweite
    deltaXiRB=lRB/nyRB;
    deltaXiSt=(l-2*lRB)/nySt;
     
    % Größen an der Oberfläche
    if lRB > 0
        lambdaO=lambdaRB;
        deltaXiO=deltaXiRB;
    else
        lambdaO=lambdaSt;
        deltaXiO=deltaXiSt;
    end        
     
    % Stabilitätsbedingung
    if deltaXiSt<sqrt(2*lambdaSt/rhoSt/cSt*deltat) || (lRB>0 && deltaXiRB<sqrt(2*lambdaRB/rhoRB/cRB*deltat))
        error('Heat flux model: Stability criterion of FDM violated. Reduce the number of points ny or set a smaller time step for the used solver.');
    end
 
    % Randbedingungen
    T(1)=(Ttau(2)*lambdaO+TAk*hAk*deltaXiO)/(lambdaO+hAk*deltaXiO);  % Temperatur am linken Rand
    if lRB>0
        T(nyRB)=(Ttau(nyRB-1)*lambdaRB*deltaXiSt+Ttau(nyRB+1)*lambdaSt*deltaXiRB)/(lambdaSt*deltaXiRB+lambdaRB*deltaXiSt);  % T_RB/St
        T(nyRB+nySt-1)=(Ttau(nyRB+nySt-2)*lambdaSt*deltaXiRB+Ttau(nyRB+nySt)*lambdaRB*deltaXiSt)/(lambdaSt*deltaXiRB+lambdaRB*deltaXiSt); % T_St/RB
    end
    T(numel(T))=(Ttau(numel(T)-1)*lambdaO*deltaXi2O+T22tau*lambda2O*deltaXiO+qR*deltaXiO*deltaXi2O)/(lambdaO*deltaXi2O+lambda2O*deltaXiO);  % Temperatur am rechten Rand (Trennfugentemperatur)
 
    % Iteration für ny Punkte in xi
    if lRB>0
     % Reibbelag links
        for i=2:nyRB-1
            T(i)=Ttau(i)+deltat*lambdaRB/rhoRB/cRB*(Ttau(i+1)-2*Ttau(i)+Ttau(i-1))/deltaXiRB^2;
        end
        % Stahl
        for i=nyRB+1:nyRB+nySt-2
            T(i)=Ttau(i)+deltat*lambdaSt/rhoSt/cSt*(Ttau(i+1)-2*Ttau(i)+Ttau(i-1))/deltaXiSt^2;
        end
        % Reibbelag rechts
        for i=nyRB+nySt:nySt+2*nyRB-3
            T(i)=Ttau(i)+deltat*lambdaRB/rhoRB/cRB*(Ttau(i+1)-2*Ttau(i)+Ttau(i-1))/deltaXiRB^2;
        end
    else
        % Stahl
        for i=2:nySt-1
            T(i)=Ttau(i)+deltat*lambdaSt/rhoSt/cSt*(Ttau(i+1)-2*Ttau(i)+Ttau(i-1))/deltaXiSt^2;
        end
    end
 end
 
 TTF=T(numel(T));  % Trennfugentemperatur
 % Thermischer Federhub
 if lRB>0
     assert(nyRB<numel(T) && nySt<numel(T));
     sTh=alphaThRB*trapz(linspace(0,lRB,nyRB),T(1:nyRB)-TRef);
     sTh=sTh+alphaThSt*trapz(linspace(lRB,l-lRB,nySt),T(nyRB:nyRB+nySt-1)-TRef);
     sTh=sTh+alphaThRB*trapz(linspace(l-lRB,l,nyRB),T(nyRB+nySt-1:2*nyRB+nySt-2)-TRef);
 else
     assert(nySt==numel(T));
     sTh=alphaThSt*trapz(linspace(0,l,nySt),T(1:nySt)-TRef);
 end


2016-02-25 19_14_28-Pruefstand_..._WMF 1D_WFM Lamelle 1 _.png
 Beschreibung:

Download
 Dateiname:  2016-02-25 19_14_28-Pruefstand_..._WMF 1D_WFM Lamelle 1 _.png
 Dateigröße:  28.65 KB
 Heruntergeladen:  415 mal
2016-02-25 19_12_15-Scope.png
 Beschreibung:

Download
 Dateiname:  2016-02-25 19_12_15-Scope.png
 Dateigröße:  7.91 KB
 Heruntergeladen:  381 mal


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 26.02.2016, 16:51     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Nun habe ich das Problem, dass die Matlab Function anscheinend nicht für jeden Zeitschritt ausgeführt wird

Woraus schließt du das?

Was möchtest du mit dem Memory-Block modellieren?

Es ist immer hilfreicher, wenn das Modell zur Verfügung steht statt Beschreibung und Screenshots, damit man das Verhalten nachvollziehen und Ursachenforschung betreiben kann.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.02.2016, 11:16     Titel:
  Antworten mit Zitat      
Hallo Harald und danke für deine Antwort!
Das gesamte Modell ist relativ komplex und ich darf dieses aus rechtlichen Gründen nicht hochladen. Ich habe aber ein Test-Modell erstellt, welches die Problematik grundsätzlich wiedergibt (auch wenn die Rechenzeit hier gut ist).
Das Problem ist grundsätzlich folgendes:
Die Matlab Function verwendet die Finite-Differenzen-Methode um ein Temperaturfeld zu berechnen. Aus diesem ergibt sich eine Längenänderung (sTh1), welche eine Eingangsgröße eines weiteren Subsystems ist. Dieses berechnet dann durch Integration einen Wärmestrom, welcher wieder als Eingangsgröße zur Berechnung des Temperaturfeldes dient. Zur Anwendung der Finite-Differenzen-Methode muss ich den Zeitschritt kennen. Dieser ist allerdings nur für den aktuellen Simulationsschritt bekannt (über die Clock berechnet), benötigen tue ich aber nicht den aktuellen, sondern den nächsten Zeitschritt. Mit den Memory-Blöcken verzögere ich einfach die Berechnung des Temperaturfeldes um einen Zeitschritt und löse damit das Problem.
Ich konnte jetzt übrigens den Memory-Block als Übeltäter identifizieren. Im Anhang nochmal ein Screenshot des Signals vor und nach dem Memory-Block. Des weiteren habe ich gelesen, dass man Memory-Blöcke mit variablen Eingangssignal nicht mit ode15s verwenden soll, was bei mir aber genau der Fall ist.
Ich verwende R2012a.

test.mdl
 Beschreibung:

Download
 Dateiname:  test.mdl
 Dateigröße:  72.22 KB
 Heruntergeladen:  421 mal
2016-02-28 10_51_12-Scope.png
 Beschreibung:

Download
 Dateiname:  2016-02-28 10_51_12-Scope.png
 Dateigröße:  5.77 KB
 Heruntergeladen:  398 mal
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.492
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.02.2016, 21:16     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
benötigen tue ich aber nicht den aktuellen, sondern den nächsten Zeitschritt.

Das ist bei variabler Schrittweite aber nicht möglich.

Schrittweitenkontrolle ist aber ohnehin Augenwischerei, da die Ergebnisse des MATLAB Function-Blocks ja nur eine Näherung liefern und das bei der Schrittweitenkontrolle keine Berücksichtigung findet.
Wie wäre es also, mit einer kleinen, festen Schrittweite zu simulieren?

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.02.2016, 15:03     Titel:
  Antworten mit Zitat      
Zitat:
Das ist bei variabler Schrittweite aber nicht möglich.

Da hast du Recht. Deswegen wollte ich die Berechnung des Temperaturfeldes eben um einen Zeitschritt verzögern. Da ich ohnehin nur eine max. Schrittweite von 0.005 erlauben kann, wird sich der Fehler dadurch in Grenzen halten.
Zitat:
Schrittweitenkontrolle ist aber ohnehin Augenwischerei, da die Ergebnisse des MATLAB Function-Blocks ja nur eine Näherung liefern und das bei der Schrittweitenkontrolle keine Berücksichtigung findet.
Wie wäre es also, mit einer kleinen, festen Schrittweite zu simulieren?

Mir gehts eher um das Stabilitätsgebiet und weniger um die Genauigkeit. Kurzzeitig braucht der Solver sehr kleine Zeitschritte, damit er konvergiert. Wenn ich nun eine fixe Schrittweite verwende, dann braucht die Simulation dadurch noch länger.
Jedenfalls bin ich jetzt auf diesen Artikel gestoßen:
http://blogs.mathworks.com/simulink.....with-with-a-memory-block/
So angenehm der Memory-Block in meinem Fall wäre, ist er scheinbar tatsächlich für die Unstetigkeit und die schlechte Performance des Modells verantwortlich - weil er eben ein diskretes Ausgangssignal hat, das sich bei Zwischenschritten des Solvers nicht ändert.
Ich habe nun alle Memory-Blöcke entfernt und arbeite stattdessen mit persistenten Variablen. Der Wärmestrom wird wie in dem Artikel über eine Transfer Function verzögert. Nach viel Probieren scheint es mit diesem Aufbau nun gut zu funktionieren. Die Rechenzeit könnte zwar immer noch besser sein, es ist aber kein Vergleich zu vorher.
Ich denke, das Problem ist gelöst - es sei denn, euch fällt dazu noch was ein.
 
kaktus018

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 29.02.2016, 20:14     Titel:
  Antworten mit Zitat      
Ich habe mich leider zu früh gefreut. Mir ist nämlich aufgefallen, dass die berechneten Temperaturen zu hoch sind. Ich habe auch bemerkt, dass der Solver manchmal negative Zeitschritte macht, wobei die FDM in dieser Form nur vorwärts iterieren kann. So sind die Wärmeströme länger wirksam, was dann unweigerlich zu zu hohen Temperaturen führt. Ich habe den Verdacht, dass ich das komplette Modell diskretisieren muss, damit meine Vorgehensweise realisierbar ist. Für Anregungen wäre ich also nach wie vor dankbar!
 
kaktus018

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.03.2016, 17:16     Titel:
  Antworten mit Zitat      
Update:
Ich habe jetzt die gesamte FDM in einen Matlab-Function-Block implementiert und für diesen eine diskrete Sample-Time vorgegeben. So wird die Funktion wirklich nur im angegebenen Zeitintervall ausgewertet, was scheinbar auch den Solver kaum stört.
Die zu hohen Temperaturen waren der FDM geschuldet. Die Wahl eines feineren Gitters hat das Problem gelöst.
 
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 - 2024 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.