【发布时间】:2022-01-28 13:51:23
【问题描述】:
我是 OpenModelica 的初学者,可能有一些基本问题,更有经验的用户可能很容易回答。
关于计划使用 OpenModelica 的应用程序的背景。目标是通过简化现实生活中的组件来创建造纸机短循环的简约模型,使它们大多只是打开和关闭的混合体积、管道和阀门。前一部分将作为流中助留剂浓度的函数,作为流中固体组分(纤维和填料)的分离器。基于简单的保留模型,实体组件分为两部分,一部分转发到压力部分,其余部分返回到线坑,是一个开放的容器,有溢流。
至少我没有直接找到能够代表三种不同物质和一种微量物质的合适的 Medium 模型。物质是水、纤维和填料。助留剂将是一种痕量物质,因为与其他物质相比,体积流量非常小。为简单起见,假设纤维和填料的行为类似于水。模拟的准确性不是本练习的关键。重点是在工艺的不同部分追踪水、纤维和填料的质量分数,并展示短循环在操作点变化中引入的一些动态行为。
我通过借鉴目前支持三种物质的不同介质模型的想法,设法拼接了一个介质模型,一个简单的模拟模型(源、罐、静态管道和水槽)似乎以合理的方式工作。
为了演示目标过程的动态,模型还应模拟物质管道中的运输延迟。静态管道模型没有考虑到这一点。我在 Buildings 库中找到了 plugFlowPipe 模型(用于区域供热应用),并且通过查看模型代码,只要“水”是独立物质之一,它就应该适用于源自 PartialMedium 模型的多物质介质(检查“水”这个名字的存在)。由于 Buildings 库不支持 Modelica 4.0.0,我不得不回到 3.2.3 版才能使用 Buildings 库。
PlugFlowPipe 似乎是一个很难正确工作的模型。模拟以错误抱怨“错误求解非线性系统......”结束。转换调试器消息使我无法弄清楚实际问题所在。
这里附上介质模型(SimpleMachineStockMedium_323_v2)和仿真模型(delay_test_05c.mo)。除此之外,还使用了 Buildings 库版本 8.1.0。抱歉,我无法将这些作为附件附加,所以我会在问题之后发布它们......
我希望有人能指出导致求解器错误的中等模型或仿真模型的问题是什么?或者给出一个想法,如何在 openmodelica 中以另一种方式对多物质介质的活塞流特性进行建模。已经非常感谢你了!
中型模型
// file: SimpleMachineStockMedium_323_v2.mo
package SimpleMachineStockMedium_323_v2
import Modelica = Modelica;
// EXTENDING FROM A CLASS
// **************************
extends Modelica.Media.Interfaces.PartialMedium(
final ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.pTX,
final singleState = true,
final reducedX = true,
final fixedX = false,
reference_X=fill(1/nX,nX),
mediumName="SimpleMachineStockMedium_323_v2",
substanceNames={"water","fiber","filler"},
extraPropertiesNames=fill("", 0)
//extraPropertiesNames={"reta"}
);
// SPECIFY CONSTANTS
// *********************************
constant SpecificHeatCapacity cp_const=4184 "Constant specific heat capacity at constant pressure";
constant SpecificHeatCapacity cv_const=4184 "Constant specific heat capacity at constant volume";
constant Density d_const=995.586 "Constant density";
constant DynamicViscosity eta_const=1.e-3 "Constant dynamic viscosity";
constant ThermalConductivity lambda_const=0.598 "Constant thermal conductivity";
constant VelocityOfSound a_const=1484 "Constant velocity of sound";
constant Temperature T_min=273 "Minimum temperature valid for medium model";
constant Temperature T_max=373 "Maximum temperature valid for medium model";
constant Temperature T0=273.15 "Zero enthalpy temperature";
// defining fluid constants for substances
import Modelica.Media.Water.ConstantPropertyLiquidWater.simpleWaterConstants;
constant Modelica.Media.Interfaces.Types.Basic.FluidConstants[3]
simpleWaterConstants(
each chemicalFormula="H2O",
each structureFormula="H2O",
each casRegistryNumber="7732-18-5",
each iupacName="oxidane",
each molarMass=0.018015268);
//constant MolarMass MM_const "Molar mass";
// Molarmasses are defined for substances, just giving same values for all
constant Real MM_const_fiber = 0.018015268;
constant Real MM_const_filler = 0.018015268;
constant Real MM_const_water = 0.018015268;
constant MolarMass[nX] MMX ={MM_const_fiber, MM_const_filler, MM_const_water} "Molar mass";
// THERMODYNAMIC STATE
// **********************
redeclare record extends ThermodynamicState "Thermodynamic state"
AbsolutePressure p "Absolute pressure of medium";
Temperature T "Temperature of medium";
// bring in the substances
MassFraction[nX] X(start=reference_X) "Mass fractions (= (component mass)/total mass m_i/m)";
end ThermodynamicState;
// MODEL BaseProperties
// ********************
redeclare replaceable model extends BaseProperties(
T(stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default),
p(stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default),
Xi(each stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default),
final standardOrderComponents = true) "Base properties"
equation
assert(T >= T_min and T <= T_max, "
Temperature T (= " + String(T) + " K) is not
in the allowed range (" + String(T_min) + " K <= T <= " + String(T_max) + " K)
required from medium model \"" + mediumName + "\".
");
// h = cp_const*(T-T0);
h = specificEnthalpy_pTX(
p,
T,
X);
u = cv_const*(T - T0);
d = d_const;
R = 0;
//MM = MM_const;
MM = molarMass(state);
state.T = T;
state.p = p;
state.X = if fixedX then reference_X else X;
annotation (Documentation(info="<html>
<p>
This is the most simple incompressible medium model, where
specific enthalpy h and specific internal energy u are only
a function of temperature T and all other provided medium
quantities are assumed to be constant.
Note that the (small) influence of the pressure term p/d is neglected.
</p>
</html>"));
end BaseProperties;
// DECLARE FUNCTIONS
// *******************
//-------------------
redeclare function setState_pTX
"Return thermodynamic state from p, T, and X or Xi"
extends Modelica.Icons.Function;
input AbsolutePressure p "Pressure";
input Temperature T "Temperature";
input MassFraction X[:]=reference_X "Mass fractions";
output ThermodynamicState state "Thermodynamic state record";
algorithm
//state := ThermodynamicState(p=p, T=T);
// take into account substances
state := if size(X,1) == 0 then ThermodynamicState(p=p,T=T,X=reference_X)
else if size(X,1) == nX then ThermodynamicState(p=p,T=T, X=X)
else ThermodynamicState(p=p,T=T, X=cat(1,X,{1-sum(X)})); // when reduceX = true
end setState_pTX;
//-------------------
redeclare function setState_phX
"Return thermodynamic state from p, h, and X or Xi"
extends Modelica.Icons.Function;
input AbsolutePressure p "Pressure";
input SpecificEnthalpy h "Specific enthalpy";
input MassFraction X[:]=reference_X "Mass fractions";
output ThermodynamicState state "Thermodynamic state record";
algorithm
state := if size(X,1) == 0 then ThermodynamicState(p = p, T = T0 + h / cp_const, X=X)
else if size(X,1) == nX then ThermodynamicState(p = p, T = T0 + h / cp_const, X=X)
else ThermodynamicState(p = p, T = T0 + h / cp_const, X=cat(1,X,{1-sum(X)}));
end setState_phX;
//-------------------
redeclare replaceable function setState_psX
"Return thermodynamic state from p, s, and X or Xi"
extends Modelica.Icons.Function;
input AbsolutePressure p "Pressure";
input SpecificEntropy s "Specific entropy";
input MassFraction X[:]=reference_X "Mass fractions";
output ThermodynamicState state "Thermodynamic state record";
algorithm
//state := ThermodynamicState(p=p, T=Modelica.Math.exp(s/cp_const +
// Modelica.Math.log(reference_T)))
// "Here the incompressible limit is used, with cp as heat capacity";
// take into account substances
state := if size(X,1) == 0 then ThermodynamicState(p = p, T = Modelica.Math.exp(s / cp_const + Modelica.Math.log(reference_T)), X=X)
else if size(X,1) == nX then ThermodynamicState(p = p, T = Modelica.Math.exp(s / cp_const + Modelica.Math.log(reference_T)), X=X)
else ThermodynamicState(p = p, T = Modelica.Math.exp(s / cp_const + Modelica.Math.log(reference_T)), X=cat(1,X,{1-sum(X)}));
end setState_psX;
//-------------------
redeclare function setState_dTX
"Return thermodynamic state from d, T, and X or Xi"
extends Modelica.Icons.Function;
input Density d "Density";
input Temperature T "Temperature";
input MassFraction X[:]=reference_X "Mass fractions";
output ThermodynamicState state "Thermodynamic state record";
algorithm
assert(false,
"Pressure can not be computed from temperature and density for an incompressible fluid!");
end setState_dTX;
//-------------------
redeclare function extends setSmoothState
"Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b"
algorithm
state := ThermodynamicState(p=Media.Common.smoothStep(
x,
state_a.p,
state_b.p,
x_small), T=Media.Common.smoothStep(
x,
state_a.T,
state_b.T,
x_small));
end setSmoothState;
//-------------------
redeclare function extends dynamicViscosity "Return dynamic viscosity"
algorithm
eta := eta_const;
end dynamicViscosity;
//-------------------
redeclare function extends thermalConductivity
"Return thermal conductivity"
algorithm
lambda := lambda_const;
end thermalConductivity;
//-------------------
redeclare function extends pressure "Return pressure"
algorithm
p := state.p;
end pressure;
//-------------------
redeclare function extends temperature "Return temperature"
algorithm
T := state.T;
end temperature;
//-------------------
redeclare function extends density "Return density"
algorithm
d := d_const;
end density;
//-------------------
redeclare function extends specificEnthalpy "Return specific enthalpy"
algorithm
h := cp_const*(state.T - T0);
end specificEnthalpy;
//-------------------
redeclare function extends specificHeatCapacityCp
"Return specific heat capacity at constant pressure"
algorithm
cp := cp_const;
end specificHeatCapacityCp;
//-------------------
redeclare function extends specificHeatCapacityCv
"Return specific heat capacity at constant volume"
algorithm
cv := cv_const;
end specificHeatCapacityCv;
//-------------------
redeclare function extends isentropicExponent "Return isentropic exponent"
algorithm
gamma := cp_const/cv_const;
end isentropicExponent;
//-------------------
redeclare function extends velocityOfSound "Return velocity of sound"
algorithm
a := a_const;
end velocityOfSound;
//-------------------
redeclare function specificEnthalpy_pTX
"Return specific enthalpy from p, T, and X or Xi"
extends Modelica.Icons.Function;
input AbsolutePressure p "Pressure";
input Temperature T "Temperature";
input MassFraction X[nX] "Mass fractions";
output SpecificEnthalpy h "Specific enthalpy";
algorithm
h := cp_const*(T - T0);
annotation (Documentation(info="<html>
<p>
This function computes the specific enthalpy of the fluid, but neglects the (small) influence of the pressure term p/d.
</p>
</html>"));
end specificEnthalpy_pTX;
//-------------------
redeclare function temperature_phX
"Return temperature from p, h, and X or Xi"
extends Modelica.Icons.Function;
input AbsolutePressure p "Pressure";
input SpecificEnthalpy h "Specific enthalpy";
input MassFraction X[nX] "Mass fractions";
output Temperature T "Temperature";
algorithm
T := T0 + h/cp_const;
end temperature_phX;
//-------------------
redeclare function density_phX "Return density from p, h, and X or Xi"
extends Modelica.Icons.Function;
input AbsolutePressure p "Pressure";
input SpecificEnthalpy h "Specific enthalpy";
input MassFraction X[nX] "Mass fractions";
output Density d "Density";
algorithm
d := density(setState_phX(
p,
h,
X));
end density_phX;
//-------------------
redeclare function extends specificInternalEnergy
"Return specific internal energy"
extends Modelica.Icons.Function;
algorithm
// u := cv_const*(state.T - T0) - reference_p/d_const;
u := cv_const*(state.T - T0);
annotation (Documentation(info="<html>
<p>
This function computes the specific internal energy of the fluid, but neglects the (small) influence of the pressure term p/d.
</p>
</html>"));
end specificInternalEnergy;
//-------------------
redeclare function extends specificEntropy "Return specific entropy"
extends Modelica.Icons.Function;
algorithm
s := cv_const*Modelica.Math.log(state.T/T0);
end specificEntropy;
//-------------------
redeclare function extends specificGibbsEnergy
"Return specific Gibbs energy"
extends Modelica.Icons.Function;
algorithm
g := specificEnthalpy(state) - state.T*specificEntropy(state);
end specificGibbsEnergy;
//-------------------
redeclare function extends specificHelmholtzEnergy
"Return specific Helmholtz energy"
extends Modelica.Icons.Function;
algorithm
f := specificInternalEnergy(state) - state.T*specificEntropy(state);
end specificHelmholtzEnergy;
//-------------------
redeclare function extends isentropicEnthalpy "Return isentropic enthalpy"
algorithm
h_is := cp_const*(temperature(refState) - T0);
end isentropicEnthalpy;
//-------------------
redeclare function extends isobaricExpansionCoefficient
"Returns overall the isobaric expansion coefficient beta"
algorithm
beta := 0.0;
end isobaricExpansionCoefficient;
//-------------------
redeclare function extends isothermalCompressibility
"Returns overall the isothermal compressibility factor"
algorithm
kappa := 0;
end isothermalCompressibility;
//-------------------
redeclare function extends density_derp_T
"Returns the partial derivative of density with respect to pressure at constant temperature"
algorithm
ddpT := 0;
end density_derp_T;
//-------------------
redeclare function extends density_derT_p
"Returns the partial derivative of density with respect to temperature at constant pressure"
algorithm
ddTp := 0;
end density_derT_p;
//-------------------
redeclare function extends density_derX
"Returns the partial derivative of density with respect to mass fractions at constant pressure and temperature"
algorithm
dddX := fill(0, nX);
end density_derX;
//-------------------
redeclare function extends molarMass "Return the molar mass of the medium"
algorithm
//MM := MM_const;
MM := 1/sum(state.X[j]/MMX[j] for j in 1:size(state.X,1));
end molarMass;
// functions that have been adopted from class PARTIALMIXTUREMEDIUM
// -----------------
replaceable function gasConstant
"Return the gas constant of the mixture (also for liquids)"
extends Modelica.Icons.Function;
input ThermodynamicState state "Thermodynamic state";
output SI.SpecificHeatCapacity R "Mixture gas constant";
algorithm
R := 0;
end gasConstant;
// -----------------
function moleToMassFractions "Return mass fractions X from mole fractions"
extends Modelica.Icons.Function;
input SI.MoleFraction moleFractions[:] "Mole fractions of mixture";
input MolarMass[:] MMX "Molar masses of components";
output SI.MassFraction X[size(moleFractions, 1)]
"Mass fractions of gas mixture";
protected
MolarMass Mmix=moleFractions*MMX "Molar mass of mixture";
algorithm
for i in 1:size(moleFractions, 1) loop
X[i] := moleFractions[i]*MMX[i]/Mmix;
end for;
annotation (smoothOrder=5);
end moleToMassFractions;
// -----------------
function massToMoleFractions "Return mole fractions from mass fractions X"
extends Modelica.Icons.Function;
input SI.MassFraction X[:] "Mass fractions of mixture";
input SI.MolarMass[:] MMX "Molar masses of components";
output SI.MoleFraction moleFractions[size(X, 1)]
"Mole fractions of gas mixture";
protected
Real invMMX[size(X, 1)] "Inverses of molar weights";
SI.MolarMass Mmix "Molar mass of mixture";
algorithm
for i in 1:size(X, 1) loop
invMMX[i] := 1/MMX[i];
end for;
Mmix := 1/(X*invMMX);
for i in 1:size(X, 1) loop
moleFractions[i] := Mmix*X[i]/MMX[i];
end for;
annotation (smoothOrder=5);
end massToMoleFractions;
end SimpleMachineStockMedium_323_v2;
使用介质 JA 塞流组件的模拟模型
// file: delay_test_05c.mo
model delay_test_05c
replaceable package Medium = SimpleMachineStockMedium_323_v2; // constrainedby Modelica.Media.Interfaces.PartialMedium "Medium in the component";
Modelica.Fluid.Vessels.OpenTank tank_A (
redeclare package Medium = Medium,
X_start = {0.8, 0.1, 0.1},
crossArea = 5,
height = 10,
level(fixed = true, start = 3),
m_flow_nominal=20,
nPorts = 3,
portsData = {
Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 0),
Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 1),
Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 1)
},
use_portsData = true
)
annotation(
Placement(visible = true, transformation(origin = {-36, -6}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Fluid.Vessels.OpenTank tank_B (
redeclare package Medium = Medium,
X_start = {0.4, 0.4, 0.2},
crossArea = 5,
height = 10,
level(fixed = true, start = 2.5),
m_flow_nominal=10,
nPorts = 2,
portsData = {
Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 1),
Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 2)
},
use_portsData = true)
annotation(
Placement(visible = true, transformation(origin = {52, 26}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Fluid.Vessels.OpenTank tank_C (
redeclare package Medium = Medium,
X_start = {0.3, 0.3, 0.4},
crossArea = 5,
height = 10,
level(fixed = true, start = 2.5),
m_flow_nominal=10,
nPorts = 2,
portsData = {Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 1),
Modelica.Fluid.Vessels.BaseClasses.VesselPortsData(diameter = 0.3, height = 2)
},
use_portsData = true
)
annotation(
Placement(visible = true, transformation(origin = {54, -48}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
Modelica.Fluid.Sources.Boundary_pT Sink_B( redeclare package Medium = Medium, use_p_in = false, nPorts = 1) annotation(
Placement(visible = true, transformation(origin = {162, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Fluid.Sources.Boundary_pT Sink_C (redeclare package Medium = Medium, T = 273, p = 101325, nPorts = 1) annotation(
Placement(visible = true, transformation(origin = {184, -64}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Fluid.Sources.MassFlowSource_T source_A(
redeclare package Medium = Medium,
T = 320, X = {0.9, 0.05, 0.05}, m_flow = 20,
nPorts = 1, use_T_in = false, use_X_in = false, use_m_flow_in = false
)
annotation(
Placement(visible = true, transformation(origin = {-138, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Fluid.Pipes.StaticPipe pipe_A_to_B(
redeclare package Medium = Medium,
allowFlowReversal = false,
diameter = 0.3,
height_ab = 0,
length = 5)
annotation(
Placement(visible = true, transformation(origin = {14, -8}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
inner Modelica.Fluid.System system(allowFlowReversal = false) annotation(
Placement(visible = true, transformation(origin = {-86, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Fluid.Pipes.StaticPipe tank_B_to_sink(
redeclare package Medium = Medium,
allowFlowReversal = false,
diameter = 0.3,
height_ab = 0,
length = 5) annotation(
Placement(visible = true, transformation(origin = {110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Fluid.Pipes.StaticPipe tank_C_to_sink(
redeclare package Medium = Medium,
allowFlowReversal = false,
diameter = 0.3,
height_ab = 0,
length = 5) annotation(
Placement(visible = true, transformation(origin = {118, -60}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Fluid.Pipes.StaticPipe staticPipe_Source_to_A(
redeclare package Medium = Medium,
allowFlowReversal = false,
diameter = 0.3,
height_ab = 0,
length = 5) annotation(
Placement(visible = true, transformation(origin = {-92, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Buildings.Fluid.FixedResistances.PlugFlowPipe plugFlowPipe_A_to_C(
redeclare package Medium = Medium,
T_start_in(displayUnit = "K") =323.15,
T_start_out(displayUnit = "K") =323.15, cPip = 500,
dIns = 0.05,
dh = 0.5, initDelay = false,
kIns = 0.028,
length = 100,
m_flow_nominal = 10,
m_flow_start = 0,
nPorts = 1, rhoPip = 8000, thickness = 0.0032)
annotation(
Placement(visible = true, transformation(origin = {-10, -62}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
// HEAT SINK FOR PLUG FLOW PIPE
Buildings.HeatTransfer.Sources.FixedTemperature heatSink(T(displayUnit = "K") = 283.15) annotation(
Placement(visible = true, transformation(origin = {-98, -58}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(source_A.ports[1], staticPipe_Source_to_A.port_a) annotation(
Line(points = {{-128, -20}, {-102, -20}}, color = {0, 127, 255}));
connect(staticPipe_Source_to_A.port_b, tank_A.ports[1]) annotation(
Line(points = {{-82, -20}, {-68, -20}, {-68, -42}, {-36, -42}, {-36, -26}}, color = {0, 127, 255}));
connect(tank_A.ports[2], pipe_A_to_B.port_a) annotation(
Line(points = {{-36, -26}, {-30, -26}, {-30, -38}, {-8, -38}, {-8, -8}, {4, -8}}, color = {0, 127, 255}));
connect(pipe_A_to_B.port_b, tank_B.ports[1]) annotation(
Line(points = {{24, -8}, {52, -8}, {52, 6}}, color = {0, 127, 255}));
connect(tank_B.ports[2], tank_B_to_sink.port_a) annotation(
Line(points = {{52, 6}, {60, 6}, {60, 0}, {100, 0}}, color = {0, 127, 255}));
connect(tank_B_to_sink.port_b, Sink_B.ports[1]) annotation(
Line(points = {{120, 0}, {132, 0}, {132, 2}, {172, 2}}, color = {0, 127, 255}));
connect(tank_A.ports[3], plugFlowPipe_A_to_C.port_a) annotation(
Line(points = {{-36, -26}, {-32, -26}, {-32, -62}, {-20, -62}}, color = {0, 127, 255}));
connect(plugFlowPipe_A_to_C.ports_b[1], tank_C.ports[1]) annotation(
Line(points = {{0, -62}, {12, -62}, {12, -86}, {52, -86}, {52, -68}, {54, -68}}, color = {0, 127, 255}));
connect(plugFlowPipe_A_to_C.heatPort, heatSink.port) annotation(
Line(points = {{-10, -52}, {-66, -52}, {-66, -58}, {-88, -58}}, color = {191, 0, 0}));
connect(tank_C.ports[2], tank_C_to_sink.port_a) annotation(
Line(points = {{54, -68}, {64, -68}, {64, -82}, {86, -82}, {86, -60}, {108, -60}}, color = {0, 127, 255}));
connect(tank_C_to_sink.port_b, Sink_C.ports[1]) annotation(
Line(points = {{128, -60}, {152, -60}, {152, -64}, {194, -64}}, color = {0, 127, 255}));
annotation(
uses(Modelica(version = "3.2.3"), Buildings(version = "8.1.0")),
Diagram(coordinateSystem(extent = {{-160, 100}, {200, -100}})),
version = "");
end delay_test_05c;
【问题讨论】:
-
Modelica Buildings Library 的最新(未发布)版本支持 MSL 4.0.0。你可以从 GitHub 下载:github.com/lbl-srg/modelica-buildings
-
仍在努力使用 PlugFlowPipe 组件。最终复制了 plugflowpipe 示例并对其进行了修改以测试介质模型。这个问题的后续在:stackoverflow.com/questions/70922397/…
标签: modelica openmodelica