2017-04-24 22 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 상태에 대한 Boolean 변수, 실행중인 펌프 수에 대한 Integer 변수 등을 사용해 보았습니다. 아직 해결할 정상 상태 솔루션을 얻을 수 없습니다.

의견을 보내 주시면 대단히 감사하겠습니다.

덕분에, 저스틴

+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 2 차 펌프를 활성화해야합니까?

3 새로운 빈도를 계산하십시오.

결정에 일부 히스테리시스를 추가하면 유사한 효과가 있습니다.

+0

Hans, 나는 귀하의 접근 방법을 시도했으며, 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;