2013-02-03 4 views
6

Ich versuche ein Modell zu erstellen, das leicht unterschiedliche Gleichungen hat, basierend darauf, ob bestimmte Komponenten existieren (in meinem Fall Fluidanschlüsse).bedingte Komponentendeklaration und eine folgende if-Gleichung

wird ein Code wie die folgenden nicht:

parameter Boolean use_component=false; 
Component component if use_component; 
equation 
if use_component then 
    component.x = 0; 
end if; 

Wie kann ich dieses Problem umgehen?

Antwort

8

Wenn Sie Bedingung Komponenten verwenden möchten, gibt es einige Einschränkungen Sie bewusst sein müssen. Abschnitt 4.4.5 der Modelica 3.3-Spezifikation fasst es gut zusammen. Er lautet: "Wenn die Bedingung falsch ist, werden die Komponente, ihre Modifikatoren und alle Verbindungsgleichungen , die die Komponente betreffen, entfernt". Ich zeige Ihnen, wie Sie dieses Problem in nur einer Sekunde lösen können, aber zuerst möchte ich erklären, warum Ihre Lösung nicht funktioniert.

Das Problem hat mit der Überprüfung des Modells zu tun. In Ihrem Fall ist es offensichtlich, dass die Gleichung component.x und die Komponente component entweder beide existieren oder keine existieren. Das liegt daran, dass Sie sie an die gleiche boolesche Variable gebunden haben. Aber was, wenn Sie hatte nicht dieses:

parameter Real some_number; 
Component component if some_number*some_number>4.0; 
equation 
if some_number>=-2 and some_number<=2 then 
    component.x = 0; 
end if; 

Wir können sehen, dass dies logisch identisch mit Ihrem Fall. Es gibt keine Möglichkeit für component.x zu existieren, wenn component nicht vorhanden ist. Aber können wir solche Dinge im Allgemeinen beweisen? Wenn also bedingte Komponenten eingeführt wurden, wurde eine konservative Semantik implementiert, die immer trivial sicherstellen kann, dass die beteiligten Variablen und Gleichungen niemals "aus der Synchronisation geraten".

Wenden wir uns zurück, was die Spezifikation sagt: „Wenn die Bedingung falsch ist, wird die Komponente, seine Modifikatoren und alle Verbindungsgleichungen die Komponente beteiligt, werden entfernt“

Für Ihren Fall könnte die Lösung möglicherweise ziemlich einfach sein. Je nachdem, wie Sie "x" deklarieren, können Sie einfach eine Änderung an component, d. H.

parameter Boolean use_component=false; 
Component component(x=0) if use_component; 

die Eleganz dieses ist, dass die Änderung gilt nur für component und wenn component nicht vorhanden ist, ist weder die Modifikation (Gleichung). Die Variable x und die zugehörige Gleichung sind also "synchron". Aber das funktioniert nicht in allen Fällen (IIRC, x muss einen input Qualifier haben, damit das funktioniert ... vielleicht ist das in Ihrem Fall möglich?).

Es gibt zwei verbleibende Alternativen. Stellen Sie zuerst die Gleichung component.x innerhalb component. Die zweite Möglichkeit besteht darin, unter component einen Konnektor einzuführen, der, wenn er angeschlossen ist, die von Ihnen gewünschte Gleichung erzeugt. Wie bei der Modifikation Fall (dies ist kein Zufall), Sie x mit einem Eingangsanschluss von einer Art assoziieren könnten und dann dies tun:

parameter Boolean use_component; 
Component component if use_component; 
Constant zero(k=0); 
equation 
connect(k.y, component.x); 

Nun könnte ich mir vorstellen, dass nach allen drei Fällen (Änderung unter Berücksichtigung, verinnerlicht Gleichung und verwenden connect), kommen Sie zu der Schlussfolgerung, dass keiner von ihnen funktionieren wird. Wenn dies der Fall ist, würde ich demütig vorschlagen, dass Sie ein Problem damit haben, wie Sie die Komponente entworfen haben. Der Grund für diese Einschränkungen liegt in der Notwendigkeit, die Komponenten selbst zu überprüfen für die Richtigkeit. Dies erfordert, dass die Komponente vollständig ist (in der Terminologie der Spezifikation "ausgewogen").

Wenn Sie das Problem mit den oben genannten Ansätzen nicht lösen können, dann vermute ich, dass Sie wirklich ein Balance-Problem haben und dass Sie wahrscheinlich irgendwie die Grenzen Ihrer Komponente neu definieren müssen. Wenn dies der Fall ist, würde ich vorschlagen, dass Sie hier eine weitere Frage mit Details zu dem, was Sie tun möchten, öffnen.

1

Ich denke, dass der Grund, warum das nicht funktioniert, ist, dass der Parser nach der Deklaration der Variable "component.x" suchen wird, die nicht existiert, wenn die Komponente nicht aktiv ist. Es funktioniert nicht, selbst wenn Sie in der Annotation "Evaluate = true" einfügen. Die sauberste Lösung ist meines Erachtens, auf Gleichungsebene zu arbeiten und verschiedene Sätze von Gleichungen im selben Block zu ermöglichen. Sie können ein Wrapper-Modell mit den richtigen Konnektoren und Parametern erstellen, und wenn es sich beispielsweise um ein kausales Modell handelt, können Sie ersetzbare Klassen verwenden, um die Modelle als Funktionen zu parametrisieren, oder im Fall von akausalen Modellen die Gleichungen hineinzulegen wenn Aussagen. Eine andere mögliche Problemumgehung besteht darin, zwei verschiedene Modelle in einem Block zu platzieren, sodass Sie ihre Variablen in den Gleichungsabschnitt einfügen und dann bedingte Verbindungen erstellen können, die die Verwendung des Blocks mit dem gewählten Verhalten ermöglichen. Mit anderen Worten, Sie können ein "Wrap-Modell" mit zwei Blöcken im Inneren erstellen und dann die Verbindungsgleichungen auf die Connectors des Wrap-Modells innerhalb von if-Anweisungen setzen. Denken Sie daran, das Modell so aufzubauen, dass selbst für die Blöcke, die nicht verwendet werden, ein konsistentes System von Anforderungen existiert. Aber das ist nicht die beste Lösung, denn wenn die Blöcke groß sind, müssen Sie länger auf die Kompilierung warten, da alles kompiliert wird.

ich das hoffentlich helfen,

Marco

0

Sie können auch eine Dummy-Komponente machen, die nicht sichtbar in der grafischen Schicht ist:

connector DummyHeatPort 
    "Dummy heatport to facilitate optional heatport. Use this with a conditional heatport by connecting it to the heatport. Then use the -DummyHeatPort.Q_flow in the thermal energy balance." 
    Modelica.SIunits.Temperature T "Port temperature"; 
    flow Modelica.SIunits.HeatFlowRate Q_flow 
    "Heat flow rate (positive if flowing from outside into the component)"; 
end DummyHeatPort; 

Dann, wenn dies in einem Zwei-Port-Modell

Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatport if use_heat_port; 
DummyHeatPort dummy_heatport; 
verwendet wird ...

equation 
flowport_a.H_flow + flowport_b.H_flow - dummy_heatport.Q_flow = storage 
    "thermal energy balance"; 
    connect(dummy_heatport, heatport); 

Auf diese Weise wird der Heatport verwendet, wenn vorhanden, aber sonst kein Fehler.

Verwandte Themen