Problems building up a simple DCDC converter in Modelica - modelica
I want to write a very simple model for a DCDC converter. For some reason, Dymola tells me that the "model is not well-posed" and overdetermined for Real elements.
It might be a quite simple problem but I can't see it!
Here's my code:
model DCDC
extends Modelica.Electrical.Analog.Interfaces.TwoPort;
parameter Real demandedVoltage;
Modelica.Electrical.Analog.Sensors.VoltageSensor sekVolt annotation (
Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={80,0})));
Modelica.Electrical.Analog.Sensors.CurrentSensor currentSensor annotation (
Placement(transformation(
extent={{-10,10},{10,-10}},
rotation=270,
origin={-50,-30})));
Modelica.Electrical.Analog.Sources.SignalCurrent signalCurrent annotation (
Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={-50,30})));
Modelica.Electrical.Analog.Sources.ConstantVoltage constantVoltage(V=
vehicleVoltage)
annotation (Placement(transformation(
extent={{-10,10},{10,-10}},
rotation=270,
origin={50,30})));
Modelica.Electrical.Analog.Sensors.CurrentSensor currentSensor1 annotation (
Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={50,-30})));
Modelica.Blocks.Math.Division division
annotation (Placement(transformation(extent={{6,22},{-10,38}})));
Modelica.Blocks.Math.Product product
annotation (Placement(transformation(extent={{8,-8},{-8,8}},
rotation=270,
origin={30,8})));
Modelica.Blocks.Math.Gain gain(k=-1)
annotation (Placement(transformation(extent={{-20,22},{-36,38}})));
Modelica.Electrical.Analog.Sensors.VoltageSensor primVolt
annotation (
Placement(transformation(
extent={{-10,10},{10,-10}},
rotation=270,
origin={-80,0})));
equation
connect(currentSensor.p, signalCurrent.n) annotation (Line(
points={{-50,-20},{-50,20}},
color={0,0,255},
smooth=Smooth.None));
connect(constantVoltage.n, currentSensor1.p) annotation (Line(
points={{50,20},{50,-20}},
color={0,0,255},
smooth=Smooth.None));
connect(signalCurrent.p, p1) annotation (Line(
points={{-50,40},{-50,50},{-100,50}},
color={0,0,255},
smooth=Smooth.None));
connect(currentSensor.n, n1) annotation (Line(
points={{-50,-40},{-50,-50},{-100,-50}},
color={0,0,255},
smooth=Smooth.None));
connect(constantVoltage.p, p2) annotation (Line(
points={{50,40},{50,50},{100,50}},
color={0,0,255},
smooth=Smooth.None));
connect(currentSensor1.n, n2) annotation (Line(
points={{50,-40},{50,-50},{100,-50}},
color={0,0,255},
smooth=Smooth.None));
connect(primVolt.n, n1) annotation (Line(
points={{-80,-10},{-80,-50},{-100,-50}},
color={0,0,255},
smooth=Smooth.None));
connect(primVolt.p, p1) annotation (Line(
points={{-80,10},{-80,50},{-100,50}},
color={0,0,255},
smooth=Smooth.None));
connect(sekVolt.p, p2) annotation (Line(
points={{80,10},{80,50},{100,50}},
color={0,0,255},
smooth=Smooth.None));
connect(sekVolt.n, n2) annotation (Line(
points={{80,-10},{80,-50},{100,-50}},
color={0,0,255},
smooth=Smooth.None));
connect(gain.y, signalCurrent.i) annotation (Line(
points={{-36.8,30},{-43,30}},
color={0,0,127},
smooth=Smooth.None));
connect(division.y, gain.u) annotation (Line(
points={{-10.8,30},{-18.4,30}},
color={0,0,127},
smooth=Smooth.None));
connect(currentSensor1.i, product.u2) annotation (Line(
points={{40,-30},{25.2,-30},{25.2,-1.6}},
color={0,0,127},
smooth=Smooth.None));
connect(sekVolt.v, product.u1) annotation (Line(
points={{70,0},{62,0},{62,-10},{34.8,-10},{34.8,-1.6}},
color={0,0,127},
smooth=Smooth.None));
connect(product.y, division.u1) annotation (Line(
points={{30,16.8},{30,34.8},{7.6,34.8}},
color={0,0,127},
smooth=Smooth.None));
connect(primVolt.v, division.u2) annotation (Line(
points={{-70,0},{14,0},{14,20},{14,20},{14,25.2},{7.6,25.2}},
color={0,0,127},
smooth=Smooth.None));
annotation (
Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,
100}}), graphics), Icon(coordinateSystem(preserveAspectRatio=false,
extent={{-100,-100},{100,100}}), graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,127},
lineThickness=0.5,
fillPattern=FillPattern.Solid,
fillColor={215,215,215}),
Line(
points={{-100,100}},
color={0,0,255},
smooth=Smooth.None),
Line(
points={{-100,100},{-100,-100},{100,-100},{100,100},{-100,100}},
color={0,0,127},
thickness=0.5,
smooth=Smooth.None),
Line(
points={{-100,-100},{100,100}},
color={0,0,127},
thickness=0.5,
smooth=Smooth.None),
Text(
extent={{-60,80},{0,20}},
lineColor={0,0,0},
lineThickness=0.5,
textString="DC"),
Text(
extent={{0,-20},{60,-80}},
lineColor={0,0,0},
lineThickness=0.5,
textString="DC")}));
end DCDC;
Hopefully someone may figure out my problem here.
Thank you in advance!
EDIT:
After the answers I decided to change my model a bit since I need the converter for a hybrid (energy/power) supply. The resulting converter is given in the following code:
model DCDC2 "Component with two electrical ports, including current"
Real v_energy "Voltage drop over the energy port";
Real v_power "Voltage drop over the power port";
Real v_output "Voltage drop over the output port";
Real i_energy "Current flowing from pos. to neg. pin of the energy port";
Real i_power "Current flowing from pos. to neg. pin of the power port";
Real i_output "Current flowing from pos. to neg. pin of the output port";
Real p_energy;
Real p_power;
Real p_output;
parameter Real demandedVoltage;
parameter Real efficiency = 1;
Modelica.Electrical.Analog.Interfaces.PositivePin pinP_Energy
annotation (Placement(transformation(extent={{-110,50},{-90,70}})));
Modelica.Electrical.Analog.Interfaces.NegativePin pinN_Energy
annotation (Placement(transformation(extent={{-110,-70},{-90,-50}})));
Modelica.Electrical.Analog.Interfaces.PositivePin pinP_Power
annotation (Placement(transformation(extent={{90,50},{110,70}})));
Modelica.Electrical.Analog.Interfaces.NegativePin pinN_Power
annotation (Placement(transformation(extent={{90,-70},{110,-50}})));
Modelica.Electrical.Analog.Interfaces.PositivePin pinP_Output
annotation (Placement(transformation(extent={{-20,80},{20,120}})));
Modelica.Electrical.Analog.Interfaces.NegativePin pinN_Output
annotation (Placement(transformation(extent={{-20,-120},{20,-80}})));
equation
v_energy = pinP_Energy.v - pinN_Energy.v;
v_power = pinP_Power.v - pinN_Power.v;
v_output = pinP_Output.v - pinN_Output.v;
0 = pinP_Energy.i + pinN_Energy.i;
0 = pinP_Power.i + pinN_Power.i;
0 = pinP_Output.i + pinN_Output.i;
i_energy = pinP_Energy.i;
i_power = pinP_Power.i;
i_output = pinP_Output.i;
p_energy = v_energy * i_energy;
p_power = v_power * i_power;
p_output = v_output * i_output;
p_output = efficiency*(p_energy + p_power);
i_output = i_energy + i_power;
v_output = demandedVoltage;
annotation (
Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,- 100},{100,
100}}), graphics), Icon(coordinateSystem(preserveAspectRatio=false,
extent={{-100,-100},{100,100}}), graphics={
Rectangle(
extent={{-100,100},{100,-100}},
lineColor={0,0,127},
lineThickness=0.5,
fillPattern=FillPattern.Solid,
fillColor={215,215,215}),
Line(
points={{-100,100}},
color={0,0,255},
smooth=Smooth.None),
Line(
points={{-100,100},{-100,-100},{100,-100},{100,100},{-100,100}},
color={0,0,127},
thickness=0.5,
smooth=Smooth.None),
Text(
extent={{-68,60},{70,-66}},
lineColor={0,0,0},
textString="Hybrid
DC
Converter")}));
end DCDC2;
If I test the converter using two simple constant current sources and one constant current load, I get again a singularity error. Dymola 2015 tells me, that there might be a not determinable ground, which shouldn't be the case.
model test2
Modelica_EnergyStorages.Sources.Loads.BooleanConstantCurrent
booleanConstantCurrent(I=40)
annotation (Placement(transformation(extent={{46,0},{26,20}})));
Modelica.Electrical.Analog.Basic.Ground ground
annotation (Placement(transformation(extent={{-84,-40},{-64,-20}})));
Modelica.Blocks.Sources.BooleanConstant booleanConstant
annotation (Placement(transformation(extent={{66,0},{46,20}})));
Modelica.Electrical.Analog.Basic.Ground ground1
annotation (Placement(transformation(extent={{26,-86},{46,-66}})));
ElectricalEnergyStorageSystem.Components.DCDC2 dCDC2_1(efficiency=1,
demandedVoltage=15)
annotation (Placement(transformation(extent={{-44,0},{-24,20}})));
Modelica.Electrical.Analog.Sources.ConstantCurrent constantCurrent(I=5)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={-74,10})));
Modelica.Electrical.Analog.Sources.ConstantCurrent constantCurrent1(I=15)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}},
rotation=270,
origin={6,10})));
Modelica.Electrical.Analog.Basic.Ground ground2
annotation (Placement(transformation(extent={{-4,-40},{16,-20}})));
equation
connect(booleanConstantCurrent.on, booleanConstant.y) annotation (Line(
points={{45,10},{45,10}},
color={255,0,255},
smooth=Smooth.None));
connect(booleanConstantCurrent.pin_n, ground1.p) annotation (Line(
points={{36,0},{36,-66}},
color={0,0,255},
smooth=Smooth.None));
connect(dCDC2_1.pinP_Output, booleanConstantCurrent.pin_p) annotation (Line(
points={{-34,20},{-34,76},{36,76},{36,20}},
color={0,0,255},
smooth=Smooth.None));
connect(booleanConstantCurrent.pin_n, dCDC2_1.pinN_Output) annotation (Line(
points={{36,0},{36,-54},{-34,-54},{-34,0}},
color={0,0,255},
smooth=Smooth.None));
connect(constantCurrent1.p, dCDC2_1.pinP_Power) annotation (Line(
points={{6,20},{-24,20},{-24,16}},
color={0,0,255},
smooth=Smooth.None));
connect(constantCurrent1.n, dCDC2_1.pinN_Power) annotation (Line(
points={{6,0},{-24,0},{-24,4}},
color={0,0,255},
smooth=Smooth.None));
connect(constantCurrent.p, dCDC2_1.pinP_Energy) annotation (Line(
points={{-74,20},{-44,20},{-44,16}},
color={0,0,255},
smooth=Smooth.None));
connect(constantCurrent.n, dCDC2_1.pinN_Energy) annotation (Line(
points={{-74,0},{-44,0},{-44,4}},
color={0,0,255},
smooth=Smooth.None));
connect(constantCurrent1.n, ground2.p) annotation (Line(
points={{6,0},{6,-20}},
color={0,0,255},
smooth=Smooth.None));
connect(ground.p, constantCurrent.n) annotation (Line(
points={{-74,-20},{-74,0}},
color={0,0,255},
smooth=Smooth.None));
annotation (uses(
Modelica_EnergyStorages(version="3.2.1"),
Modelica(version="3.2.1"),
Buildings(version="2.0.0")), Diagram(coordinateSystem(preserveAspectRatio
=false, extent={{-100,-100},{100,100}}), graphics));
end test2;
And the code results in the following model. (Constant current load is from the Modelica_EnergyStorages library)
Hope you can somehow help me with that issue! Thanks in advance!
The only small problem is that you have declared demandedVoltage but you use vehicleVoltage. Nothing else is wrong with your model.
Note: It would be better to include a minimal top-model for testing in the question.
I tested your model in a top-model TestDCDC together with a capacitor as power supply and a resistor as load in SimulationX 3.6.5.
The following picture shows the schematic of the test model.
The results obtained with SimulationX are depicted in the following figure.
I also checked the equation system generated by SimulationX. It looks fine.
Dymola 2015 generates a wrong error message saying that there are two more variables than equations. You should issue a bug-report for this model to the producer of Dymola. Note, that the symbolic analysis of Modelica models is quite complicated and problems like that may happen. Usually the maintainer of the tool is grateful for a bug-report in this case.
Discussion of the solution:
The DCDC converter demands a constant power of P=100W from the capacitor and the initial voltage of the capacitor is capacitor1.v.start=10 V.
This gives an energy-time signal of
W = C/2*(v.start)^2-P*time = 50Ws - 100W*time
and the capacitor voltage signal results to
capacitor1.v = 2*sqrt(W)/C = 2V/As * sqrt(50Ws-100Ws*time)
At time = 0.5s the capacitor is empty and the current diverges.
SimulationX stops correctly with an error message at time=0.5.
Complete model for reproducing the results:
model TestDCDC
model DCDC
extends Modelica.Electrical.Analog.Interfaces.TwoPort;
parameter Real demandedVoltage;
Modelica.Electrical.Analog.Sensors.VoltageSensor sekVolt annotation(Placement(transformation(
origin={80,0},
extent={{-10,-10},{10,10}},
rotation=270)));
Modelica.Electrical.Analog.Sensors.CurrentSensor currentSensor annotation(Placement(transformation(
origin={-50,-30},
extent={{-10,10},{10,-10}},
rotation=270)));
Modelica.Electrical.Analog.Sources.SignalCurrent signalCurrent annotation(Placement(transformation(
origin={-50,30},
extent={{-10,-10},{10,10}},
rotation=270)));
Modelica.Electrical.Analog.Sources.ConstantVoltage constantVoltage(V=demandedVoltage) annotation(Placement(transformation(
origin={50,30},
extent={{-10,10},{10,-10}},
rotation=270)));
Modelica.Electrical.Analog.Sensors.CurrentSensor currentSensor1 annotation(Placement(transformation(
origin={50,-30},
extent={{-10,-10},{10,10}},
rotation=270)));
Modelica.Blocks.Math.Division division annotation(Placement(transformation(extent={{6,22},{-10,38}})));
Modelica.Blocks.Math.Product product annotation(Placement(transformation(
origin={30,8},
extent={{8,-8},{-8,8}},
rotation=270)));
Modelica.Blocks.Math.Gain gain(k=-1) annotation(Placement(transformation(extent={{-20,22},{-36,38}})));
Modelica.Electrical.Analog.Sensors.VoltageSensor primVolt annotation(Placement(transformation(
origin={-80,0},
extent={{-10,10},{10,-10}},
rotation=270)));
equation
connect(currentSensor.p,signalCurrent.n) annotation(Line(points={{-50,-20},{-50,-15},{-50,15},{-50,20}}));
connect(constantVoltage.n,currentSensor1.p) annotation(Line(points={{50,20},{50,15},{50,-15},{50,-20}}));
connect(signalCurrent.p,p1) annotation(Line(points={{-50,40},{-50,45},{-50,50},{-95,50},{-100,50}}));
connect(currentSensor.n,n1) annotation(Line(points={{-50,-40},{-50,-45},{-50,-50},{-95,-50},{-100,-50}}));
connect(constantVoltage.p,p2) annotation(Line(points={{50,40},{50,45},{50,50},{95,50},{100,50}}));
connect(currentSensor1.n,n2) annotation(Line(points={{50,-40},{50,-45},{50,-50},{95,-50},{100,-50}}));
connect(primVolt.n,n1) annotation(Line(points={{-80,-10},{-80,-15},{-80,-50},{-95,-50},{-100,-50}}));
connect(primVolt.p,p1) annotation(Line(points={{-80,10},{-80,15},{-80,50},{-95,50},{-100,50}}));
connect(sekVolt.p,p2) annotation(Line(points={{80,10},{80,15},{80,50},{95,50},{100,50}}));
connect(sekVolt.n,n2) annotation(Line(points={{80,-10},{80,-15},{80,-50},{95,-50},{100,-50}}));
connect(gain.y,signalCurrent.i) annotation(Line(
points={{-36.7,30},{-41.7,30},{-38,30},{-43,30}},
color={0,0,127}));
connect(division.y,gain.u) annotation(Line(
points={{-10.7,30},{-15.7,30},{-13.3,30},{-18.3,30}},
color={0,0,127}));
connect(currentSensor1.i,product.u2) annotation(Line(
points={{40,-30},{35,-30},{25.3,-30},{25.3,-6.7},{25.3,-1.7}},
color={0,0,127}));
connect(sekVolt.v,product.u1) annotation(Line(
points={{70,0},{65,0},{65,-6.7},{34.7,-6.7},{34.7,-1.7}},
color={0,0,127}));
connect(product.y,division.u1) annotation(Line(
points={{30,16.7},{30,21.7},{30,34.7},{12.7,34.7},{7.7,34.7}},
color={0,0,127}));
connect(primVolt.v,division.u2) annotation(Line(
points={{-70,0},{-65,0},{12.7,0},{12.7,25.3},{7.7,25.3}},
color={0,0,127}));
annotation(
Icon(
coordinateSystem(preserveAspectRatio=false),
graphics={
Rectangle(
lineColor={0,0,127},
fillColor={215,215,215},
fillPattern=FillPattern.Solid,
lineThickness=0.5,
extent={{-100,100},{100,-100}}),
Line(
points={{-100,100}}),
Line(
points={{-100,100},{-100,-100},{100,-100},{100,100},{-100,100}},
color={0,0,127},
thickness=0.5),
Line(
points={{-100,-100},{100,100}},
color={0,0,127},
thickness=0.5),
Text(
textString="DC",
lineThickness=0.5,
extent={{-60,80},{0,20}}),
Text(
textString="DC",
lineThickness=0.5,
extent={{0,-20},{60,-80}})}),
Diagram(coordinateSystem(preserveAspectRatio=false)));
end DCDC;
DCDC dcdc(demandedVoltage=10) annotation(Placement(transformation(extent={{-30,30},{-10,50}})));
Modelica.Electrical.Analog.Basic.Ground ground1 annotation(Placement(transformation(extent={{-85,-5},{-65,15}})));
Modelica.Electrical.Analog.Basic.Resistor resistor1(R=2) annotation(Placement(transformation(
origin={35,40},
extent={{-10,-10},{10,10}},
rotation=-90)));
Modelica.Electrical.Analog.Basic.Ground ground2 annotation(Placement(transformation(extent={{0,-5},{20,15}})));
Modelica.Electrical.Analog.Basic.Capacitor capacitor1(
v(
start=10,
fixed=true),
C=1) annotation(Placement(transformation(
origin={-75,40},
extent={{-10,-10},{10,10}},
rotation=-90)));
equation
connect(resistor1.p,dcdc.p2) annotation(Line(
points={{35,50},{35,55},{15,55},{15,45},{-5,45},{-10,
45}},
thickness=0.0625));
connect(resistor1.n,dcdc.n2) annotation(Line(
points={{35,30},{35,25},{15,25},{15,35},{-5,35},{-10,
35}},
thickness=0.0625));
connect(ground2.p,dcdc.n2) annotation(Line(
points={{10,15},{10,20},{10,35},{-5,35},{-10,35}},
thickness=0.0625));
connect(dcdc.p1,capacitor1.p) annotation(Line(
points={{-30,45},{-35,45},{-35,55},{-75,55},{-75,50}},
thickness=0.0625));
connect(dcdc.n1,capacitor1.n) annotation(Line(
points={{-30,35},{-35,35},{-35,25},{-75,25},{-75,30}},
thickness=0.0625));
connect(ground1.p,capacitor1.n) annotation(Line(
points={{-75,15},{-75,20},{-75,25},{-75,30}},
thickness=0.0625));
end TestDCDC;
Related
OpenModelica Building Libary, using PlugFlowPipe component
This question is a continuation to the question: OpenModelica: How to model plug flow for multi substance fluid medium? The modelica does not include by default a medium model supporting multiple substances and trace substances. Therefore, I was putting together a medium model that works fine with basic Modelica fluid components (sources, open tanks, static pipe). However, Buildings library's component Buildings.Fluid.FixedResistances.PlugFlowPipe seems to be problematic and I could not figure out why? I have a very limited experience on OpenModelica and would appreciate if someone could help and point out the reasoning. I have ended up to the Building library since I haven't found any other component in other libraries that would model the plug flow and transfer delays in pipe lines. Below are the medium model and Simulation model that has been used for testing. Medium model used: // file: SimpleMachineStockMedium_400_v1.mo package SimpleMachineStockMedium_400_v1 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_400_v1", 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_s = 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_s "Mixture gas constant"; algorithm R_s := 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_400_v1; PlugFlowPipe model derived from the example : model testing_PlugFlowPipe_example_ver01 "Simple example of plug flow pipe" // Modifications to the example import Buildings = Buildings; import Sources = Buildings.Fluid.Sources; import Sensors = Buildings.Fluid.Sensors; //replaceable package Medium = Buildings.Media.Water; replaceable package Medium = SimpleMachineStockMedium_400_v1; // End of modifications final parameter Modelica.Units.SI.MassFlowRate m_flow_nominal = 3 "Mass flow rate"; Modelica.Blocks.Sources.Ramp Tin(height = 20, duration = 0, offset = 273.15 + 50, startTime = 100) "Ramp pressure signal" annotation( Placement(transformation(extent = {{-100, -10}, {-80, 10}}))); Sources.Boundary_pT sin(redeclare package Medium = Medium, T = 273.15 + 10, nPorts = 2, p(displayUnit = "Pa") = 101325) "Pressure boundary condition" annotation( Placement(transformation(extent = {{100, -10}, {80, 10}}))); Buildings.Fluid.FixedResistances.PlugFlowPipe pip(redeclare package Medium = Medium, dh = 0.1, length = 100, dIns = 0.05, kIns = 0.028, m_flow_nominal = m_flow_nominal, cPip = 500, thickness = 0.0032, initDelay = true, m_flow_start = m_flow_nominal, rhoPip = 8000, T_start_in = 323.15, T_start_out = 323.15) "Pipe" annotation( Placement(transformation(extent = {{0, 10}, {20, 30}}))); Buildings.HeatTransfer.Sources.FixedTemperature bou[2](each T = 283.15) "Boundary temperature" annotation( Placement(transformation(extent = {{-40, 60}, {-20, 80}}))); Buildings.Fluid.Sources.MassFlowSource_T sou(redeclare package Medium = Medium, use_T_in = true, m_flow = m_flow_nominal, nPorts = 1) "Flow source" annotation( Placement(transformation(extent = {{-60, 10}, {-40, 30}}))); Buildings.Fluid.Sensors.TemperatureTwoPort senTemOut(redeclare package Medium = Medium, m_flow_nominal = m_flow_nominal, tau = 0, T_start = 323.15) "Temperature sensor" annotation( Placement(transformation(extent = {{40, 10}, {60, 30}}))); Buildings.Fluid.Sensors.TemperatureTwoPort senTemIn(redeclare package Medium = Medium, m_flow_nominal = m_flow_nominal, tau = 0, T_start = 323.15) "Temperature sensor" annotation( Placement(transformation(extent = {{-30, 10}, {-10, 30}}))); Sensors.TemperatureTwoPort senTemInNoMix(redeclare package Medium = Medium, m_flow_nominal = m_flow_nominal, tau = 0, T_start = 323.15) "Temperature sensor" annotation( Placement(transformation(extent = {{-30, -30}, {-10, -10}}))); Buildings.Fluid.FixedResistances.PlugFlowPipe pipNoMix(have_pipCap = false, redeclare package Medium = Medium, dh = 0.1, length = 100, dIns = 0.05, kIns = 0.028, m_flow_nominal = m_flow_nominal, cPip = 500, thickness = 0.0032, initDelay = true, m_flow_start = m_flow_nominal, rhoPip = 8000, T_start_in = 323.15, T_start_out = 323.15) "Pipe" annotation( Placement(transformation(extent = {{0, -30}, {20, -10}}))); Sensors.TemperatureTwoPort senTemOutNoMix(redeclare package Medium = Medium, m_flow_nominal = m_flow_nominal, tau = 0, T_start = 323.15) "Temperature sensor" annotation( Placement(transformation(extent = {{40, -30}, {60, -10}}))); Sources.MassFlowSource_T souNoMix(redeclare package Medium = Medium, use_T_in = true, m_flow = m_flow_nominal, nPorts = 1) "Flow source" annotation( Placement(transformation(extent = {{-60, -30}, {-40, -10}}))); equation connect(Tin.y, sou.T_in) annotation( Line(points = {{-79, 0}, {-68, 0}, {-68, 24}, {-62, 24}}, color = {0, 0, 127})); connect(pip.port_b, senTemOut.port_a) annotation( Line(points = {{20, 20}, {40, 20}}, color = {0, 127, 255})); connect(senTemOut.port_b, sin.ports[1]) annotation( Line(points = {{60, 20}, {76, 20}, {76, -1}, {80, -1}}, color = {0, 127, 255})); connect(senTemIn.port_b, pip.port_a) annotation( Line(points = {{-10, 20}, {0, 20}}, color = {0, 127, 255})); connect(senTemInNoMix.port_b, pipNoMix.port_a) annotation( Line(points = {{-10, -20}, {0, -20}}, color = {0, 127, 255})); connect(pipNoMix.port_b, senTemOutNoMix.port_a) annotation( Line(points = {{20, -20}, {40, -20}}, color = {0, 127, 255})); connect(senTemOutNoMix.port_b, sin.ports[2]) annotation( Line(points = {{60, -20}, {76, -20}, {76, 1}, {80, 1}}, color = {0, 127, 255})); connect(bou[1].port, pip.heatPort) annotation( Line(points = {{-20, 70}, {-4, 70}, {-4, 40}, {10, 40}, {10, 30}}, color = {191, 0, 0})); connect(bou[2].port, pipNoMix.heatPort) annotation( Line(points = {{-20, 70}, {-4, 70}, {-4, 0}, {10, 0}, {10, -10}}, color = {191, 0, 0})); connect(sou.ports[1], senTemIn.port_a) annotation( Line(points = {{-40, 20}, {-30, 20}}, color = {0, 127, 255})); connect(souNoMix.ports[1], senTemInNoMix.port_a) annotation( Line(points = {{-40, -20}, {-30, -20}}, color = {0, 127, 255})); connect(Tin.y, souNoMix.T_in) annotation( Line(points = {{-79, 0}, {-68, 0}, {-68, -16}, {-62, -16}}, color = {0, 0, 127})); annotation( __Dymola_Commands(file = "modelica://Buildings/Resources/Scripts/Dymola/Fluid/FixedResistances/Examples/PlugFlowPipe.mos" "Simulate and Plot"), experiment(StopTime = 1000, Tolerance = 1e-006), Documentation(info = "<html> <p>Basic test of model <a href=\"modelica://Buildings.Fluid.FixedResistances.PlugFlowPipe\"> Buildings.Fluid.FixedResistances.PlugFlowPipe</a> with and without outlet mixing volume. This test includes an inlet temperature step under a constant mass flow rate. </p> </html>", revisions = "<html> <ul> <li>July 27, 2021 by Baptiste Ravache<br/>Add case without mixing volume</li> </ul> <ul> <li>September 8, 2017 by Bram van der Heijde<br/>First implementation</li> </ul> </html>"), Diagram(coordinateSystem(extent = {{-120, -100}, {120, 100}})), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}))); end testing_PlugFlowPipe_example_ver01; EDIT: Version information: MSL 4.0.0 Buildings library: I was told to use version 9.0.0. The repository https://github.com/lbl-srg/modelica-buildings did not have any specific label for that. I was using the master branch of the repository and the file "modelica-buildings/Buildings/package.mo" gives the version information 9.0.0 (cloned 27.1.2022). Information obtained from the Buildings library through OMEdit Error Message (Intergrator method dassl): Latest Debug message from Transformational debugger Error Message when using rungekutta integrator:
You need the latest development version of Buildings (the master branch; not any released version) because have_pipCap was only introduced in https://github.com/lbl-srg/modelica-buildings/commit/89bf74035bdea926701edef2c3dbf35f48b32680 Without this Buildings version, you will get the message: Error: Modified element have_pipCap not found in class PlugFlowPipe. It is recommended to let the Modelica tool put the annotation uses on the code so the same version can be used for testing. I am assuming this is the problem because the questions did not list the version of Buildings used or the error-message you got.
Compiling of OpenModelica-Model in Twinbuilder
I have a model which is written in Openmodelica. I want to implement this model in Twinbuilder with Modelica. The code of the model is as follows: model SelfActingValve extends Modelica.Fluid.Interfaces.PartialTwoPortTransport; // Import Elements import Modelica.Constants.pi; import Modelica.Constants.g_n; // Thermodynamic states //Medium.ThermodynamicState port_a_state_inflow "State at port_a if inflowing"; //Medium.ThermodynamicState port_b_state_inflow "State at port_b if inflowing"; // Parameter parameter Modelica.SIunits.Length dGap=0.0062 "Mean value of outer diameter of the valve and the diameter of the pipe in front of the valve "; parameter Modelica.SIunits.Angle alpha=pi/2"Angle between the vertical and the bevel edge of the cone valve"; parameter Modelica.SIunits.Length dchamber=0.008"diameter before the valve"; parameter Real gravityAccelerat = g_n; parameter Real cValve = 100 "spring constant/(N/m)"; parameter Modelica.SIunits.Length spPre = 0.0029 "length of the spring preload"; parameter Modelica.SIunits.Length scaleS = 0.0089 "maximum of possible movement of the sprin"; parameter Modelica.SIunits.Mass mValve = 0.000486 "Mass of the valve body"; parameter Modelica.SIunits.Area surfacePorta=1"Surface of the valve at port_a"; parameter Modelica.SIunits.Area surfacePortb=1"Surface of the valve at port_b"; parameter Modelica.SIunits.Volume volValve= 436e-9 "Volume of the valvebody"; parameter Modelica.SIunits.Length dhydro=1.52e-3"hydraulic eyuivalent diameter of the gap "; parameter Boolean outletValve = false "= true --> outletValve, false-->inlet valve" annotation( Dialog(tab = "General"), Evaluate = true); parameter Real kgeo=10"geometric constant"; parameter Real zetaOwn=0.7"loss coeffizient of the valve"; // Variables in the equation //protected // Real zetaOwn_dummy(start=0.7)"dummy for loss coefficient"; // Real zetaOwn(start=0.7) "loss coefficient"; // Real P_lose(start=0); Real x(start = 0, min=0, max=scaleS) "Position of the valve"; Real xdot(start = 0) "velocity of the valve"; Real force0(start = 0) " preload of spring"; Real forceSpr(start = 0) "spring force"; Real dummydot(start = 0) "first derrivative dummy"; Real forcePress(start=0); Real forceGrav(start = 0) "Gravity force of valve"; Real forceDamp(start=0)"Damping force from friction"; Real densiWat(start=998.2)"density of the medium"; Real eta(start=1)"dynamic viscosity"; Real thetaStar(start=0)"damping factor"; Real volumstream(start=0); // Real reynold(start=10000)"Reynold number of the fluid before the gap"; // Real psi(start=0.4)"coeffizeint to describe the not equal pressure distribution on the valve"; Real reynoldGap(start=1)"Reynold number of the fluid in the gap"; equation volumstream=m_flow*densiWat; // outflow equation m_flow=x*dGap*pi*densiWat*sin(alpha)*(abs((2*dp)/(zetaOwn*densiWat)))^(1/2); //Ansatz für Lösen der Singularität, aber keine Ergebnisse. // Isenthalpic state transformation (no storage and no loss of energy) port_a.h_outflow = inStream(port_b.h_outflow); port_b.h_outflow = inStream(port_a.h_outflow); // Fence modelation if dummydot < 0 and x<0 then der(xdot) = 0; der(x) = 0; elseif dummydot > 0 and x>scaleS then der(xdot) = 0; der(x) = 0; else if outletValve == true then der(xdot) = 1 / mValve * ((-force0) - forceGrav - forceSpr + forcePress-forceDamp*xdot); // der(xdot) = 1 / mValve * ((-force0) - forceGrav - forceSpr + forcePress); xdot = der(x); else der(xdot) = 1 / mValve * ((-force0) + forceGrav - forceSpr+ forcePress-forceDamp*xdot); // der(xdot) = 1 / mValve * ((-force0) + forceGrav - forceSpr+ forcePress); xdot = der(x); end if; // This If loop is for the direction of the Forces, e.g. Depending if we have a outlet or a inlet valve the pressure force appeals in different directions. end if; // This If loop is for modelling of the fences of the valve when dummydot < 0 and x<0 then // xdotnew=if edge(impact) then 0 else xdot; reinit(xdot, 0); elsewhen dummydot > 0 and x> scaleS then // xdotnew=if edge(impact) then 0 else xdot; reinit(xdot, 0); end when; // This when loop reinitializes the speed and the accleration of the valve, when it hit the fences. // equation of motion and force definition if outletValve == true then dummydot = 1 / mValve * ((-force0) - forceGrav - forceSpr+ forcePress-forceDamp*xdot ); // dummydot = 1 / mValve * ((-force0) - forceGrav - forceSpr+ forcePress ); else dummydot = 1 / mValve * ((-force0) + forceGrav - forceSpr + forcePress-forceDamp*xdot); // dummydot = 1 / mValve * ((-force0) + forceGrav - forceSpr + forcePress); end if; // This If loop is for the direction of the Forces, e.g. Depending if we have a outlet or a inlet valve the pressure force appeals in different directions. Dummydot is to calculate the actual acceleration to see, if we get away from the fences. force0 = spPre * cValve "preload of the spring"; forcePress= port_a.p*surfacePorta-port_b.p*surfacePortb"Force of the pressures acting on the valve"; forceSpr = cValve * x"force of the spring due to movements of the valve"; forceGrav = gravityAccelerat*( mValve -densiWat*volValve) "Gravity of the valve"; forceDamp=thetaStar*eta*dGap/kgeo"damping force"; thetaStar=10*reynoldGap+505"help variable for caculation forceDamp"; // psi=0.82-1.6*x/dGap-0.075*log(abs(reynold)); //zetaOwn=280/reynoldGap+1; eta = if m_flow > 0 then Medium.dynamicViscosity(state_a) else Medium.dynamicViscosity(state_b); densiWat=if m_flow>0 then Medium.density(state_a) else Medium.density(state_b); if x< scaleS/1000 then reynoldGap=0; // reynold=1; else reynoldGap=4*m_flow/(pi*2*x*sin(alpha)*eta); // reynold=4*m_flow/(pi*dchamber*eta); end if; // if loop: First fix for to big Reynold number in case of nearly closed valve positions annotation(Icon(coordinateSystem( preserveAspectRatio=true, extent={{-100,-100},{100,100}}), graphics={ Line(points={{0,50},{0,0}}), Rectangle( extent={{-20,60},{20,50}}, fillPattern=FillPattern.Solid), Polygon( points={{-100,50},{100,-50},{100,50},{0,0},{-100,-50},{-100,50}}, fillColor={255,255,255}, fillPattern=FillPattern.Solid), Polygon( points=DynamicSelect({{-100,0},{100,-0},{100,0},{0,0},{-100,-0},{-100, 0}}, {{-100,50*opening},{-100,50*opening},{100,-50*opening},{ 100,50*opening},{0,0},{-100,-50*opening},{-100,50*opening}}), fillColor={0,255,0}, lineColor={255,255,255}, fillPattern=FillPattern.Solid), Polygon(points={{-100,50},{100,-50},{100,50},{0,0},{-100,-50},{-100, 50}})}),Documentation(info="<html> <p> This model is build up witht the equations of the doctoral degree thesis ofErwin Thiel at the University Erlangen-Nürnberg with the title 'Kinematik und Druckverlust selbsttätiger Ventile oszillierender Verdrängerpumpen'. GENAUERE BESCHREIBUNG FOLGT <p> </html>"),Icon(coordinateSystem(initialScale = 0.1), graphics = {Line(points = {{0, 50}, {0, 0}}), Rectangle(fillPattern = FillPattern.Solid, extent = {{-20, 60}, {20, 50}}), Polygon(fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, points = {{-100, 50}, {100, -50}, {100, 50}, {0, 0}, {-100, -50}, {-100, 50}}), Polygon(lineColor = {255, 255, 255}, fillColor = {0, 255, 0}, fillPattern = FillPattern.Solid, points = {{-100, 0}, {100, 0}, {100, 0}, {0, 0}, {-100, 0}, {-100, 0}}), Polygon(points = {{-100, 50}, {100, -50}, {100, 50}, {0, 0}, {-100, -50}, {-100, 50}})}), uses(Modelica(version = "3.2.3"))); end SelfActingValve; I get the error when compiling this code in TwinBuilder. The error is : Command GetStaticIconSVG failed with following error: User error: ERROR: The annotation for the icon for SelfActingValve is malformed, cannot generate an icon java exception in java.lang.NullPointerException Do you know how to handle this error? I appreciate your help and time you invest to give the advice.
You have two Icon-annotations, at the end of the model, remove one of them. You can remove the entire annotation if you just want to test it.
Parametrised Modelica library and possibility to use models as parameters - part 2
I work with understanding how parametrized packages in a library can be adapted to external application code, i.e. I like to keep library code and application code very separate. In my example here I have two parameters of my package Equipment, a connector LCon and also a model CType. The connector affect all models in the Equipment package. The model CType only affects one model RType in the Equipment (and have a closer inner-outer relation) to that model. When I adapt the package Equipment to the application requirement of LCon2 and CTyp2 I can do that in one sweep as below. code1 package Equipment2 import BR5i.Equipment; extends Equipment(redeclare connector LCon=LCon2, redeclare model CType=CType2); end Equipment2; However, I think the code (in the long run) is more readable if I divide these two adaptations to two different parts. I try the code below, but does not work. Error text: Cannot find class declaration for RType - when I run it in JModelica. code2 package Equipment2 import BR5i.Equipment; extends Equipment(redeclare connector LCon=LCon2); end Equipment2; model BRType2 import BR5i.Equipment2.RType; extends RType(redeclare model CType=CType2); end BRType2; (And for code 2 the library was modified so the parameter CType was moved Equipment level down to the individual model RType where CType should serve as a parameter. And in the end I want BRType2 for code 2 correspond to Equipment2.RType from code 1). I wonder if it is at all possible to make changes in several steps like this, i.e. first RType get a new connector LCon2 and then in the next step RType now imported from Equipment2 shall get CType replaced to CType2? I understand that the code should not be seen as a sequence of "assignment statements", but rather parallel. In my eyes the logic of the "equations" in code 2 should make it possible to get a correct BRType2.
Your "code2" would result in BRType2 not having CType modified. A redeclare does not mean "change package A to look like this", but rather "this should be like package A, but with these changes". So to get the result you want, you should do something like: package Equipment2 import BR5i.Equipment; extends Equipment(redeclare connector LCon=LCon2); end Equipment2; model BRType2 // Equipment2 has the change in LCon, so extend RType from there instead import Equipment2.RType; extends RType(redeclare model CType=CType2); end BRType2; Also note that this approach will not give the expected results if Equipment contains any instances of or other references to Rtype, as they would refer to the unchanged RType, not to BRType2. Why you get the error about not finding RType, I can't say. It could plausibly be a bug, but I'd first check to see if you have written the path to it correctly.
On request I here supply a small self-contained example, about 150 lines. I decided to re-use my toy-example used in a couple of other posts recently and now add on what is needed to exemplify the problem discussed here. It means I use different names of things compared to what is written above, but the structure of the problem is exactly the same. The toy-example describe pumping of a medium from one vessel to another and is made general so that we can easily change medium and the equipment of pumps and tanks are automatically updated. Originally the medium contain two substances. With a separate short application code we define a medium with more components and update the package Equipment by redeclaring the connector LiquidCon and then system setup is simply re-used. Now I add on an inner model to the harvest that describe some reaction between the substances. Originally we have a reaction model NoReaction that leave the substances in the harvest tank without any reaction. Another reaction model is Reaction 3 that shows degradation of substance 3. The problem I want to highlight is that if we first adapt the equipment with a connector for say three substances. And then in a second round change the reaction model of the adapted equipment3 to a reaction model Reaction3, then JModelica compiler gives error message, while OpenModelica does not and produce simulation resultat that are ok. This is marked Alternative 2 in the code. Alternative 1. On other hand if the two very different re-declrations are done at the same time, i.e. both changed connector LiquidCon and model ReactionType then it works in both JModelica and OpenModelica. Below self-contained code and the example Test now is Alternative 2 and generates error in JModelica 2.4 but works in OpenModelica. Not clear to me what to expect from the Modelica def itself. package DEMO_v14 // Here I have put together a small demo-library to illustrate questions // around structuring handling of medium. The key structures are taken // from MSL fluid, I think it is fair to say. // Author: Jan Peter Axelsson // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium2 replaceable constant String name = "Two components" "Medium name"; replaceable constant Integer nc = 2 "Number of substances"; replaceable type Concentration = Real[nc] "Substance conc"; replaceable constant Real[nc] mw = {10, 20} "Substance weight"; constant Integer A = 1 "Substance index"; constant Integer B = 2 "Substance index"; end Medium2; package Medium3 import M2 = DEMO_v14.Medium2; extends M2 (name="Three components" "Medium name", nc=3 "Number of substances", mw = cat(1,M2.mw,{30}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; end Medium3; connector LiquidCon3 Medium3.Concentration c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon3; model Reaction3 constant Integer nc = 3; outer Real[nc] c; outer Real[nc] q; equation q[1] = 0; q[2] = 0; q[3] =-c[3]; end Reaction3; // --------------------------------------------------------------------------------------------- // Equipment dependent on the medium // --------------------------------------------------------------------------------------------- package Equipment replaceable connector LiquidCon end LiquidCon; // replaceable model ReactionType // Alternative 1 // end ReactionType; model PumpType LiquidCon inlet, outlet; RealInput Fsp; equation inlet.F = Fsp; connect(outlet, inlet); end PumpType; model FeedtankType LiquidCon outlet; constant Integer medium_nc = size(outlet.c,1); parameter Real[medium_nc] c_in (each unit="kg/m3") = {1.0*k for k in 1:medium_nc} "Feed inlet conc"; parameter Real V_0 (unit="m3") = 100 "Initial feed volume"; Real V(start=V_0, fixed=true, unit="m3") "Feed volume"; equation for i in 1:medium_nc loop outlet.c[i] = c_in[i]; end for; der(V) = outlet.F; end FeedtankType; model HarvesttankType // Connection to reaction replaceable model ReactionType // Alternative 2 end ReactionType; ReactionType reaction; inner Real[medium_nc] c "Substance conc"; inner Real[medium_nc] q "Reaction rate"; LiquidCon inlet, port; constant Integer medium_nc = size(inlet.c,1); parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume"; parameter Real[medium_nc] m_0 (each unit="kg/m3") = zeros(medium_nc) "Initial substance mass"; Real[medium_nc] m (start=m_0, each fixed=true) "Substance mass"; Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume"; equation for i in 1:medium_nc loop der(m[i]) = inlet.c[i]*inlet.F + q[i]; c[i] = m[i]/V; port.c[i] = c[i]; end for; der(V) = inlet.F; end HarvesttankType; model NoReaction constant Integer nc = Medium.nc; outer Real[nc] c; outer Real[nc] q; equation for i in 1:nc loop q[i] = 0; end for; end NoReaction; end Equipment; // --------------------------------------------------------------------------------------------- // Control // --------------------------------------------------------------------------------------------- package Control block FixValueType RealOutput out; parameter Real val=0; equation out = val; end FixValueType; end Control; // --------------------------------------------------------------------------------------------- // Adaptation of library for the actual culture and media // --------------------------------------------------------------------------------------------- // package Equipment3 // Alternative 1 // import DEMO_v14.Equipment; // extends Equipment(redeclare connector LiquidCon=LiquidCon3, // redeclare model ReactionType=Reaction3); // end Equipment3; package Equipment3 // Alternative 2 import DEMO_v14.Equipment; extends Equipment(redeclare connector LiquidCon=LiquidCon3); end Equipment3; model HarvesttankType3 import DEMO_v14.Equipment3.HarvesttankType; extends HarvesttankType(redeclare model ReactionType=Reaction3); end HarvesttankType3; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- model Test Medium3 medium; Equipment3.FeedtankType feedtank; // Equipment3.HarvesttankType harvesttank; // Alternative 1 HarvesttankType3 harvesttank; // Alternative 2 Equipment3.PumpType pump; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end DEMO_v14;
I have not had time to analyze your problem in Detail, but I would like to point out here that if some code is accepted in one tool, but not accepted in the other, it does not necessarily mean the bug is in the tool that does not accept the code. Modelica semantics got quite a bit stricter over time to make Modelica safer to use, and easier to be portable across tools. Since the OpenModelica kernel is one of the oldest ones around, it is known to accept a lot of code that is actually not (anymore in many cases) legal Modelica in the latest versions. Sorry, I don't have the time to analyze this in depth from the Modelica semantics legality point of view. I am in any case convinced that you can achieve what you want to achieve with certainly legal Modelica. Two remarks on modeling practices: It is unsafe, and should be avoided, to have an empty class (connector in your case) as a replaceable class since it can be replaced with anything, which is inherently unsafe. I also think that you can achieve what you want to achieve with a variable length vector in the connector, the connector itself does not need to be replaceable. All the best, /Hubertus
I buy the idea that to make a library package parametrized in a safe way you make the flexibility as “small” as you can. You can in the package have a constant integer nc that you give the number Medium3.nc at the time when you adapt the package. And then the connector LiquidCon is defined inside the package Equipment and have a declaration of concentration vector as Real [nc] c; Other information about the Medium than nc can be brought to the application Test on configuration level rather than as adaptation of the package Equipment, and not discussed in this example but in other related posts. In this way the package adaptation process would be as “safe” as you can. The other adaptation that involves introducing a ReactionType to HarvesttankType (that is now adapted to the actual nc) needs to be very flexible for this library package to be of any interest. What we require from the ReactionType is to have the interface: outer Real(nc] c, q; and that we can describe in a partial model and use the constrainedby construction, to bring some safety. See code DEMO_v17_alt1 and d17_alt1_app7 below. However, I would prefer to write the code as alt2 and keep ReactionType etc defined for HarvesttankType only and not for the whole Equipment package. That would need to allow for a two-step procedure of adaptation of the library. First level adapt the Equipment to the number of medium components. Second level adapt the now adapted HarvesttankType to the ReactionType. This is not possible in JModelica, but actually in OpenModelica. So only alt1 works in JModelica 2.4 while both alt1 and alt2 works in OpenModelica 1.13.2 (and 1.14 beta). What does the current Modelica definition say? The library code DEMO_v17_alt1: package DEMO_v17_alt1 // Here I have put together a small demo-library to illustrate questions // around structuring handling of medium. The key structures are taken // from MSL fluid, I think it is fair to say. // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium2 replaceable constant String name = "Two components" "Medium name"; replaceable constant Integer nc = 2 "Number of substances"; replaceable type Concentration = Real[nc] "Substance conc"; replaceable constant Real[nc] mw = {10, 20} "Substance weight"; constant Integer A = 1 "Substance index"; constant Integer B = 2 "Substance index"; end Medium2; package Medium3 import M2 = DEMO_v17_alt1.Medium2; extends M2 (name="Three components" "Medium name", nc=3 "Number of substances", mw = cat(1,M2.mw,{30}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; end Medium3; model Reaction3 constant Integer nc = 3; outer Real[nc] c; outer Real[nc] q; equation q[1] = 0; q[2] = 0; q[3] =-c[3]; end Reaction3; // --------------------------------------------------------------------------------------------- // Equipment dependent on the medium // --------------------------------------------------------------------------------------------- package Equipment constant Integer nc; connector LiquidCon Real[nc] c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon; replaceable model ReactionType = NoReaction // Alternative 1 constrainedby ReactionTypeInterface; partial model ReactionTypeInterface // Alternative 1 outer Real[nc] c, q; end ReactionTypeInterface; model NoReaction // Alternative 1 extends ReactionTypeInterface; equation for i in 1:nc loop q[i] = 0; end for; end NoReaction; model PumpType LiquidCon inlet, outlet; RealInput Fsp; equation inlet.F = Fsp; connect(outlet, inlet); end PumpType; model FeedtankType LiquidCon outlet; constant Integer medium_nc = size(outlet.c,1); parameter Real[medium_nc] c_in (each unit="kg/m3") = {1.0*k for k in 1:medium_nc} "Feed inlet conc"; parameter Real V_0 (unit="m3") = 100 "Initial feed volume"; Real V(start=V_0, fixed=true, unit="m3") "Feed volume"; equation for i in 1:medium_nc loop outlet.c[i] = c_in[i]; end for; der(V) = outlet.F; end FeedtankType; model HarvesttankType // Connection to reaction // replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface; // Alternative 2 ReactionType reaction; inner Real[medium_nc] c "Substance conc"; inner Real[medium_nc] q "Reaction rate"; LiquidCon inlet, port; constant Integer medium_nc = size(inlet.c,1); parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume"; parameter Real[medium_nc] m_0 (each unit="kg/m3") = zeros(medium_nc) "Initial substance mass"; Real[medium_nc] m (start=m_0, each fixed=true) "Substance mass"; Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume"; equation for i in 1:medium_nc loop der(m[i]) = inlet.c[i]*inlet.F + q[i]; c[i] = m[i]/V; port.c[i] = c[i]; end for; der(V) = inlet.F; end HarvesttankType; end Equipment; // --------------------------------------------------------------------------------------------- // Control // --------------------------------------------------------------------------------------------- package Control block FixValueType RealOutput out; parameter Real val=0; equation out = val; end FixValueType; end Control; // --------------------------------------------------------------------------------------------- // Adaptation of library DEMO_v17_alt1 to Medium3 and Reaction3 // --------------------------------------------------------------------------------------------- package Equipment3 // Alternative 1 import DEMO_v17_alt1.Equipment; extends Equipment(nc=Medium3.nc, redeclare model ReactionType=Reaction3); end Equipment3; // package Equipment3 // Alternative 2 // import DEMO_v17_alt2.Equipment; // extends Equipment(nc=3); // end Equipment3; // model HarvesttankType3 // import DEMO_v17_alt2.Equipment3.HarvesttankType; // extends HarvesttankType(redeclare model ReactionType=Reaction3); // end HarvesttankType3; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- model Test Medium3 medium; Equipment3.FeedtankType feedtank; Equipment3.HarvesttankType harvesttank; // Alternative 1 // HarvesttankType3 harvesttank; // Alternative 2 Equipment3.PumpType pump; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end DEMO_v17_alt1; and the application code d17_alt1_app7 encapsulated package d17_alt1_app7 // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium7 import M2 = DEMO_v17_alt1.Medium2; extends M2 (name = "Seven components" "Medium name", nc = 7 "Number of substances", mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; constant Integer D = 4 "Substance index"; constant Integer E = 5 "Substance index"; constant Integer F = 6 "Substance index"; constant Integer G = 7 "Substance index"; end Medium7; model Reaction7 constant Integer nc = 7; outer Real[nc] c; outer Real[nc] q; equation q[1] = 0; q[2] = 0; q[3] = 0; q[4] = 0; q[5] = 0; q[6] = 0; q[7] =-c[7]; end Reaction7; // --------------------------------------------------------------------------------------------- // Adaptation of library DEMO_v17_alt1 to Medium7 and Reaction7 // --------------------------------------------------------------------------------------------- package Equipment7 import DEMO_v17_alt1.Equipment; extends Equipment(nc=Medium7.nc, redeclare model ReactionType=Reaction7); end Equipment7; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- import DEMO_v17_alt1.Control; model Test Medium7 medium; // Instance not necessary but helpful for user interface Equipment7.PumpType pump; Equipment7.FeedtankType feedtank; Equipment7.HarvesttankType harvesttank; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end d17_alt1_app7;
I have recently got some help on the subject from both people related to Modelon and to OpenModelica and I am grateful for that. Below updated files of the library and the application. The presented code does work in JModelica and OpenModelica and now also in Dymola. A couple of comments to the code errors that are corrected. In the model Test I have the habit to make an instance of the Medium of interest. It is actually not allowed (and not very meaningful either) to make an instance of a package like this in Modelica, although current versions of JModelica and OpenModelica support it. The reason I do this instance of the package Medium is two-fold: I need generally in Test (but not in this example) have access to information in the medium package to make the configuration. For example if I connect a sensor to the harvest tank and that sensor is of gernal type then I need to specify what substance I want to measure and that is best done using the mnemonics for substance position in the state vector store in the package medium. I can of course import the mnemonics I need for the configuration, one by one, but shorter and even more readable to just use the medium package. From the FMU it is good to be able to access the information in the medium package. This package may contain not only mnemonics but also various facts about the medium that we want to make use of when designing a tailer-made user interface for the FMU and interactive simulation. This is what I do in Python using JModelica. This works actually fine as it is now with JModelica and PyFMI but what I have learned is forbidden in Modelica. In several places I transmit the number of components in the medium nc to the different equipment models. And I do this transmission of nc somewhat in-directly using the connector and “measure" the size of the vector. This is not OK to do like this in Modelica at compilation time.Also this works in both JModelica and OpenModelica currently, but not in Dymola. I resolve this by introducing a local constant in the general package Equipment that is unspecified, but given the appropriate number later when the package is adapted to the medium that should be used. Then it get the value medium.nc These modification make the code more generally accepted I hope, and at least works for JModelica, OpenModelica and Dymola. However, I am not too happy with the solutions since it do not address the my uderlying user-requirements as described above. Also, with this “solution”, the “alternative 2” - adaptation of the library in two (or more steps) is not relevant - which after all was the key question in the post. I will try to re-formulate this question with a smaller example in a new post later on. Below the library DEMO_v18_alt1 and then after that the application d18_alt1_app7 package DEMO_v18_alt1 // Here I have put together a small demo-library to illustrate questions // around structuring handling of medium. The key structures are taken // from MSL fluid, I think it is fair to say. // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium2 replaceable constant String name = "Two components" "Medium name"; replaceable constant Integer nc = 2 "Number of substances"; replaceable type Concentration = Real[nc] "Substance conc"; replaceable constant Real[nc] mw = {10, 20} "Substance weight"; constant Integer A = 1 "Substance index"; constant Integer B = 2 "Substance index"; end Medium2; package Medium3 import M2 = DEMO_v18_alt1.Medium2; extends M2 (name="Three components" "Medium name", nc=3 "Number of substances", mw = cat(1,M2.mw,{30}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; end Medium3; model Reaction3 constant Integer nc = 3; outer Real[nc] c; outer Real[nc] q; equation q[1] = 0; q[2] = 0; q[3] =-c[3]; end Reaction3; // --------------------------------------------------------------------------------------------- // Equipment dependent on the medium // --------------------------------------------------------------------------------------------- package Equipment constant Integer nc; connector LiquidCon Real[nc] c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon; replaceable model ReactionType = NoReaction // Alternative 1 constrainedby ReactionTypeInterface; partial model ReactionTypeInterface // Alternative 1 outer Real[nc] c, q; end ReactionTypeInterface; model NoReaction // Alternative 1 extends ReactionTypeInterface; equation for i in 1:nc loop q[i] = 0; end for; end NoReaction; model PumpType LiquidCon inlet, outlet; RealInput Fsp; equation inlet.F = Fsp; connect(outlet, inlet); end PumpType; model FeedtankType LiquidCon outlet; parameter Real[nc] c_in (each unit="kg/m3") = {1.0*k for k in 1:nc} "Feed inlet conc"; parameter Real V_0 (unit="m3") = 100 "Initial feed volume"; Real V(start=V_0, fixed=true, unit="m3") "Feed volume"; equation for i in 1:nc loop outlet.c[i] = c_in[i]; end for; der(V) = outlet.F; end FeedtankType; model HarvesttankType // Connection to reaction // replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface; // Alternative 2 ReactionType reaction; inner Real[nc] c "Substance conc"; inner Real[nc] q "Reaction rate"; LiquidCon inlet, port; parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume"; parameter Real[nc] m_0 (each unit="kg/m3") = zeros(nc) "Initial substance mass"; Real[nc] m (start=m_0, each fixed=true) "Substance mass"; Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume"; equation for i in 1:nc loop der(m[i]) = inlet.c[i]*inlet.F + q[i]; c[i] = m[i]/V; port.c[i] = c[i]; end for; der(V) = inlet.F; end HarvesttankType; end Equipment; // --------------------------------------------------------------------------------------------- // Control // --------------------------------------------------------------------------------------------- package Control block FixValueType RealOutput out; parameter Real val=0; equation out = val; end FixValueType; end Control; // --------------------------------------------------------------------------------------------- // Adaptation of library for the actual culture and media // --------------------------------------------------------------------------------------------- package Equipment3 // Alternative 1 import DEMO_v18_alt1.Equipment; extends Equipment(nc=Medium3.nc, redeclare model ReactionType=Reaction3); end Equipment3; // package Equipment3 // Alternative 2 // import DEMO_v18_alt2.Equipment; // extends Equipment(nc=Medium3.nc); // end Equipment3; // model HarvesttankType3 // import DEMO_v18_alt2.Equipment3.HarvesttankType; // extends HarvesttankType(redeclare model ReactionType=Reaction3); // end HarvesttankType3; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- model Test package medium = DEMO_v18_alt1.Medium3; // Not accessible in FMU though Equipment3.FeedtankType feedtank; Equipment3.HarvesttankType harvesttank; // Alternative 1 // HarvesttankType3 harvesttank; // Alternative 2 Equipment3.PumpType pump; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end DEMO_v18_alt1; and here the application code encapsulated package d18_alt1_app7 // Here I put together an application for 7 substances - print 8 pt // and import code from the library DEMO. // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium7 import M2 = DEMO_v18_alt1.Medium2; extends M2 (name = "Seven components" "Medium name", nc = 7 "Number of substances", mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; constant Integer D = 4 "Substance index"; constant Integer E = 5 "Substance index"; constant Integer F = 6 "Substance index"; constant Integer G = 7 "Substance index"; end Medium7; model Reaction7 constant Integer nc = 7; outer Real[nc] c; outer Real[nc] q; equation q[1] = 0; q[2] = 0; q[3] = 0; q[4] = 0; q[5] = 0; q[6] = 0; q[7] =-c[7]; end Reaction7; // --------------------------------------------------------------------------------------------- // Adaptation of library DEMO_v18_alt1 to Medium7 and Reaction7 // --------------------------------------------------------------------------------------------- package Equipment7 import DEMO_v18_alt1.Equipment; extends Equipment(nc=Medium7.nc, redeclare model ReactionType=Reaction7); end Equipment7; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- import DEMO_v18_alt1.Control; model Test package medium = d18_alt1_app7.Medium7; // Not accessible in FMU though Equipment7.PumpType pump; Equipment7.FeedtankType feedtank; Equipment7.HarvesttankType harvesttank; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end d18_alt1_app7;
Extending packages and access to the content
I continue work on understanding how to best divide code in library and application. In a few previous posts I have worked with a toy example DEMO_xx library with application dxx_app7. Below is a slightly updated version to cover the question here. I have included the possibility to add a sensor to the harvest tank. Now I want to understand how to in application code bring in information from the application Medium7 that is extended from the library Medium2 and use that fully in a new component model in the application. What I understand is that if you import a package that is extended from another package you only get what is the “latest” package and NOT what is built up from through extensions and what is aggregated total Medium7 information. This fact is illustrated in the example by changing the constant SensorX.component from C that works to A or B that does not work. However, if I make a local instance of Medium7 THEN I get the complete information of Medium7. I can do that in SensorX as marked Question 1 - alt 2. I can also do this choice of substrate to measure out in the configuration of the system and marked Question 1 alt 3. This is more readable code I think. But how do I make all of the content of Medium7 available locally? Must I define locally a new constant for every constant I need as I show here with sensorX.component? Generally you may want to in a model have access to various properties of the medium and that is convenient to put in the package Medium Also I wish I could import a connector LiquidCon adapted for Medium7 instead of writing that code once again in package Sensor7. Import as suggested does not work. Is there another way? I have only tested the code in JModelica 2.4 and it might be a bug? Would appreciate some input on these two questions. / Jan Peter Below the application code d12_app7 that is of interest for the questions and then the associated library DEMO_v12. I have marked up with comments changes of code for the two questions and as the code stands it is for question 1 alt 1. encapsulated package d12_app7 // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium7 import M2 = DEMO_v12.Medium2; extends M2 (name = "Seven components" "Medium name", nc = 7 "Number of substances", mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; constant Integer D = 4 "Substance index"; constant Integer E = 5 "Substance index"; constant Integer F = 6 "Substance index"; constant Integer G = 7 "Substance index"; end Medium7; // --------------------------------------------------------------------------------------------- // New sensor introduced in this application for measurement of substance A // --------------------------------------------------------------------------------------------- package Sensor7 connector LiquidCon Medium7.Concentration c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon; model SensorX // import d12_app7.Equipment7.LiquidCon; // Question 2 import d12_app7.Medium7.*; // Question 1 - alt 1 constant Integer component = C; // Question 1 - alt 1 // constant Integer component = d12_app7.Medium7.A; // Question 1 - alt 2 LiquidCon probe; RealOutput out; equation probe.F = 0; out = probe.c[component]; end SensorX; end Sensor7; // --------------------------------------------------------------------------------------------- // Adaptation of library DEMO_v12 to Medium7 // --------------------------------------------------------------------------------------------- package Equipment7 import DEMO_v12.Equipment; extends Equipment(redeclare package Medium=Medium7); end Equipment7; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- import DEMO_v12.Control; model Test Equipment7.Medium medium; // Instance not necessary but helpful for user interface Equipment7.PumpType pump; Equipment7.FeedtankType feedtank; Equipment7.HarvesttankType harvesttank; Sensor7.SensorX sensor; // Question 1 alt 1 and 2 // Sensor7.SensorX sensor(component = medium.A); // Question 1 alt 3 Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); connect(sensor.probe, harvesttank.port); end Test; end d12_app7; And finally the library code DEMO_v12 package DEMO_v12 // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium2 replaceable constant String name = "Two components" "Medium name"; replaceable constant Integer nc = 2 "Number of substances"; replaceable type Concentration = Real[nc] "Substance conc"; replaceable constant Real[nc] mw = {10, 20} "Substance weight"; constant Integer A = 1 "Substance index"; constant Integer B = 2 "Substance index"; end Medium2; package Medium3 import M2 = DEMO_v12.Medium2; extends M2 (name="Three components" "Medium name", nc=3 "Number of substances", mw = cat(1,M2.mw,{30}) "Substance weight", redeclare type Concentration = Real[nc] "Substance conc"); constant Integer C = 3 "Substance index"; end Medium3; // --------------------------------------------------------------------------------------------- // Equipment dependent on the medium // --------------------------------------------------------------------------------------------- package Equipment replaceable package Medium end Medium; connector LiquidCon Medium.Concentration c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon; model PumpType LiquidCon inlet, outlet; RealInput Fsp; equation inlet.F = Fsp; connect(outlet, inlet); end PumpType; model FeedtankType LiquidCon outlet; constant Integer medium_nc = size(outlet.c,1); parameter Real[medium_nc] c_in (each unit="kg/m3") = {1.0*k for k in 1:medium_nc} "Feed inlet conc"; parameter Real V_0 (unit="m3") = 100 "Initial feed volume"; Real V(start=V_0, fixed=true, unit="m3") "Feed volume"; equation for i in 1:medium_nc loop outlet.c[i] = c_in[i]; end for; der(V) = outlet.F; end FeedtankType; model HarvesttankType LiquidCon inlet, port; constant Integer medium_nc = size(inlet.c,1); parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume"; parameter Real[medium_nc] m_0 (each unit="kg/m3") = zeros(medium_nc) "Initial substance mass"; Real[medium_nc] c "Substance conc"; Real[medium_nc] m (start=m_0, each fixed=true) "Substance mass"; Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume"; equation for i in 1:medium_nc loop der(m[i]) = inlet.c[i]*inlet.F; c[i] = m[i]/V; port.c[i] = c[i]; end for; der(V) = inlet.F; end HarvesttankType; end Equipment; // --------------------------------------------------------------------------------------------- // Control // --------------------------------------------------------------------------------------------- package Control block FixValueType RealOutput out; parameter Real val=0; equation out = val; end FixValueType; end Control; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- // package Equipment3 = Equipment(redeclare package Medium=Medium3); // Just shorter version package Equipment3 import DEMO_v12.Equipment; extends Equipment(redeclare package Medium=Medium3); end Equipment3; model Test Equipment3.Medium medium; Equipment3.FeedtankType feedtank; Equipment3.HarvesttankType harvesttank; Equipment3.PumpType pump; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end DEMO_v12;
I have also on this post recently got some help from people related to Modelon-JModelica and to OpenModelica - thank you! Below answers and comments as well as updated code. To make content of Medium7 available we can (likely) do as in the presented code. In my new code I decide what substance to measure not until configuration of the Test model. Therefore I in the model SensorX make a declaration constant Integer component without any value. Note a constant can only be given a value once. To avoid writing the code of LiquidCon a second time it is better to put the code of the sensor model in the extension of package Equipment where adaptation is made to Medium7. In the model Test we need to have access to the mnemonics of components. The construction in the code with an instance of a package is not allowed in Modelica (but still works in JModelica and OpenModelica). A generally accepted way to do is given in the new code. Note that this solution makes the content of the actual Medium not accessible through FMU. To get that accessibility local instances need to be made of various medium constants in the model, as done with name. I have in DEMO_v20.Medium2 taken away “replaceable” in front of constants, and the technique to just give these Medium constants different values in Medium3 is allowed since Modelica 3.2 (but not in 3.1) according to Hans Olsson in a previous post response. I have in DEMO_v20 introduced a partial MediumBase and then Medium2 extends from that and MeiumBase also is constraining type for the formal parameter Medium for package Equipment. The code works for JModelica both running DEMO_v20 alone with the Test example for three substances and together with the application code for seven substances. In OpenModelica only the Test example for three substances work, however. Would appreciate help to get the code working in OpenModelica and to check it in Dymolas as well. Library code DEMO_v20 package DEMO_v20 // Here I have put together a small demo-library to illustrate questions // around structuring handling of medium. The key structures are taken // from MSL fluid, I think it is fair to say. // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; partial package MediumBase constant String name "Medium name"; constant Integer nc "Number of substances"; replaceable type Concentration = Real[nc] "Substance conc"; end MediumBase; package Medium2 extends MediumBase (name="Two components", nc=2); constant Real[nc] mw = {10, 20} "Substance weight"; constant Integer A = 1 "Substance index"; constant Integer B = 2 "Substance index"; end Medium2; package Medium3 import M2 = DEMO_v20.Medium2; extends M2 (name="Three components" "Medium name", nc=3 "Number of substances", mw = cat(1,M2.mw,{30}) "Substance weight"); constant Integer C = 3 "Substance index"; end Medium3; // --------------------------------------------------------------------------------------------- // Equipment dependent on the medium // --------------------------------------------------------------------------------------------- package Equipment replaceable package Medium = MediumBase constrainedby MediumBase; connector LiquidCon Medium.Concentration c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon; model PumpType LiquidCon inlet, outlet; RealInput Fsp; equation inlet.F = Fsp; connect(outlet, inlet); end PumpType; model FeedtankType LiquidCon outlet; constant Integer medium_nc = size(outlet.c,1); parameter Real[medium_nc] c_in (each unit="kg/m3") = {1.0*k for k in 1:medium_nc} "Feed inlet conc"; parameter Real V_0 (unit="m3") = 100 "Initial feed volume"; Real V(start=V_0, fixed=true, unit="m3") "Feed volume"; equation for i in 1:medium_nc loop outlet.c[i] = c_in[i]; end for; der(V) = outlet.F; end FeedtankType; model HarvesttankType LiquidCon inlet, port; constant Integer medium_nc = size(inlet.c,1); parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume"; parameter Real[medium_nc] m_0 (each unit="kg/m3") = zeros(medium_nc) "Initial substance mass"; Real[medium_nc] c "Substance conc"; Real[medium_nc] m (start=m_0, each fixed=true) "Substance mass"; Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume"; equation for i in 1:medium_nc loop der(m[i]) = inlet.c[i]*inlet.F; c[i] = m[i]/V; port.c[i] = c[i]; end for; der(V) = inlet.F; end HarvesttankType; end Equipment; // --------------------------------------------------------------------------------------------- // Control // --------------------------------------------------------------------------------------------- package Control block FixValueType RealOutput out; parameter Real val=0; equation out = val; end FixValueType; end Control; // --------------------------------------------------------------------------------------------- // Adaptation of package Equipment to Medium3 // --------------------------------------------------------------------------------------------- package Equipment3 extends DEMO_v20.Equipment(redeclare package Medium=Medium3); end Equipment3; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- model Test package medium = DEMO_v20.Medium3; // Not accessible in FMU though constant String name = medium.name; // But name here is accessible Equipment3.FeedtankType feedtank; Equipment3.HarvesttankType harvesttank; Equipment3.PumpType pump; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end DEMO_v20; And the corresponding application code d20_app7.mo encapsulated package d20_app7 // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium7 import M2 = DEMO_v20.Medium2; extends M2 (name = "Seven components" "Medium name", nc = 7 "Number of substances", mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight"); constant Integer C = 3 "Substance index"; constant Integer D = 4 "Substance index"; constant Integer E = 5 "Substance index"; constant Integer F = 6 "Substance index"; constant Integer G = 7 "Substance index"; end Medium7; // --------------------------------------------------------------------------------------------- // Adaptation of library DEMO_v20 to Medium7 and including a new model SensorX // --------------------------------------------------------------------------------------------- package Equipment7 extends DEMO_v20.Equipment(redeclare package Medium=Medium7); model SensorX LiquidCon probe; RealOutput out; constant Integer component "Component measured"; equation probe.F = 0; out = probe.c[component]; end SensorX; end Equipment7; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- import DEMO_v20.Control; model Test package medium = Medium7; // Not accessible in FMU though constant String name = medium.name; // But name here is accessible Equipment7.PumpType pump; Equipment7.FeedtankType feedtank; Equipment7.HarvesttankType harvesttank; Equipment7.SensorX sensor(component = medium.G); Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); connect(sensor.probe, harvesttank.port); end Test; end d20_app7;
Tested both DEMO_v20.mo and d20_app7.mo in Dymola Version 2018 (64-bit), 2017-04-10. Loading the file DEMO_v20.mo gives the error, <medium declaration> (line 137, column 27: C:/Users/adeas31/Desktop/DEMO_v20.mo) medium already declared on line 135. And running DEMO_v20.Test gives, Translation of DEMO_v20.Test: For variable feedtank.medium_nc declared in class DEMO_v20.Equipment.FeedtankType, C:/Users/adeas31/Desktop/DEMO_v20.mo at line 77, and used in component feedtank. The variability of the definition equation: feedtank.medium_nc = size(feedtank.outlet.c, 1); is higher than the declared variability of the variables. For variable harvesttank.medium_nc declared in class DEMO_v20.Equipment.HarvesttankType, C:/Users/adeas31/Desktop/DEMO_v20.mo at line 91, and used in component harvesttank. The variability of the definition equation: harvesttank.medium_nc = size(harvesttank.inlet.c, 1); is higher than the declared variability of the variables. Basic type inconsistencies detected. Translation aborted. ERRORS have been issued. Running d20_app7.Test gives, Translation of d20_app7.Test: Encapsulation of d20_app7 prevented us from finding DEMO_v20 in global scope. Missing base class DEMO_v20.Equipment the class DEMO_v20.Equipment exists, but Modelica is case-sensitive and uses scoping File: C:/Users/adeas31/Desktop/d20_app7.mo, line 46 Context: d20_app7.Equipment7 Component type specifier Equipment7.PumpType not found File: C:/Users/adeas31/Desktop/d20_app7.mo, line 67 Component context: pump Component declared as Equipment7.PumpType pump in d20_app7.Test Component type specifier Equipment7.FeedtankType not found File: C:/Users/adeas31/Desktop/d20_app7.mo, line 68 Component context: feedtank Component declared as Equipment7.FeedtankType feedtank in d20_app7.Test Component type specifier Equipment7.HarvesttankType not found File: C:/Users/adeas31/Desktop/d20_app7.mo, line 69 Component context: harvesttank Component declared as Equipment7.HarvesttankType harvesttank in d20_app7.Test Component type specifier LiquidCon not found File: C:/Users/adeas31/Desktop/d20_app7.mo, line 49 Component context: sensor.probe Component declared as LiquidCon probe in d20_app7.Equipment7.SensorX WARNINGS have been issued. ERRORS have been issued. Hope that helps.
Thank you Adeel! The Dymola error log made me do the following changes to the code: DEMO_v20 here I eliminated the instantiation of medium - forgot it see 3) above DEMO_v20 here I now get the size of the models from Medium.nc instead of through the connector and size of c. D20_app7 here I now in the procedure of adaptation of package Equipment, first import, and then extend and adapt to Medium7. The updated code DEMO_v22 and d22_app7 now works with both JModelica and OpenModelica. Would be good to have it tested in Dymola too 🙂 Updated code DEMO_v22.mo package DEMO_v22 // Here I have put together a small demo-library to illustrate questions // around structuring handling of medium. The key structures are taken // from MSL fluid, I think it is fair to say. // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; partial package MediumBase constant String name "Medium name"; constant Integer nc "Number of substances"; replaceable type Concentration = Real[nc] "Substance conc"; end MediumBase; package Medium2 extends MediumBase (name="Two components", nc=2); constant Real[nc] mw = {10, 20} "Substance weight"; constant Integer A = 1 "Substance index"; constant Integer B = 2 "Substance index"; end Medium2; package Medium3 import M2 = DEMO_v22.Medium2; extends M2 (name="Three components" "Medium name", nc=3 "Number of substances", mw = cat(1,M2.mw,{30}) "Substance weight"); constant Integer C = 3 "Substance index"; end Medium3; // --------------------------------------------------------------------------------------------- // Equipment dependent on the medium // --------------------------------------------------------------------------------------------- package Equipment replaceable package Medium = MediumBase constrainedby MediumBase; connector LiquidCon Medium.Concentration c "Substance conc"; flow Real F (unit="m3/s") "Flow rate"; end LiquidCon; model PumpType LiquidCon inlet, outlet; RealInput Fsp; equation inlet.F = Fsp; connect(outlet, inlet); end PumpType; model FeedtankType LiquidCon outlet; parameter Real[Medium.nc] c_in (each unit="kg/m3") = {1.0*k for k in 1:Medium.nc} "Feed inlet conc"; parameter Real V_0 (unit="m3") = 100 "Initial feed volume"; Real V(start=V_0, fixed=true, unit="m3") "Feed volume"; equation for i in 1:Medium.nc loop outlet.c[i] = c_in[i]; end for; der(V) = outlet.F; end FeedtankType; model HarvesttankType LiquidCon inlet, port; parameter Real V_0 (unit="m3") = 1.0 "Initial harvest liquid volume"; parameter Real[Medium.nc] m_0 (each unit="kg/m3") = zeros(Medium.nc) "Initial substance mass"; Real[Medium.nc] c "Substance conc"; Real[Medium.nc] m (start=m_0, each fixed=true) "Substance mass"; Real V(start=V_0, fixed=true, unit="m3") "Harvest liquid volume"; equation for i in 1:Medium.nc loop der(m[i]) = inlet.c[i]*inlet.F; c[i] = m[i]/V; port.c[i] = c[i]; end for; der(V) = inlet.F; end HarvesttankType; end Equipment; // --------------------------------------------------------------------------------------------- // Control // --------------------------------------------------------------------------------------------- package Control block FixValueType RealOutput out; parameter Real val=0; equation out = val; end FixValueType; end Control; // --------------------------------------------------------------------------------------------- // Adaptation of package Equipment to Medium3 // --------------------------------------------------------------------------------------------- package Equipment3 extends DEMO_v22.Equipment(redeclare package Medium=Medium3); end Equipment3; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- model Test package medium = DEMO_v22.Medium3; // Not accessible in FMU though constant String name = medium.name; // But name here is now accessible Equipment3.FeedtankType feedtank; Equipment3.HarvesttankType harvesttank; Equipment3.PumpType pump; Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); end Test; end DEMO_v22; and updated application code d22_app7.mo encapsulated package d22_app7 // Here I put together an application for 7 substances - print 8 pt // and import code from the library DEMO. // --------------------------------------------------------------------------------------------- // Interfaces // --------------------------------------------------------------------------------------------- import Modelica.Blocks.Interfaces.RealInput; import Modelica.Blocks.Interfaces.RealOutput; package Medium7 import M2 = DEMO_v22.Medium2; extends M2 (name = "Seven components" "Medium name", nc = 7 "Number of substances", mw = cat(1,M2.mw,{30,40,50,60,70}) "Substance weight"); constant Integer C = 3 "Substance index"; constant Integer D = 4 "Substance index"; constant Integer E = 5 "Substance index"; constant Integer F = 6 "Substance index"; constant Integer G = 7 "Substance index"; end Medium7; // --------------------------------------------------------------------------------------------- // Adaptation of library DEMO_v22 to Medium7 and including a new model SensorX // --------------------------------------------------------------------------------------------- package Equipment7 import DEMO_v22.Equipment; extends Equipment(redeclare package Medium=Medium7); model SensorX LiquidCon probe; RealOutput out; constant Integer component "Component measured"; equation probe.F = 0; out = probe.c[component]; end SensorX; end Equipment7; // --------------------------------------------------------------------------------------------- // Examples of systems // --------------------------------------------------------------------------------------------- import DEMO_v22.Control; model Test package medium = Medium7; // Not accessible in FMU though constant String name = medium.name; // But name here is accessible Equipment7.PumpType pump; Equipment7.FeedtankType feedtank; Equipment7.HarvesttankType harvesttank; Equipment7.SensorX sensor(component = medium.G); Control.FixValueType Fsp(val=0.2); equation connect(feedtank.outlet, pump.inlet); connect(pump.outlet, harvesttank.inlet); connect(Fsp.out, pump.Fsp); connect(sensor.probe, harvesttank.port); end Test; end d22_app7;
Parameter Estimation of Kinetic model
I have a chemical kinetic model (2-Tissue compartment Model) with Constrained K3(where K3 is rate constant) I have modelled plasma function along with Chemical kinetic model in order to plot the output characteristics I would like to estimate the Rate Constant k3 from the Code below function c_t = output_function_constrainedK3(t, a1, a2, a3,b1,b2,b3,td, tmax,k1,k2,k3) DV_free= k1/(k2+k3); K3 = k3*((k1/k2)/DV_free); K_1 = (k1*k2)/(k2+K3); K_2 = (k1*K3)/(k2+K3); c_t = zeros(size(t)); ind = (t > td) & (t < tmax); c_t(ind)= conv(((t(ind) - td) ./ (tmax - td) * (a1 + a2 + a3)),(K_1*exp(-(k2+K3)*t(ind)+K_2)),'same'); ind = (t >= tmax); c_t(ind)= conv((a1 * exp(-b1 * (t(ind) - tmax))+ a2 * exp(-b2 * (t(ind) - tmax))) + a3 * exp(-b3 * (t(ind) - tmax)),(K_1*exp(-(k2+K3)*t(ind)+K_2)),'same'); plot(t,c_t); figure %plot(t,c_tnp); axis([0 50 -2000 80000]); xlabel time ; ylabel concentration ; end The initial estimates for all the parameters is enlisted below t=0:0.1:60; td =0.3; tmax=0.8; a1=2501; a2=18500; a3=65000; b1=0.5; b2=0.7; b3=0.3; k1=0.014; k2=0.051; k3=0.07; Kindly suggest me a method to estimate K3 parameter from nonlinear kinetic model code described above In the above function the parameters values for a1, a2, a3,b1, b2 ,b3, td, tmax, k1, k2 will remain constant. I would like to know how K3 value changes with change in time t value, for this i would like to initially estimate K3 at t interval t=0:0.1:60.. Any help greatly appreciated