Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

New Medium

New Medium

Hi!
As said, I am a newbie to Modelica and having a hard time to create a new medium. My final goal is to create a new mixture medium but as I did not succeed I stepped back and tried to create a new single phase, single component medium but also this does not work out.
Actually creating the medium in terms of syntax seems ok and the model check does not report any errors, but testing the medium with the Modelica.Media.Utilities.PartialTestModel fails. The problem appears, when using a non-constant density. In the code of the model below I tried different things. Once with a constant density declared in the baseProperties which seems to work, once with the density calculated within the baseProperties causing problems and once calling the density function, not working either, though the latter two options give different error.
The medium implemented in the code here is simple water, using not very sophisticated approximations, but the values calculated should be meaningful, though.
Can anyone help me getting this fixed? What am I missing?
Big thanks in advance
Chris

Here is the code of my created medium

Code:


package LiBrH2O_3
  extends Modelica.Media.Interfaces.PartialMixtureMedium(
  final mediumName = "LiBrH2O_3",
//  final substanceNames = {"LiBr", "H2O"},
  final substanceNames = { mediumName },
  final singleState = true,
  final reducedX = true,
  final fixedX = false,
  ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.pTX);
  //    Temperature(
  //      min=273,
  //      max=450,
  //      start=293.15),
  //    T_default = 293.15,
  //    pressure(
  //      min = 0,
  //      max = 1.0e6,
  //      start = 1.5e5),
  //    density(
  //      start = 994),
  //    SpecificEnthalpy(
  //      start = 53000
  //    ),
  //    SpecificHeatCapacity(
  //      start = 2300
  //    ),

  redeclare model extends BaseProperties(
    final standardOrderComponents = true "Base properties of medium",
      h(stateSelect=StateSelect.default),
      d(stateSelect=StateSelect.default),
      T(stateSelect=StateSelect.prefer),
      p(stateSelect=StateSelect.prefer)
    )
   
    protected
      constant Real ca = 999.79684;
      constant Real cb = 0.068317355;
      constant Real cc = -0.010740248;
      constant Real cd = 0.00082140905;
      constant Real ce = -2.3030988e-5;
      Real Td = state.T - 273.15;

    equation
      state = ThermodynamicState(p = p, T = T, X = X);     
      d = ca + cb * Td + cc * Td^2 + cd * Td^2.5 + ce * Td^3; // fails with some error, running the model test
//      d = density(state); // fails with some error when running the medium test
//      d = 998; // using constant density here the medium seems to work as epected
      h = specificEnthalpy(state);
      u = h - p / d;
      MM = 0.01801528;
      R = 8.3144 / MM;
  end BaseProperties;

  redeclare replaceable record ThermodynamicState "A selection of variables that uniquely defines the thermodynamic state"
    extends Modelica.Icons.Record;
    AbsolutePressure p "Absolute pressure of medium";
    Temperature T "Temperature of medium";
    MassFraction[nX] X(start = reference_X) "Mass fractions (= (component mass)/total mass  m_i/m)";
    annotation(
      Documentation(info = "<html></html>"));
  end ThermodynamicState;

  redeclare function extends specificEnthalpy "Return specific enthalpy" extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificEnthalpy h "Specific enthalpy";
    protected
      constant Real d1 = 2.844699e-2;
      constant Real d2 = 4.211925;
      constant Real d3 = -1.017034e-3;
      constant Real d4 = 1.311054e-5;
      constant Real d5 = 6.756469e-8;
      constant Real d6 = 1.724481e-10;
      Real T = state.T - 273.15;
    algorithm
      h := (d1 + d2 * T + d3 * T^2 + d4 * T^3 + d5 * T^4 + d6 * T^5) * 1000;

    annotation(Documentation(info = "<html></html>"));
  end specificEnthalpy;

  redeclare function extends specificHeatCapacityCp "Return specific heat capacity at constant pressure" extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificHeatCapacity cp
      "Specific heat capacity at constant pressure"; 
    protected
      constant Real a = 4.2174356;
      constant Real b = -0.0056181625;
      constant Real c = 0.0012992528;
      constant Real d = -0.00011535353;
      constant Real e = 4.14964e-6;
      Real T = state.T - 273.15;     
    algorithm
      cp := (a + b * T + c * T^1.5 + d * T^2 + e * T^2.5) * 1000;
    annotation(Documentation(info = "<html></html>"));
  end specificHeatCapacityCp;

  redeclare partial function density "Return density"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output Density d "Density";
    protected
      constant Real ca = 999.79684;
      constant Real cb = 0.068317355;
      constant Real cc = -0.010740248;
      constant Real cd = 0.00082140905;
      constant Real ce = -2.3030988e-5;
      Real T = state.T - 273.15;
    algorithm
      d := ca + cb * T + cc * T^2 + cd * T^2.5 + ce * T^3;
//      d := 998;
  end density;
 

  redeclare function extends setState_pTX "Return thermodynamic state as function of p, T and composition 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, X = X);
    annotation(
      Inline = true);
  end setState_pTX;
 
  annotation(
    Documentation(info = "<html></html>"));
end LiBrH2O_3;

Code used to test the medium:

Code:


model Test_LiBrH2O
  extends Modelica.Media.Examples.Utilities.PartialTestModel(
    redeclare package Medium = LiBrH2O_3);
   
end Test_LiBrH2O;

Edited by: ChrisK - Feb-23-20 03:28:01

Re: New Medium

Hi Chris,

The origin of the problem is in the setState_pTX function. In OpenModelica the information message is telling that there are duplicate elements not identical. You are extending the original function and you are redeclaring the input and output variables. If you redeclare the function without extension, or you take out the redeclaration of variables, the problem is solved. For example:
  redeclare function extends setState_pTX "Return thermodynamic state as function of p, T and composition X or Xi" extends Modelica.Icons.Function;
    algorithm
      state := ThermodynamicState(p = p, T = T, X = X);
    annotation(
      Inline = true);
  end setState_pTX;

It is strange that if you change the test to PartialTestModel2, that is an extension of the one you are using, there is no problem with your original code. I would think that there is no problem with your code, but with the tool.

Carlos

Re: New Medium

Hi Carlos!
Thanks a lot for your reply. I revised the use of extend but unfortunately this didn't resolve the problem.
But in another forum Stack overflow - Two-phase Modelica example I found an interesting example of how to set up a new medium Water - temperature dependent density. Looking at the example I noticed that I was missing at least some XXX_reference and default_XXX values and probably even more important in the different functions it should be indicated how often they may be differentiated, using something like annotation(..., smoothOrder=N, ...). Not doing so results in an error stating I have a singular matrix.
In summary using the stated example I was able to set up a medium that passes the tests. I am leaving this reply here in case someone else faces the same problem.
Cheers
Christian

Re: New Medium

Hi Christian,

Thank you very much for the information. In fact I didn't take enough care. With the solution I proposed the model compiles and runs on OpenModelica 1.14.1 on Windows, but I didn't look at the Simulation Output window, it is telling that after a successful initialization the simulation terminated by an assert at time 0.00038.
This is different from what you are experiencing. Normally after initial convergence you have no problems. I have written several media packages, and what you tell is completely right: having good reference and default values for pressure, temperature and enthalpy is of great importance for convergence. I normally do not specify smoothOrder, but I know it is a help for the solver.

Regards

Carlos

Re: New Medium

Hi Carlos!
In some configuration I had seen this error as well. This is a little bit off topic, but is there a tutorial / book or any other source giving more insight in these details of modeling fluid systems with OM? Actually I want to do simulations with an absorption chiller but I am struggling quite a lot.
Cheers
Christian

Re: New Medium

Hi Christian,
As far as I know there is no book that could be a reference for the modeling of media, or mass transfer with Modelica. I found interesting, although now it is quite old, this dissertation from C.C.Richter link.
For me there are three main fields: fluid properties calculation, fluid flow and heat transfer, and mass transfer.
Regarding properties calculation, the Media library from the Modelica standard library is quite adequate, although there are not models for multicomponent, multiphase, mediums. The examples that come with the library, mainly for water and air are good, but quite complex. When you want to work with other fluids you do not find too much to choose, at least open source. There is the External Media library, that allows to link with CoolProp or ReefProp, but as far as I know it is almost impossible to make it work with Open Modelica. There is also the system library HelmholtzMedia, but it is not easy to extend an it is also not working. So I decided to make my own libraries, that you can find here. The more flexible one is using external functions and objects and therefore is not supported by the new frontend of Open Modelica (necessary to wait for its implementation in version 2.0), but yes by the old frontend.
Regarding fluid flow and heat transfer, I think that the Fluid library implemented in Modelica is too complex to be useful, and I see that there is much more people sharing this oppinion. I come from the engineering field where "keep it simple" is a must. I am polishing the library that I have used along some years in order to publish it as open source.
Regarding mass transfer, I understand that the first necessary step is to have a multicomponent, multiphase media definition, but there is nothing here for now. Work for the future.

Cheers

Carlos

Re: New Medium

Hi Carlos!
Thanks for the advice I could take a look at the thesis. As I am engineer as well, in my opinion KISS is always a good strategy. Actually I could set up my medium to run with the tests provided and took some steps further to build an absorption cooling system. But I ran into more difficulties. At first I built two separate modules one for the Absorber / Evaporator and one for the Generator / Condenser. The modules compiled fine but joining them with some expansion valve and pump resulted in an error I could not solve yet. Therefore I put some of the parts together into a small test module and I the following problem:
The code posted here runs fine unless uncomment the two commented blocks including the lines starting with Abs_.... . Doing so results in this error: "Error in region computation of IF97 steam tables(p = 5582.09, T = 308)". Do you have any suggestions?
I attached the file as well and the file including the medium definition I use (LiBrH2O_5). Both are undocumented but I hope easy to understand
Cheers Christian

Code:


model H2OTest
  replaceable package Refrigerant = Modelica.Media.Water.WaterIF97_pT;
  replaceable package Solution = LiBrH2O_5;
 
  // Generator parameters
  Refrigerant Gen_H2O;
  Modelica.Media.Interfaces.Types.SaturationProperties Gen_H2OSat;
  Refrigerant.ThermodynamicState Gen_H2O_liq;
  // dew point, one-phase side
  Refrigerant.ThermodynamicState Gen_H2O_vap;
 
  Solution.ThermodynamicState Gen_state;
  Modelica.SIunits.SpecificEnthalpy Gen_h_sol(start=1.0e5);
  Modelica.SIunits.SpecificEnthalpy Gen_h_dot_eva(start=1.0e5);
  Modelica.SIunits.SpecificHeatCapacity Gen_cp_sol(start = 4.2e3);   
 
  Modelica.SIunits.Mass Gen_M_g(start = 20, min = 0);
  Modelica.SIunits.Mass Gen_M_c(start = 20, min = 0);
  Modelica.SIunits.Mass Gen_M_v(min = 0);

  Modelica.SIunits.MassFlowRate Gen_m_dot_con(start = 0, min = 0);
  Modelica.SIunits.MassFlowRate Gen_m_dot_eva(start = 0, min = 0);
 
  Modelica.SIunits.Temp_K Gen_T_g(min = 273.15, max = 373.15, start = 298);
  Modelica.SIunits.Temp_K Gen_T_c(min = 273.15, max = 373.15, start = 308);   
 
//  Refrigerant Abs_H2O;
//  Modelica.Media.Interfaces.Types.SaturationProperties Abs_H2OSat;
//  Refrigerant.ThermodynamicState Abs_H2O_liq;
//  Refrigerant.ThermodynamicState Abs_H2O_vap; 

equation
  Gen_H2OSat = Gen_H2O.setSat_T(Gen_T_c);
  Gen_H2O_liq = Gen_H2O.setBubbleState(Gen_H2OSat);
  Gen_H2O_vap = Gen_H2O.setDewState(Gen_H2OSat);
 
  Gen_state = Solution.setState_pTX(Gen_H2OSat.psat, Gen_T_g, {0.5, 0.5});
  Gen_cp_sol = Solution.specificHeatCapacityCp(Gen_state);
  Gen_h_sol = Solution.specificEnthalpy(Gen_state);
  Gen_h_dot_eva = Gen_H2O_vap.h - Gen_h_sol;

  der(Gen_M_c) = Gen_m_dot_con;
  Gen_M_c * Gen_H2O.specificHeatCapacityCp(Gen_H2O_liq) * der(Gen_T_c) = Gen_m_dot_con * Gen_H2O_liq.h; 
  der(Gen_M_g) = Gen_m_dot_eva;
  0 = Gen_m_dot_eva * Gen_h_dot_eva + Gen_M_g * Gen_cp_sol * der(Gen_T_g); 
  der(Gen_M_v) = (-Gen_m_dot_con) + Gen_m_dot_eva;
  0 = Gen_m_dot_con * abs(Gen_H2O_vap.h - Gen_H2O_liq.h) + Gen_m_dot_eva * Gen_H2O_vap.h + Gen_H2O.specificHeatCapacityCp(Gen_H2O_vap) * der(Gen_T_c) * Gen_M_v;   
  Gen_T_g = Solution.saturationTemperature(Gen_state);
 
//  Abs_H2OSat = Abs_H2O.setSat_T(283);
//  Abs_H2O_liq = Abs_H2O.setBubbleState(Abs_H2OSat);
//  Abs_H2O_vap = Abs_H2O.setDewState(Abs_H2OSat);

end H2OTest;

LiBrH2O-5.mo

H2OTest.mo

Edited by: ChrisK - Mar-18-20 15:46:13

Re: New Medium

Hi Chris,

It seems an OpenModelica fault. I received no error message, but I am using the old frontend by default. When I switched to the new frontend the message appeared. The selected medium should be able to calculate the saturation states at 283 K,  nevertheless I changed the medium to StandardWater, that in fact is WaterIF97_ph, and the problem disappeared also with the new frontend.
Just one question, Why do you make two copies of the Refrigerant package (Gen_H2O and Abs_H2O) instead of using it directly. It seems also better to use Refrigerant.SaturationProperties instead of Modelica.Media.Interfaces.Types.SaturationProperties.
Regarding your media definition, I have not had enough time to review it, but I will try to do it in the next days.

Regards

Carlos

Re: New Medium

Hi Carlos!
Thanks a lot for your reply, you are the light in the tunnel!

> Why do you make two copies of the Refrigerant package (Gen_H2O and Abs_H2O) instead of using it directly.

Actually I want to have these in separate modules but as I was not able to get them running I decided to join the stuff in one module first, get it running and separate again later on. Therefore I maintained the final variable structure

> It seems also better to use Refrigerant.SaturationProperties instead of Modelica.Media.Interfaces.Types.SaturationProperties.

I simply was not aware of this member, thanks for the advice, already changed it!

Cheers Christian

There are 0 guests and 0 other users also viewing this topic