Buildings.Fluid.Examples.Performance

Package of examples that demonstrate computation speed performance

Information

This package contains examples that illustrate the Modelica conference paper by Jorissen et al. (2015) about speed optimization.

References

Extends from Modelica.Icons.ExamplesPackage (Icon for packages containing runnable examples).

Package Content

Name Description
Buildings.Fluid.Examples.Performance.Example1v1 Example1v1 Example 1 model without mixing volume
Buildings.Fluid.Examples.Performance.Example1v2 Example1v2 Example 1 model with mixing volume
Buildings.Fluid.Examples.Performance.Example2 Example2 Example 2 model with series pressure components
Buildings.Fluid.Examples.Performance.Example3 Example3 Example 3 model with mixed series/parallel pressure drop components
Buildings.Fluid.Examples.Performance.Example4 Example4 Example 4 model of simple condensing heat exchanger
Buildings.Fluid.Examples.Performance.Example5 Example5 Example 5 model of Modelica code that is inefficiently compiled into C-code
Buildings.Fluid.Examples.Performance.Example6 Example6 Example 6 model of Modelica code that is inefficiently compiled into C-code
Buildings.Fluid.Examples.Performance.Example7 Example7 Example 7 model of Modelica code that is more efficiently compiled into C-code
Buildings.Fluid.Examples.Performance.Example8 Example8 Common subexpression elimination example
Buildings.Fluid.Examples.Performance.PressureDrop PressureDrop Package with various configurations of pressure drop models to analyze symbolic processing
Buildings.Fluid.Examples.Performance.BaseClasses BaseClasses  

Buildings.Fluid.Examples.Performance.Example1v1 Buildings.Fluid.Examples.Performance.Example1v1

Example 1 model without mixing volume

Buildings.Fluid.Examples.Performance.Example1v1

Information

This model demonstrates the impact of the allowFlowReversal and from_dp parameters on the sizes of nonlinear algebraic loops. The user can change the parameter value in the respective BooleanConstant blocks and rerun the simulation to compare the performance. The results are also demonstrated below for nRes.k = 20, the number of parallel branches, which contain one pressure drop element each.

These results were generated using Dymola 2015FD01 64 bit on Ubuntu 14.04.

Default case:

AllowFlowReversal = true and from_dp = false

Sizes of nonlinear systems of equations: {6, 21, 46}

Sizes after manipulation of the nonlinear systems: {1, 19, 22}

Change 1:

AllowFlowReversal = false and from_dp = false

Sizes of nonlinear systems of equations: {6, 21}

Sizes after manipulation of the nonlinear systems: {1, 19}

Change 2:

AllowFlowReversal = false and from_dp = true

Sizes of nonlinear systems of equations: {6, 21}

Sizes after manipulation of the nonlinear systems: {1, 1}

These changes also have a significant impact on the computational speed.

Following script can be used in Dymola to compare the CPU times. For this script to work, make sure that Dymola stores at least 4 results.

cpuOld=OutputCPUtime;
evaluateOld=Evaluate;
OutputCPUtime:=true;
simulateModel("Buildings.Fluid.Examples.Performance.Example1v1(allowFlowReversal.k=true, from_dp.k=false)", stopTime=10000, numberOfIntervals=10, method="dassl", resultFile="Example1v1");
simulateModel("Buildings.Fluid.Examples.Performance.Example1v2(from_dp.k=true, allowFlowReversal.k=true)", stopTime=10000, numberOfIntervals=10, method="dassl", resultFile="Example1v2");
simulateModel("Buildings.Fluid.Examples.Performance.Example1v1(allowFlowReversal.k=false, from_dp.k=false)", stopTime=10000, numberOfIntervals=10, method="dassl", resultFile="Example1v1");
simulateModel("Buildings.Fluid.Examples.Performance.Example1v1(allowFlowReversal.k=false, from_dp.k=true)", stopTime=10000, numberOfIntervals=10, method="dassl", resultFile="Example1v1");
createPlot(id=1, position={15, 10, 592, 421}, range={0.0, 10000.0, -0.01, 0.35}, autoscale=false, grid=true);
plotExpression(apply(Example1v1[end-2].CPUtime), false, "Default case", 1);
plotExpression(apply(Example1v2[end].CPUtime), false, "Adding dummy states", 1);
plotExpression(apply(Example1v1[end-1].CPUtime), false, "allowFlowReversal=false", 1);
plotExpression(apply(Example1v1[end].CPUtime), false, "allowFlowReversal=false, from_dp=true", 1);
OutputCPUtime=cpuOld;
Evaluate=evaluateOld;

See Jorissen et al. (2015) for a discussion.

References

Extends from Buildings.Fluid.Examples.Performance.BaseClasses.Example1 (Example 1 partial model).

Parameters

TypeNameDefaultDescription
Realm_flow_nominal0.1Gain value multiplied with input signal

Modelica definition

model Example1v1 "Example 1 model without mixing volume" extends Buildings.Fluid.Examples.Performance.BaseClasses.Example1( allowFlowReversal(k=false), from_dp(k=true)); equation for i in 1:nRes.k loop connect(res[i].port_b, val.port_3); end for; end Example1v1;

Buildings.Fluid.Examples.Performance.Example1v2 Buildings.Fluid.Examples.Performance.Example1v2

Example 1 model with mixing volume

Buildings.Fluid.Examples.Performance.Example1v2

Information

This example is an extension of Buildings.Fluid.Examples.Performance.Example1v1 and demonstrates the use of mixing volumes for decoupling the algebraic loop that solves for the enthalpy of the system.

Example1v1:

Sizes of nonlinear systems of equations: {6, 21, 46}

Sizes after manipulation of the nonlinear systems: {1, 19, 22}

Example1v2 using mixing volumes:

Sizes of nonlinear systems of equations: {6, 21, 4}

Sizes after manipulation of the nonlinear systems: {1, 19, 1}

See Jorissen et al. (2015) for a discussion.

References

Extends from Buildings.Fluid.Examples.Performance.BaseClasses.Example1 (Example 1 partial model).

Parameters

TypeNameDefaultDescription
Realm_flow_nominal0.1Gain value multiplied with input signal
Timetau10Time constant at nominal flow [s]

Modelica definition

model Example1v2 "Example 1 model with mixing volume" extends Buildings.Fluid.Examples.Performance.BaseClasses.Example1; parameter Modelica.SIunits.Time tau=10 "Time constant at nominal flow"; Fluid.Delays.DelayFirstOrder[nRes.k] vol( redeclare each package Medium = Medium, each m_flow_nominal=m_flow_nominal, each allowFlowReversal=allowFlowReversal.k, each nPorts=2, each tau=tau, each energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial) "Mixing volumes for adding states in enthalpy circuit"; equation for i in 1:nRes.k loop connect(vol[i].ports[1], res[i].port_b); connect(vol[i].ports[2], val.port_3); end for; end Example1v2;

Buildings.Fluid.Examples.Performance.Example2 Buildings.Fluid.Examples.Performance.Example2

Example 2 model with series pressure components

Buildings.Fluid.Examples.Performance.Example2

Information

This example demonstrates that the use of the parameter from_dp can be important for reducing the size of algebraic loops in hydraulic circuits with many pressure drop components connected in series and a pump setting the pressure head.

If from_dp=true, we obtain:
Sizes of nonlinear systems of equations: {7}
Sizes after manipulation of the nonlinear systems: {5}
If from_dp=false, we obtain:
Sizes of nonlinear systems of equations: {7}
Sizes after manipulation of the nonlinear systems: {1}

This can have a large impact on computational speed.

Following script can be used in Dymola to compare the CPU times.

cpuOld=OutputCPUtime;
evaluateOld=Evaluate;
OutputCPUtime:=true;
simulateModel("Buildings.Fluid.Examples.Performance.Example2(from_dp.k=false)", stopTime=10000, numberOfIntervals=10, method="dassl", resultFile="Example2");
simulateModel("Buildings.Fluid.Examples.Performance.Example2(from_dp.k=true)", stopTime=10000, numberOfIntervals=10, method="dassl", resultFile="Example2");
createPlot(id=1, position={15, 10, 592, 421}, range={0.0, 10000.0, -0.01, 25}, autoscale=false, grid=true);
plotExpression(apply(Example2[end-1].CPUtime), false, "from_dp=false", 1);
plotExpression(apply(Example2[end].CPUtime), false, "from_dp=true", 1);
OutputCPUtime=cpuOld;
Evaluate=evaluateOld;

See Jorissen et al. (2015) for a discussion.

References

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
MassFlowRatem_flow_nominal1Nominal mass flow rate [kg/s]
PressureDifferencedp_nominal1Pressure drop at nominal mass flow rate [Pa]

Modelica definition

model Example2 "Example 2 model with series pressure components" extends Modelica.Icons.Example; package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater; parameter Modelica.SIunits.MassFlowRate m_flow_nominal=1 "Nominal mass flow rate"; parameter Modelica.SIunits.PressureDifference dp_nominal=1 "Pressure drop at nominal mass flow rate"; Fluid.Movers.FlowControlled_dp pump_dp( redeclare package Medium = Medium, m_flow_nominal=m_flow_nominal, use_inputFilter=false, allowFlowReversal=false, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, nominalValuesDefineDefaultPressureCurve=true) "Pump model with unidirectional flow"; Fluid.Sources.Boundary_pT bou(redeclare package Medium = Medium, nPorts=1) "Boundary for absolute pressure boundary condition"; Modelica.Blocks.Sources.Pulse pulse(period=1) "Pulse input"; FixedResistances.PressureDrop[nRes.k] res( redeclare each package Medium = Medium, each m_flow_nominal=m_flow_nominal, each from_dp=from_dp.k, each allowFlowReversal=false, dp_nominal={dp_nominal*(1 + mod(i, 3)) for i in 1:nRes.k}); Modelica.Blocks.Sources.BooleanConstant from_dp(k=true) "Block for easily changing parameter from_dp.k"; Modelica.Blocks.Sources.IntegerConstant nRes(k=6) "Number of parallel branches"; equation connect(pump_dp.port_a, bou.ports[1]); connect(pump_dp.dp_in, pulse.y); connect(res[1].port_a, pump_dp.port_b); for i in 1:nRes.k-1 loop connect(res[i].port_b, res[i+1].port_a); end for; connect(res[nRes.k].port_b, pump_dp.port_a); end Example2;

Buildings.Fluid.Examples.Performance.Example3 Buildings.Fluid.Examples.Performance.Example3

Example 3 model with mixed series/parallel pressure drop components

Buildings.Fluid.Examples.Performance.Example3

Information

This example demonstrates the importance of merging pressure drop components that are connected in series, into one pressure drop component. Parameter mergeDp.k can be used to merge two components that are connected in series. Parameter from_dp also has an influence of the computational speed.

Following script can be used in Dymola to compare the CPU times. For this script to work, make sure that Dymola stores at least 4 results.

cpuOld=OutputCPUtime;
evaluateOld=Evaluate;
OutputCPUtime:=true;
simulateModel("Buildings.Fluid.Examples.Performance.Example3(from_dp.k=false, mergeDp.k=false, nRes.k=10)", stopTime=1000, numberOfIntervals=10, method="dassl", resultFile="Example3");
simulateModel("Buildings.Fluid.Examples.Performance.Example3(from_dp.k=false, mergeDp.k=true, nRes.k=10)", stopTime=1000, numberOfIntervals=10, method="dassl", resultFile="Example3");
simulateModel("Buildings.Fluid.Examples.Performance.Example3(from_dp.k=true, mergeDp.k=false, nRes.k=10)", stopTime=1000, numberOfIntervals=10, method="dassl", resultFile="Example3");
simulateModel("Buildings.Fluid.Examples.Performance.Example3(from_dp.k=true, mergeDp.k=true, nRes.k=10)", stopTime=1000, numberOfIntervals=10, method="dassl", resultFile="Example3");
createPlot(id=1, position={15, 10, 592, 421}, range={0.0, 1000.0, -0.01, 8}, autoscale=false, grid=true);
plotExpression(apply(Example3[end-3].CPUtime), false, "from_dp=false, mergeDp=false", 1);
plotExpression(apply(Example3[end-2].CPUtime), false, "from_dp=false, mergeDp=true", 1);
plotExpression(apply(Example3[end-1].CPUtime), false, "from_dp=true, mergeDp=false", 1);
plotExpression(apply(Example3[end].CPUtime), false, "from_dp=true, mergeDp=true", 1);
OutputCPUtime=cpuOld;
Evaluate=evaluateOld;

See Jorissen et al. (2015) for a discussion.

References

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
MassFlowRatem_flow_nominal1Nominal mass flow rate [kg/s]
PressureDifferencedp_nominal1Pressure drop at nominal mass flow rate [Pa]

Modelica definition

model Example3 "Example 3 model with mixed series/parallel pressure drop components" extends Modelica.Icons.Example; package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater; parameter Modelica.SIunits.MassFlowRate m_flow_nominal=1 "Nominal mass flow rate"; parameter Modelica.SIunits.PressureDifference dp_nominal=1 "Pressure drop at nominal mass flow rate"; Fluid.Movers.FlowControlled_m_flow pump( redeclare package Medium = Medium, m_flow_nominal=m_flow_nominal, use_inputFilter=false, allowFlowReversal=false, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, nominalValuesDefineDefaultPressureCurve=true) "Pump model with unidirectional flow"; Fluid.Sources.Boundary_pT bou(redeclare package Medium = Medium, nPorts=1) "Boundary for absolute pressure boundary condition"; Modelica.Blocks.Sources.Pulse pulse(period=1) "Pulse input"; FixedResistances.PressureDrop[nRes.k] res( redeclare each package Medium = Medium, each m_flow_nominal=m_flow_nominal, each from_dp=from_dp.k, each allowFlowReversal=false, dp_nominal={dp_nominal*(1 + mod(i, 3)) + (if mergeDp.k then 0 else dp_nominal) for i in 1:nRes.k}) "First pressure drop component"; Modelica.Blocks.Sources.BooleanConstant mergeDp(k=true) "Block for easily changing parameter mergeDp.k"; Modelica.Blocks.Sources.BooleanConstant from_dp(k=true) "Block for easily changing parameter from_dp.k"; FixedResistances.PressureDrop[nRes.k] res1( redeclare package Medium = Medium, each m_flow_nominal=m_flow_nominal, each from_dp=from_dp.k, each allowFlowReversal=false, each dp_nominal=if mergeDp.k then 0 else dp_nominal) "Second pressure drop component"; Modelica.Blocks.Sources.IntegerConstant nRes(k=6) "Block for easily changing parameter nRes.k"; equation connect(pump.port_a, bou.ports[1]); connect(pulse.y, pump.m_flow_in); connect(res.port_b, res1.port_a); for i in 1:nRes.k loop connect(res[i].port_a, pump.port_b); connect(res1[i].port_b, pump.port_a); end for; end Example3;

Buildings.Fluid.Examples.Performance.Example4 Buildings.Fluid.Examples.Performance.Example4

Example 4 model of simple condensing heat exchanger

Buildings.Fluid.Examples.Performance.Example4

Information

This example generates a non-linear algebraic loop that consists of 12 equations before manipulation. This loop can be decoupled and removed by changing the equation

port_a.m_flow + port_b.m_flow = -mWat_flow;

in Buildings.Fluid.Interfaces.StaticTwoPortConservationEquation to

port_a.m_flow + port_b.m_flow = 0;

See Jorissen et al. (2015) for a discussion.

References

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
BooleanallowFlowReversalfalse= false to simplify equations, assuming, but not enforcing, no flow reversal

Modelica definition

model Example4 "Example 4 model of simple condensing heat exchanger" extends Modelica.Icons.Example; package Medium = Buildings.Media.Air; parameter Boolean allowFlowReversal=false "= false to simplify equations, assuming, but not enforcing, no flow reversal"; Modelica.SIunits.MassFlowRate m_condens = min(0, -vol.ports[1].m_flow*(bou.X[1] - xSat.X[1])) "Water vapor mass flow rate"; Fluid.MixingVolumes.MixingVolumeMoistAir vol( nPorts=2, ports(m_flow(min={0,-Modelica.Constants.inf})), redeclare package Medium = Medium, massDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, m_flow_nominal=1, V=1, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, allowFlowReversal=allowFlowReversal, prescribedHeatFlowRate=true) "Mixing volume for extracting moisture"; Fluid.HeatExchangers.ConstantEffectiveness hex( redeclare package Medium1 = Medium, redeclare package Medium2 = Medium, m1_flow_nominal=1, m2_flow_nominal=1, dp1_nominal=0, dp2_nominal=0, allowFlowReversal1=allowFlowReversal, allowFlowReversal2=allowFlowReversal) "Heat exchanger"; Fluid.Sources.Boundary_pT bou( redeclare package Medium = Medium, p=Medium.p_default + 1000, use_p_in=false, use_T_in=true, X={0.02,0.98}, nPorts=2) "Sink and source"; Fluid.Sources.MassFlowSource_T sou( redeclare package Medium = Medium, m_flow=1, T=273.15, nPorts=1) "Air source"; Fluid.Sources.Boundary_pT sin(redeclare package Medium = Medium, nPorts=1) "Air sink"; Modelica.Blocks.Sources.RealExpression mCond(y=m_condens); Buildings.Utilities.Psychrometrics.X_pTphi xSat(use_p_in=false) "Block for converting relative humidity into absolute humidity"; Modelica.Blocks.Sources.Constant phiSat(k=1) "Humidity of 100%"; Modelica.Blocks.Sources.Ramp Tin( duration=1, height=20, offset=293.15) "Inlet temperature ramp"; FixedResistances.PressureDrop res( redeclare package Medium = Medium, m_flow_nominal=1, dp_nominal=100, allowFlowReversal=allowFlowReversal, from_dp=true) "Pressure drop component"; Fluid.Sensors.TemperatureTwoPort senTem( redeclare package Medium = Medium, allowFlowReversal=false, m_flow_nominal=1, tau=0) "Temperature sensor"; equation connect(phiSat.y, xSat.phi); connect(mCond.y, vol.mWat_flow); connect(Tin.y, bou.T_in); connect(res.port_b, sin.ports[1]); connect(senTem.port_b, vol.ports[1]); connect(senTem.T, xSat.T); connect(vol.ports[2], res.port_a); connect(hex.port_a1, sou.ports[1]); connect(hex.port_a2, bou.ports[1]); connect(hex.port_b1, bou.ports[2]); connect(hex.port_b2, senTem.port_a); end Example4;

Buildings.Fluid.Examples.Performance.Example5 Buildings.Fluid.Examples.Performance.Example5

Example 5 model of Modelica code that is inefficiently compiled into C-code

Buildings.Fluid.Examples.Performance.Example5

Information

This example illustrates the impact of Modelica code formulations on the C-code.

Compare the C-code in dsmodel.c when setting the parameter efficient to true or false and when adding annotation(Evaluate=true) to the parameter efficient.

This produces:

Efficient = false and Evaluate = false

helpvar[0] = sin(Time);
F_[0] = helpvar[0]*(IF DP_[0] THEN W_[0] ELSE DP_[1]+DP_[2]+DP_[3]);

Efficient = false and Evaluate = true

helpvar[0] = sin(Time);
F_[0] = helpvar[0]*(DP_[0]+DP_[1]+DP_[2]);

Efficient = true and Evaluate = true

helpvar[0] = sin(Time);
F_[0] = helpvar[0]*W_[1];

The last option requires much less operations to be performed and is therefore more efficient.

See Jorissen et al. (2015) for a discussion.

References

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
Booleanefficientfalse 
Reala[3]1:3 
Realbsum(a) 

Modelica definition

model Example5 "Example 5 model of Modelica code that is inefficiently compiled into C-code" extends Modelica.Icons.Example; parameter Boolean efficient = false; parameter Real[3] a = 1:3; parameter Real b=sum(a); Real c; initial equation c=0; equation der(c) = sin(time)*(if efficient then b else sum(a)); end Example5;

Buildings.Fluid.Examples.Performance.Example6 Buildings.Fluid.Examples.Performance.Example6

Example 6 model of Modelica code that is inefficiently compiled into C-code

Buildings.Fluid.Examples.Performance.Example6

Information

This example, together with Buildings.Fluid.Examples.Performance.Example7, illustrates the overhead generated by divisions by parameters. See Jorissen et al. (2015) for a complementary discussion.

Running the following commands allows comparing the CPU times of the two models, disregarding as much as possible the influence of the integrator:

simulateModel("Buildings.Fluid.Examples.PerformanceExamples.Example6", stopTime=100, numberOfIntervals=1, method="Rkfix4", fixedstepsize=0.001, resultFile="Example6");
simulateModel("Buildings.Fluid.Examples.PerformanceExamples.Example7", stopTime=100, numberOfIntervals=1, method="Rkfix4", fixedstepsize=0.001, resultFile="Example7");

Comparing the CPU times indicates a speed improvement of 56%. This difference almost disappears when adding annotation(Evaluate=true) to R and C.

In dsmodel.c we find:

DynamicsSection
W_[2] = divmacro(X_[0]-X_[1],"T[1]-T[2]",DP_[0],"R");
F_[0] = divmacro(W_[1]-W_[2],"Q_flow[1]-Q_flow[2]",DP_[1],"C");

This suggests that the parameter division needs to be handled during each function evaluation, probably causing the increased overhead.

The following command allows comparing the CPU times objectively.

simulateModel("Buildings.Fluid.Examples.Performance.Example6", stopTime=100, numberOfIntervals=1, method="Euler", fixedstepsize=0.001, resultFile="Example6");

See Jorissen et al. (2015) for a discussion.

References

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
IntegernCapacitors500 
RealR0.001 
RealC1000 

Modelica definition

model Example6 "Example 6 model of Modelica code that is inefficiently compiled into C-code" extends Modelica.Icons.Example; parameter Integer nCapacitors = 500; parameter Real R = 0.001; //annotation(Evaluate=true); parameter Real C = 1000; //annotation(Evaluate=true); Real[nCapacitors] T; Real[nCapacitors+1] Q_flow; initial equation T = fill(273.15,nCapacitors); equation Q_flow[1]=((273.15+sin(time))-T[1])/R; der(T[1])=(Q_flow[1]-Q_flow[2])/C; for i in 2:nCapacitors loop Q_flow[i] = (T[i-1] - T[i])/R; der(T[i])=(Q_flow[i]-Q_flow[i+1])/C; end for; Q_flow[nCapacitors+1]=0; //adiabatic end Example6;

Buildings.Fluid.Examples.Performance.Example7 Buildings.Fluid.Examples.Performance.Example7

Example 7 model of Modelica code that is more efficiently compiled into C-code

Buildings.Fluid.Examples.Performance.Example7

Information

See Buildings.Fluid.Examples.Performance.Example6 for the documentation.

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
IntegernTem500 
RealR0.001 
RealC1000 
RealtauInv1/(R*C) 

Modelica definition

model Example7 "Example 7 model of Modelica code that is more efficiently compiled into C-code" extends Modelica.Icons.Example; parameter Integer nTem = 500; parameter Real R = 0.001; parameter Real C = 1000; parameter Real tauInv = 1/(R*C); Real[nTem] T; initial equation T = fill(273.15, nTem); equation der(T[1])= ((273.15+sin(time))-2*T[1] + T[2])*tauInv; for i in 2:nTem-1 loop der(T[i])=(T[i+1]+T[i-1]-2*T[i])*tauInv; end for; der(T[nTem])= (T[nTem-1]-T[nTem])*tauInv; end Example7;

Buildings.Fluid.Examples.Performance.Example8 Buildings.Fluid.Examples.Performance.Example8

Common subexpression elimination example

Buildings.Fluid.Examples.Performance.Example8

Information

This is a very simple example demonstrating common subexpression elimination. The Dymola generated C-code of this model is:

W_[0] = sin(Time+1);
W_[1] = W_[0];

Hence, the sine and addition are evaluated once only, which is more efficient.

Extends from Modelica.Icons.Example (Icon for runnable examples).

Modelica definition

model Example8 "Common subexpression elimination example" extends Modelica.Icons.Example; Real a = sin(time+1); Real b = sin(time+1); end Example8;