Julie Dutoit
Julie Dutoit

Reputation: 11

In Modelica, how to call a variable in a different block without wiring the 2 blocks?

We are modeling various industrial component blocks, with each having CAPEX, labour cost, maintenance cost, total OPEX, etc. We would like to have 1 block, in the best case not wired to the other blocks, to account for the total OPEX, total CAPEX, total labour costs, etc. induced by the blocks present in a model : the number of blocks is not fixed. Is there a way of not connecting the blocks with a wire ?

In case there is no way, we found the solution of using the RealOutput y vector, as defined in Modelica.Blocks.Interfaces.MO : nout is defined as the number of actual variables we would like to add up (e.g. if CAPEX, OPEX and maintenance are of interest, then nout = n = 3). However, we struggle for 2 points :

  1. How can we pass a matrix through this RealOutput ? This would be useful for instance when the CAPEX has 3 values : estimated, optimistic and pessimistic.
  2. How can we take up this y in only 1 block ? For now we managed to use n Modelica.Blocks.Math.MultiSum blocks to take up each variable separately, but is there a way of adding them up respectively, but in the same block ?

Thank you already for your much appreciated help and answers !

Upvotes: 1

Views: 323

Answers (1)

Christoph
Christoph

Reputation: 5612

I think you should be able to do this with the inner/outer construct and a custom connector with a flow variable for, e.g., your capex, as demonstrated in section 5.8 of Fritzson's book "Principles of Object-Oriented Modeling and Simulation with Modelica 3.3".

I could have sworn there is already an example around that sums masses of components to a total, but I could not find it anywhere...

package SO_69945088

model System
  FinancialAggregator fin_totals() "Collects financial info";
  inner CapexConn common_connection "autoshared connection";
  Component comp1(capex_info.amount={0, 3, 5});
  Component comp2(capex_info.amount={1, 10, 12});
  Component comp3(capex_info.amount={5, 6, 7});
equation
  //Conveniently collect financial info in fin_totals
  connect(common_connection, fin_totals.agg_conn);
end System;
connector CapexConn
  // the amount being a "flow" variables means all contributions
  // sum at a connection point.
  flow Real[3] amount;    
  // every "flow" variable should have a non-flow variable,
  // at least for "physical" connections. Let's add a dummy:
  Real [3] period;

end CapexConn;

  model CapexEmitter
    CapexConn conn;
    Real[3] amount = fill(0, 3);
    Real[3] period;
  equation
// Here you could also have more logic, like computing emitted capex
// depending on the period
    conn.amount = -amount; //negative because of sign of flow direction in connectors
    conn.period = period;
  end CapexEmitter;

model Component "Industrial component block with capex tracking"
  // (you would extend your other components from this to use it)
  outer CapexConn common_connection;  // make outside connection visible
  CapexEmitter capex_info;
equation
  // all Component instances automatically connect, without manual wiring
  connect(capex_info.conn, common_connection);
end Component;

  model FinancialAggregator
    CapexConn agg_conn;
    Real[3] capexsum; 
    Real period[3] = {1,1,1};
  equation
   capexsum = agg_conn.amount;
   period = agg_conn.period;

  end FinancialAggregator;
end SO_69945088;

Simulating System gives a fin_totals.capexsum of {6, 19, 24} (optimistic, estimated, pessimistic).

This should give you a starting point showing the principles.

Upvotes: 1

Related Questions