Skip to content

Commit

Permalink
Develop (#4)
Browse files Browse the repository at this point in the history
* adding examples and basic people express structure

* streamlining and corrections

streamline experiments for tea cup example to run for 60 minutes; make use of information level for temperature (this is not Kelvin and so degrees may be negative in general...)

* Update Fleet.mo

State of affairs when getting the error for connecting potentialPassengerMiles (inside the expandable connector) to RMP.u1

* adjusting physical models

correcting errors in formulae and making TeaCupPhysical2.mo a more elaborate model with structural parameters

* complete fleet module

* building PEX

* finish staff and building passengers

This is the commit that is relevant with regard to the expandable connector issue (#2) for the main model

* finishing passenger subsystem

runs and passes first test

* final touches

* get PEX running

Base run now shows that everything works fine

* fixed spelling

that was quite involved ... ;-)

* minor fixes

* exogenous version added

Passenger component now has switchable input for peoplesFare and travelFrequency

* final touches

streamlining model plots and adding presentation and notebook files to resources

* Update README.md

* Update README.md

* update package icon

* Update ISDC2022_Workshop232.nb

* added testingNotebook

modified tests for fleet and included them in testing Notebook

* fixed testing

TestReport now runs fine from within Workshop Notebook

* adding staff tests

* Fix Base.Run

switches now working for passengers module

* Update ISDC2022_Workshop232.nb

* add resources

adding Poster and updated WS presentation file

* Update ISDC2022_Workshop232.nb

Final version
  • Loading branch information
gwr69 authored Jul 21, 2022
1 parent d85d85f commit ca1627e
Show file tree
Hide file tree
Showing 63 changed files with 128,139 additions and 22,943 deletions.
44 changes: 44 additions & 0 deletions ISDC2022_Workshops/Components/Fleet.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
within ISDC2022_Workshops.Components;

model Fleet "People express fleet"
extends Interfaces.Fleet;
parameter BusinessSimulation.Units.Rate growthTarget(displayUnit = "1/yr") = 3.17097919837646e-09 "Growth rate envisoned by Don Burr";
parameter BusinessSimulation.Units.TangibleAssets initAC = 3 "Initial number of aircraft";
protected
BusinessSimulation.Stocks.MaterialStock aircraft(initialValue = initAC) "Aircraft of norm size in the fleet" annotation(Placement(visible = true, transformation(origin = {0, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.SourcesOrSinks.ExponentialChange growing annotation(Placement(visible = true, transformation(origin = {-40, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.ConstantConverter targetGrowth(redeclare replaceable type OutputType = BusinessSimulation.Units.Rate, value = growthTarget) "Envisioned growth" annotation(Placement(visible = true, transformation(origin = {-120, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Product_3 availableSeatMiles(redeclare replaceable type OutputType = BusinessSimulation.Units.AmountRate) "Available seat miles" annotation(Placement(visible = true, transformation(origin = {75, 20}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Min revenuePassengerMiles "Revenue passenger miles (RPM)" annotation(Placement(visible = true, transformation(origin = {30, 40}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Division_Guarded loadFactor(redeclare replaceable type OutputType = BusinessSimulation.Units.Fraction) "Utilization of seat capacity" annotation(Placement(visible = true, transformation(origin = {-10, 30}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.ConstantConverterRate opDaysPerYear(redeclare replaceable type ValueType = BusinessSimulation.Units.Time_days, value = 31104000, timeBaseString = "year") "Operational days per year" annotation(Placement(visible = true, transformation(origin = {125, 15}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.ConstantConverterRate dailyCapacityPerPlane(value(displayUnit = "thousand") = 360000, timeBaseString = "day", redeclare replaceable type ValueType = BusinessSimulation.Units.Amount) "Operational days per ye" annotation(Placement(visible = true, transformation(origin = {115, 48.013}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.DiscreteDelay.Smooth perceivedLoadFactor(delayTime(displayUnit = "mo") = 7884000, init = BusinessSimulation.Types.InitializationOptions.SteadyState) annotation(Placement(visible = true, transformation(origin = {-40, 30}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Lookup.ConcaveLookupPositive adjFactor(y0 = 0, s = 0.2) "Adjustment factor for growth rate" annotation(Placement(visible = true, transformation(origin = {-80, 30}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Product_2 fracGrowthRate "Fractional growth rate fleet" annotation(Placement(visible = true, transformation(origin = {-80, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
// illustration
BusinessSimulation.CausalLoop.InfoFlowIndicator lab2 annotation(Placement(visible = true, transformation(origin = {-32.37, 62.633}, extent = {{-10, -10}, {10, 10}}, rotation = -360)));
BusinessSimulation.CausalLoop.InfoFlowIndicator lab3 annotation(Placement(visible = true, transformation(origin = {8.394, 50}, extent = {{-10, -10}, {10, 10}}, rotation = -270)));
BusinessSimulation.CausalLoop.InfoFlowIndicator lab4 annotation(Placement(visible = true, transformation(origin = {27.782, 75}, extent = {{-10, -10}, {10, 10}}, rotation = -720)));
equation
connect(growing.massPort, aircraft.inflow) annotation(Line(visible = true, origin = {-20, -30}, points = {{-10, 0}, {10, 0}}, color = {128, 0, 128}));
connect(aircraft.y1, availableSeatMiles.u3) annotation(Line(visible = true, origin = {75.029, -15}, points = {{-64.529, -20}, {23.356, -20}, {23.356, 30}, {7.971, 30}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(revenuePassengerMiles.u2, availableSeatMiles.y) annotation(Line(visible = true, origin = {49.127, 27.5}, points = {{-11.127, 7.5}, {2.384, 7.5}, {2.384, -7.5}, {17.873, -7.5}}, color = {0, 0, 128}, smooth = Smooth.Bezier));
connect(revenuePassengerMiles.y, loadFactor.u1) annotation(Line(visible = true, origin = {12.5, 37.5}, points = {{9.5, 2.5}, {2.5, 2.5}, {2.5, -2.5}, {-14.5, -2.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(availableSeatMiles.y, loadFactor.u2) annotation(Line(visible = true, origin = {45.801, 22.5}, points = {{21.199, -2.5}, {-25.801, -2.5}, {-25.801, 2.5}, {-47.801, 2.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(opDaysPerYear.y, availableSeatMiles.u2) annotation(Line(visible = true, origin = {104.699, 17.5}, points = {{14.301, -2.5}, {0.301, -2.5}, {0.301, 2.5}, {-21.699, 2.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(io.potentialPassengerMiles, revenuePassengerMiles.u1) "input potentialPassengerMiles (Rate)" annotation(Line(visible = true, origin = {32, 71}, points = {{-32, 34}, {-32, 9}, {28, 9}, {28, -26}, {6, -26}}, color = {0, 0, 128}, smooth = Smooth.Bezier));
connect(dailyCapacityPerPlane.y, availableSeatMiles.u1) annotation(Line(visible = true, origin = {98, 36.507}, points = {{11, 11.506}, {-3, 11.506}, {-3, -11.507}, {-15, -11.507}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(perceivedLoadFactor.u, loadFactor.y) annotation(Line(visible = true, origin = {-24.319, 30}, points = {{-6.319, 0}, {6.319, 0}}, color = {0, 0, 128}));
connect(perceivedLoadFactor.y, adjFactor.u) annotation(Line(visible = true, origin = {-65.227, 29.203}, points = {{15.227, 0.797}, {-7.613, 0.797}, {-6.773, 0.797}}, color = {1, 37, 163}));
connect(targetGrowth.y, fracGrowthRate.u2) annotation(Line(visible = true, origin = {-102.523, -12.5}, points = {{-11.477, -7.5}, {2.523, -7.5}, {2.523, 7.5}, {14.523, 7.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(adjFactor.y, fracGrowthRate.u1) annotation(Line(visible = true, origin = {-94, 17.5}, points = {{6, 12.5}, {-6, 12.5}, {-6, -12.5}, {6, -12.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(fracGrowthRate.y, growing.u) annotation(Line(visible = true, origin = {-54, -6.667}, points = {{-18, 6.667}, {9, 6.667}, {9, -13.333}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(fracGrowthRate.y, io.growthRate) "output fractional growth rate" annotation(Line(visible = true, origin = {-38.4, 45}, points = {{-33.6, -45}, {-21.6, -45}, {-21.6, 15}, {38.4, 15}, {38.4, 60}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(aircraft.y, io.aircraft) annotation(Line(visible = true, origin = {2.083, 51.35}, points = {{2.917, -70.95}, {2.917, 12.02}, {-2.083, 12.02}, {-2.083, 53.65}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(revenuePassengerMiles.y, io.RPM) "output revenue passenger miles (RPM)" annotation(Line(visible = true, origin = {7.333, 61.667}, points = {{14.667, -21.667}, {4.34, -21.667}, {4.34, 10.833}, {-7.333, 10.833}, {-7.333, 43.333}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
annotation(Documentation(info = "<html>
<p class=\"aside\">This information is part of the ISDC2022 Workshops package.</p>
<p>The fleet of planes will grow (or decline) at a fractional rate that is determined by CEO Burr's vision, which is modulated by the perceived <code>loadFactor</code>.</p>
</html>"), Diagram(coordinateSystem(extent = {{-148.5, -105}, {148.5, 105}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5}), graphics = {Text(visible = true, origin = {-55, 98.848}, textColor = {0, 0, 128}, extent = {{-34.511, -3.848}, {34.511, 3.848}}, textString = "potentialPassengerMiles", fontSize = 12, fontName = "Lato", horizontalAlignment = TextAlignment.Right), Text(visible = true, origin = {54.511, 98.848}, textColor = {0, 0, 128}, extent = {{-34.511, -3.848}, {34.511, 3.848}}, textString = "aircraft", fontSize = 12, fontName = "Lato", horizontalAlignment = TextAlignment.Left), Text(visible = true, origin = {54.511, 93.848}, textColor = {0, 0, 128}, extent = {{-34.511, -3.848}, {34.511, 3.848}}, textString = "growthRate", fontSize = 12, fontName = "Lato", horizontalAlignment = TextAlignment.Left), Text(visible = true, origin = {54.511, 88.848}, textColor = {0, 0, 128}, extent = {{-34.511, -3.848}, {34.511, 3.848}}, textString = "revenuePassengerMiles", fontSize = 12, fontName = "Lato", horizontalAlignment = TextAlignment.Left)}));
end Fleet;
41 changes: 41 additions & 0 deletions ISDC2022_Workshops/Components/HiringPolicy.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
within ISDC2022_Workshops.Components;

block HiringPolicy "Setting the hiring rate"
extends BusinessSimulation.Interfaces.PartialConverters.Policy_SO;
parameter Real MCM(unit = "people") = 60 "Maximum capapcity multiplier, i.e., max staff per plane";
parameter BusinessSimulation.Units.Rate RI(displayUnit = "1/yr") = 9.51293759512938e-07 "Recruiting intensity, i.e., job interviews per recruiter per year";
parameter BusinessSimulation.Units.Amount AR(displayUnit = "percent") = 0.03 "Fraction of applicants accepted";
BusinessSimulation.Interfaces.Connectors.RealInput planes "Number of aircraft in the fleet" annotation(Placement(visible = true, transformation(origin = {-145, 60}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-110, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Interfaces.Connectors.RealInput recruiters "Staff available for screening candidates" annotation(Placement(visible = true, transformation(origin = {-145, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-110, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Interfaces.Connectors.RealInput totalStaff "Total staff currently employed" annotation(Placement(visible = true, transformation(origin = {-145, -60}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-110, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Product_2 maxCapacity "Maximum capacity for staff" annotation(Placement(visible = true, transformation(origin = {-60, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.ConstantConverter maxStaffPerPlane(value = MCM) "Maximum staff per plane" annotation(Placement(visible = true, transformation(origin = {-110, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Logical.Less belowLimitQ "True, if total staff below limit on staff" annotation(Placement(visible = true, transformation(origin = {40, 20}, extent = {{-10, 10}, {10, -10}}, rotation = 0)));
BusinessSimulation.Converters.ConstantConverterRate noHiring(timeBaseString = "year", value = 0) "Zero hiring rate" annotation(Placement(visible = true, transformation(origin = {40, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Logical.Switch hiringRate(redeclare replaceable type OutputType = BusinessSimulation.Units.Rate) annotation(Placement(visible = true, transformation(origin = {80, 0}, extent = {{-10, -10}, {10, 10}}, rotation = -360)));
BusinessSimulation.Converters.ConstantConverter recruitingLoad(value = RI) "Job interview rate per recruiter" annotation(Placement(visible = true, transformation(origin = {-120, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Product_2 interviewRate(redeclare replaceable type OutputType = BusinessSimulation.Units.Rate) "Job interviews per period" annotation(Placement(visible = true, transformation(origin = {-80, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.ConstantConverter acceptedFraction(value = AR) "Fraction of applicants accepted" annotation(Placement(visible = true, transformation(origin = {-70, 15}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
BusinessSimulation.Converters.Product_2 unrestrictedHiringRate(redeclare replaceable type OutputType = BusinessSimulation.Units.Rate) "Hiring rate before taking capacity restrictions into account" annotation(Placement(visible = true, transformation(origin = {-32.465, 5}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(planes, maxCapacity.u1) annotation(Line(visible = true, origin = {-118.494, 50}, points = {{-26.506, 10}, {15.636, 10}, {15.636, -5}, {50.494, -5}}, color = {0, 0, 128}, smooth = Smooth.Bezier));
connect(maxStaffPerPlane.y, maxCapacity.u2) annotation(Line(visible = true, origin = {-90.045, 27.5}, points = {{-13.955, -7.5}, {5.045, -7.5}, {5.045, 7.5}, {22.045, 7.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(totalStaff, belowLimitQ.u1) annotation(Line(visible = true, origin = {-18.25, -12.5}, points = {{-126.75, -47.5}, {5.103, -47.5}, {5.103, 27.5}, {50.25, 27.5}}, color = {0, 0, 128}, smooth = Smooth.Bezier));
connect(maxCapacity.y, belowLimitQ.u2) annotation(Line(visible = true, origin = {-5, 32.5}, points = {{-47, 7.5}, {5, 7.5}, {5, -7.5}, {37, -7.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(hiringRate.y, y) annotation(Line(visible = true, origin = {124, 0}, points = {{-36, 0}, {36, -0}}, color = {1, 37, 163}));
connect(belowLimitQ.y, hiringRate.u_cond) annotation(Line(visible = true, origin = {69.341, 15.996}, points = {{-21.341, 4.004}, {10.671, 4.004}, {10.671, -8.008}}, color = {190, 52, 178}, smooth = Smooth.Bezier));
connect(noHiring.y, hiringRate.u2) annotation(Line(visible = true, origin = {62, -17.5}, points = {{-16, -12.5}, {-2, -12.5}, {-2, 12.5}, {10, 12.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(recruiters, interviewRate.u1) annotation(Line(visible = true, origin = {-113.25, -7.5}, points = {{-31.75, 7.5}, {3.25, 7.5}, {3.25, -7.5}, {25.25, -7.5}}, color = {0, 0, 128}, smooth = Smooth.Bezier));
connect(recruitingLoad.y, interviewRate.u2) annotation(Line(visible = true, origin = {-103, -32.5}, points = {{-11, -7.5}, {-2, -7.5}, {-2, 7.5}, {15, 7.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(acceptedFraction.y, unrestrictedHiringRate.u1) annotation(Line(visible = true, origin = {-53.616, 12.5}, points = {{-10.384, 2.5}, {-1.384, 2.5}, {-1.384, -2.5}, {13.151, -2.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(interviewRate.y, unrestrictedHiringRate.u2) annotation(Line(visible = true, origin = {-59.609, -12.5}, points = {{-12.391, -7.5}, {-0.391, -7.5}, {-0.391, 12.5}, {19.144, 12.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
connect(unrestrictedHiringRate.y, hiringRate.u1) annotation(Line(visible = true, origin = {22.5, 2.5}, points = {{-46.965, 2.5}, {-2.5, 2.5}, {-2.5, 2.5}, {49.5, 2.5}}, color = {1, 37, 163}, smooth = Smooth.Bezier));
annotation(Documentation(info = "<html>
<p class=\"aside\">This information is part of the ISDC2022 Workshops package.</p>
<p>Hiring in People Express is almost entirely driven by the size of the experienced workforce, which needs to interview candidates. PEX prides itself not to fire staff—unless proven incompetent—and will not hire more than needed, which here is checked with regard to a multiple of the current fleet size.</p>
<h4>See also</h4>
<p>
<a href=\"modelica://ISDC2022_Workshops.Components.Staff\">Staff</a>
</p>
</html>"), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10}), graphics = {Text(visible = true, textColor = {0, 0, 128}, extent = {{-96.456, -12}, {96.456, 12}}, textString = "RECRUITING", fontName = "Lato Black", textStyle = {TextStyle.Bold})}));
end HiringPolicy;
Loading

0 comments on commit ca1627e

Please sign in to comment.