Search code examples
oopmodelica

How to model simple mass fraction calculation in Modelica using OOP approach?


I am wanting to program a simple calculation in OMEdit to better understand how write more Object-Oriented code to find the answer (as opposed to using a single Model). The problem I am trying to solve is given the mole fractions yi and the molar mass Mi of the simplified constituents of air, determine the mass fraction wi for each constituent.

Given: Mole Fractions (yi) and Molar Masses (Mi) of Air:

Constituent yi Mi
N2 0.781 28
O2 0.209 32
Ar 0.01 39.9

Mair = Σ(yi*Mi)

wi =yi*Mi/Mair

The answers I am expecting are

Constituent wi
N2 0.754
O2 0.231
Ar 0.014

To model each constituent of the composition, I have

model Constituent
  parameter Real y "molar fraction";
  parameter Real M "molar mass";
  Real M_total;
  Real w "mass fraction";
equation
w = y * M/M_total;
end Constituent;

To model the collection of constituents and calculate, I have

model Composition

  parameter Integer nc =1;
  Constituent[nc] constituents;
  Real M_total;
equation
  M_total = sum(constituents[i].M*constituents[i].y for i in size(constituents));
end Composition;

and then to execute the program I have

model Example_1_1

  Constituent[3] constituents(
  M = {28,32,39.9},
  y = {0.781,0.209,0.01}
  
  );
  
  
  Composition composition(
  nc = 3,
  constituents =constituents);

equation

end Example_1_1;

but it doesn't work


Solution

  • There are some fundamental issues with your approach:

    1. In Constituent you are missing an equation for M_total.
    2. In Composition the constituents should have parameters set
    3. The example is singular due to multiple reasons.

    Also I'm not sure if having models for both, Constituent and Composition is the best approach. I would make the Composition a single record as shown below:

    record Composition
      parameter Integer n(min=1) "Number of constituents";
      parameter Modelica.Units.SI.DimensionlessRatio y[n] "molar fraction";
      parameter Modelica.Units.SI.Mass M[n] "molar mass";
      final parameter Modelica.Units.SI.Mass M_total=sum(y.*M);
      final parameter Modelica.Units.SI.DimensionlessRatio w[n]=y.*M/M_total "mass fraction";
      annotation (uses(Modelica(version="4.0.0")));
    end Composition;
    

    Records come with the limitation, that they cannot have a equation section, but computing final parameters is good enough in this case.

    Then the example would be

    model Example_1_1
    
      Composition comp(
        n = 3,
        M = {28,32,39.9},
        y = {0.781,0.209,0.01});
    
    end Example_1_1;
    

    giving your expected result for comp.w (using the correct equation from the code, not the description).