Search code examples
modelicaopenmodelica

Derivative of a flow variable [Openmodelica fluid library]


I am trying to make some openmodelica models which have similar workings as the modelica fluid library, as in it uses ports with a flow variable and several components working further on a TwoPort component. To simplify my question, I'll try using the modelica fluid library as an example.

In one of my components which builds upon the PartialTwoPort, I need the derivative of the flow variable m_flow, but when I try implementing this, the systems doesn't seem to be able to handle it. (I tried looking for an answer online but couldn't find anything that could help me)

I made a simple testing model which could (hopefully) be used to test possible solutions. The TestValue is thus what I would like to get as a resulting parameter which I could use in further code. The model works when the TestValue is commented out but returns an error when it is not.

model Fluid_test
  //extends Modelica.Icons.Example;

  replaceable package Medium = Modelica.Media.Water.StandardWaterOnePhase
    constrainedby Modelica.Media.Interfaces.PartialMedium;
    
Modelica.Fluid.Sources.FixedBoundary boundary(
    nPorts = 1,
    use_T=true,
    T=Modelica.Units.Conversions.from_degC(20),
    p=600000,
    redeclare package Medium = Medium) annotation(
    Placement(transformation(origin = {-56, -18}, extent = {{-10, -10}, {10, 10}})));
    
Modelica.Fluid.Sources.FixedBoundary boundary1(
    p=600000,
    T=400,
    nPorts=2,
    redeclare package Medium = Medium)
    annotation (Placement(transformation(origin = {-18, 44}, extent = {{100, -40}, {80, -20}})));

Modelica.Fluid.Machines.PrescribedPump pump(
    checkValve=true,
    checkValveHomotopy = Modelica.Fluid.Types.CheckValveHomotopyType.Closed,
    N_nominal=1200,
    redeclare function flowCharacteristic =
        Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.quadraticFlow (
          V_flow_nominal={0,0.25,0.5}, head_nominal={100,60,0}),
    use_N_in=true,
    nParallel=1,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    V(displayUnit="l") = 0.05,
    massDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    redeclare package Medium = Medium,
    p_b_start=600000,
    T_start=400) annotation(
    Placement(transformation(origin = {-10, 14}, extent = {{-10, -10}, {10, 10}})));
  Modelica.Blocks.Sources.Constant const annotation(
    Placement(transformation(origin = {-8, 58}, extent = {{-10, -10}, {10, 10}})));

Real TestValue;

equation
TestValue = der(pump.port_a.m_flow);
  connect(boundary.ports[1], pump.port_a) annotation(
    Line(points = {{-46, -18}, {-20, -18}, {-20, 14}}, color = {0, 127, 255}));
  connect(pump.port_b, boundary1.ports[1]) annotation(
    Line(points = {{0, 14}, {62, 14}}, color = {0, 127, 255}));
  connect(const.y, pump.N_in) annotation(
    Line(points = {{4, 58}, {-10, 58}, {-10, 24}}, color = {0, 0, 127}));
  annotation(
    Diagram);
end Fluid_test;

The error that returns is the following: enter image description here


Solution

  • Unfortunately, the mass flowrate is not a state, and using the der() this way is not the proper way to evaluate the derivative in my opinion. I would use the Derivative block with a small enough time constant as described in the modified example below:

    model Fluid_test
      //extends Modelica.Icons.Example;
    
      replaceable package Medium = Modelica.Media.Water.StandardWaterOnePhase constrainedby Modelica.Media.Interfaces.PartialMedium;
    
      Modelica.Fluid.Sources.FixedBoundary boundary(
        nPorts=1,
        use_T=true,
        T=Modelica.Units.Conversions.from_degC(20),
        p=600000,
        redeclare package Medium = Medium) annotation (Placement(transformation(origin={-50,0}, extent={{-10,-10},{10,10}})));
    
      Modelica.Fluid.Sources.FixedBoundary boundary1(
        p=600000,
        T=400,
        redeclare package Medium = Medium,
        nPorts=1) annotation (Placement(transformation(origin={-40,30}, extent={{100,-40},{80,-20}})));
    
      Modelica.Fluid.Machines.PrescribedPump pump(
        checkValve=true,
        checkValveHomotopy=Modelica.Fluid.Types.CheckValveHomotopyType.Closed,
        N_nominal=1200,
        redeclare function flowCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.quadraticFlow (V_flow_nominal={0,0.25,0.5}, head_nominal={100,60,0}),
        use_N_in=true,
        nParallel=1,
        energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
        V(displayUnit="l") = 0.05,
        massDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
        redeclare package Medium = Medium,
        p_b_start=600000,
        T_start=400) annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
      Modelica.Blocks.Sources.Constant const(k=1) annotation (Placement(transformation(origin={-20,30}, extent={{-10,-10},{10,10}})));
    
      Real TestValue;
      Modelica.Blocks.Continuous.Derivative derBlock(
        k=1,
        T=1e-2,
        initType=Modelica.Blocks.Types.Init.SteadyState);
    
      inner Modelica.Fluid.System system annotation (Placement(transformation(extent={{40,-80},{60,-60}})));
    equation 
      derBlock.u = pump.port_a.m_flow;
      TestValue = derBlock.y;
    
      connect(boundary.ports[1], pump.port_a) annotation (Line(points={{-40,0},{-10,0}}, color={0,127,255}));
      connect(const.y, pump.N_in) annotation (Line(points={{-9,30},{0,30},{0,10}}, color={0,0,127}));
      connect(pump.port_b, boundary1.ports[1]) annotation (Line(points={{10,0},{40,0}}, color={0,127,255}));
      annotation (uses(Modelica(version="4.0.0")));
    end Fluid_test;
    

    I have also corrected the number of ports on boundary1 (from 2 to 1), set the constant value of the Constant block to 1 (instead of nothing) and added a System block. They lead to warnings in Dymola.