2017-04-24 30 views
1

我正在嘗試解決我認爲應該使用Modelica的簡單穩態組件分段問題,但我正在努力尋求解決方案。在穩態Modelica模型中解決組件暫存問題

我準備了一個帶有兩臺並聯泵的實例,它必須向系統提供目標總流量(vTotal)。一臺泵是變頻泵,並提供與指令頻率(fPump1)成比例的流量(v1),該值可以在0和fMax之間變化。另一臺泵是一臺定速泵,每當運行時輸出一個固定的流量(v2IfRunning),當它不運行時輸出零流量。

目標是解決正在運行的泵的數量和變頻泵頻率。變速泵始終運轉,只有當變速泵需要以大於fMax的頻率運行時才使用恆速泵。我的示例代碼如下:

model TwoPumpCode 
    // Pump 1 
    Modelica.SIunits.Frequency fPump1 "pump 1 frequency"; 
    Modelica.SIunits.Frequency fMax = 50 "maximum frequency"; 
    Modelica.SIunits.VolumeFlowRate v1; 

    // Pump 2 
    // Boolean runPump2(start=false) "true if pump 2 should run"; 
    Modelica.SIunits.VolumeFlowRate v2IfRunning = 30; 
    Modelica.SIunits.VolumeFlowRate v2 
    "actual flow through pump 2"; 

    Integer nPumpsRunning(start = 1) "number of pumps running"; 

    // Total flow 
    Modelica.SIunits.VolumeFlowRate vTotal = 70; 

equation 
    // Calculate the flow through pump 1 as a function of frequency 
    v1 = fPump1; 

    // Calculate the flow through pump 2 based upon running state 
    if fPump1 > fMax then 
    nPumpsRunning = 2; 
    v2 = v2IfRunning; 
    else 
    nPumpsRunning = 1; 
    v2 = 0; 
    end if; 

    // Calculate the total flow 
    vTotal = v1 + v2; 

end TwoPumpCode; 

此外,這是一個穩態模型。我嘗試過使用if,when,reinit,用於pumpRunning狀態的布爾變量,用於運行泵的數量的整數變量等,並且我仍然無法獲得穩態解決方案來解決問題。

任何建議將不勝感激。

感謝, 賈斯汀

+1

您可以將控制邏輯從您的泵型號中分離出來,在MSL模型中。然後你有一個有開/關開關的泵型號和一個控制器。在控制器中,使用滯後來避免抖動。 – matth

+0

感謝您的反饋數據。系統的其餘部分是純粹的穩態,所以如果可能的話,我寧願避免控制器的動態。你能推薦一個MSL的特定例子嗎? –

+1

像「Modelica.Blocks.Logical.OnOffController」這樣的控制器不會增加動態,因爲沒有存儲/集成等,它就像你的代碼一樣使用'if'條件。也許我不應該稱之爲控制器,更好地稱它爲邏輯塊!?你可能會在github上找到使用示例:https://git.io/v9IGP – matth

回答

1

我現在更好地理解它。問題是我們需要分離變量。

model TwoPumpCode 
    Modelica.SIunits.VolumeFlowRate vTotal = 70-40*time; 
    model TwoPumpSimple 
    // Pump 1 
    Modelica.SIunits.Frequency fPump1 "pump 1 frequency"; 
    Modelica.SIunits.Frequency fMax = 50 "maximum frequency"; 
    Modelica.SIunits.VolumeFlowRate v1; 

    // Pump 2 
    // Boolean runPump2(start=false) "true if pump 2 should run"; 
    Modelica.SIunits.VolumeFlowRate v2IfRunning = 30; 
    Modelica.SIunits.VolumeFlowRate v2 
    "actual flow through pump 2"; 

    Integer nPumpsRunning(start = 1) "number of pumps running"; 
    // Total flow 
    input Modelica.SIunits.VolumeFlowRate vTotal; 
    input Boolean activeSecond; 
    equation 
    // Calculate the flow through pump 1 as a function of frequency 
    v1 = fPump1; 

    // Calculate the flow through pump 2 based upon running state 
    if activeSecond then 
    nPumpsRunning = 2; 
    v2 = v2IfRunning; 
    else 
    nPumpsRunning = 1; 
    v2 = 0; 
    end if; 

    // Calculate the total flow 
    vTotal = v1 + v2; 
    end TwoPumpSimple; 
    //TwoPumpSimple first(vTotal=vTotal,activeSecond=first.fPump1>first.fMax); 
    TwoPumpSimple first(vTotal=vTotal,activeSecond=false); 
    TwoPumpSimple second(vTotal=vTotal,activeSecond=first.fPump1>first.fMax); 
end TwoPumpCode; 

的出注釋行是相同的第一溶液中,並將其改變爲離散問題 - 但是,問題有時缺乏的溶液。

新變種做以下操作: 1沒有第二個泵需要多高的頻率?

2我們應該激活第二個泵嗎?

3計算新頻率 - 基於此。

在決策中增加一些滯後效應也會有類似的效果。

+0

漢斯,我嘗試了你的方法,並且你在Dymola中模擬它是正確的。但是,由此產生的解決方案結果似乎並不正確。我的最終結果包括:activeSecond = true,nPumpsRunning = 2,v2 = 0,v1 = 70,fPump1 = 70.這些結果似乎彼此不一致。 –

+0

啊,我看到了 - 問題是條件fPump1> fMax。如果我們用vTotal> fMax代替它,這個模擬就可以工作。 –

1

根據matth的反饋,我可以使用基於Modelica.Blocks.Logical.OnOffController示例的pre()運算符。功能代碼如下所示,供參考。

model TwoPumpCode_matth 
    // Pump 1 
    Modelica.SIunits.Frequency fPump1 "pump 1 frequency"; 
    Modelica.SIunits.Frequency fMax = 50 "maximum frequency"; 
    Modelica.SIunits.VolumeFlowRate v1; 

    // Pump 2 
    parameter Boolean runPump2InitialValue = false; 
    Boolean runPump2(start=runPump2InitialValue) "true if pump 2 should run"; 
    Modelica.SIunits.VolumeFlowRate v2IfRunning = 30; 
    Modelica.SIunits.VolumeFlowRate v2 "actual flow through pump 2"; 

    // Total flow 
    Modelica.SIunits.VolumeFlowRate vTotal = 70; 

initial equation 
    pre(runPump2) = runPump2InitialValue; 

equation 
    // Calculate the flow through pump 1 as a function of frequency 
    v1 = fPump1; 

    // Calculate the flow through pump 2 based upon running state 
    runPump2 = pre(runPump2) or (fPump1 > fMax); 
    if runPump2 then 
    v2 = v2IfRunning; 

    else 
    v2 = 0; 

    end if; 

    // Calculate the total flow 
    vTotal = v1 + v2; 

end TwoPumpCode_matth;