""" Python model 'bes.py' Translated using PySD """ from pathlib import Path import numpy as np from pysd.py_backend.statefuls import Integ from pysd import Component __pysd_version__ = "3.14.2" __data = {"scope": None, "time": lambda: 0} _root = Path(__file__).parent component = Component() ####################################################################### # CONTROL VARIABLES # ####################################################################### _control_vars = { "initial_time": lambda: 0, "final_time": lambda: 120, "time_step": lambda: 1, "saveper": lambda: time_step(), } def _init_outer_references(data): for key in data: __data[key] = data[key] @component.add(name="Time") def time(): """ Current time of the model. """ return __data["time"]() @component.add( name="FINAL TIME", units="Month", comp_type="Constant", comp_subtype="Normal" ) def final_time(): """ The final time for the simulation. """ return __data["time"].final_time() @component.add( name="INITIAL TIME", units="Month", comp_type="Constant", comp_subtype="Normal" ) def initial_time(): """ The initial time for the simulation. """ return __data["time"].initial_time() @component.add( name="SAVEPER", units="Month", limits=(0.0, np.nan), comp_type="Auxiliary", comp_subtype="Normal", depends_on={"time_step": 1}, ) def saveper(): """ The frequency with which output is stored. """ return __data["time"].saveper() @component.add( name="TIME STEP", units="Month", limits=(0.0, np.nan), comp_type="Constant", comp_subtype="Normal", ) def time_step(): """ The time step for the simulation. """ return __data["time"].time_step() ####################################################################### # MODEL VARIABLES # ####################################################################### @component.add( name="Noise", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"time": 1} ) def noise(): return float(np.random.uniform(0, 5, size=())) @component.add( name="Demand", units="loaves/Day", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"base_demand": 1, "noise": 1}, ) def demand(): return base_demand() + noise() @component.add( name="Amplitude of Seasonal Variations", units="loaves", comp_type="Constant", comp_subtype="Normal", ) def amplitude_of_seasonal_variations(): return 30 @component.add(name="phi", units="radians", comp_type="Constant", comp_subtype="Normal") def phi(): return 0 @component.add( name="Base Demand", units="loaves/Day", comp_type="Constant", comp_subtype="Normal" ) def base_demand(): return 200 @component.add( name="Sigma", units="loaves/Day", comp_type="Constant", comp_subtype="Normal" ) def sigma(): return 5 @component.add(name="Period", units="days", comp_type="Constant", comp_subtype="Normal") def period(): return 7 @component.add( name="Available Workers", units="workers", comp_type="Constant", comp_subtype="Normal", ) def available_workers(): return 2 @component.add( name="Base Rate", units="loaves/Day", comp_type="Constant", comp_subtype="Normal" ) def base_rate(): return 200 @component.add( name="Lead Time Sugar", units="days", comp_type="Constant", comp_subtype="Normal" ) def lead_time_sugar(): return 1 @component.add( name="Bread Production", units="loaves/Day", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"base_rate": 1, "minresource": 1, "labour_efficiency": 1}, ) def bread_production(): return float(np.minimum(base_rate(), minresource())) * labour_efficiency() @component.add( name="Water Safety", units="litres", comp_type="Constant", comp_subtype="Normal" ) def water_safety(): return 300 @component.add( name="Sugar Purchase", units="kg", comp_type="Auxiliary", comp_subtype="Normal", depends_on={ "bread_production": 1, "suger_per_loaf": 1, "sugar_safety": 1, "sugar": 1, "lead_time_sugar": 1, }, ) def sugar_purchase(): return float( np.maximum( 0, (bread_production() * suger_per_loaf() + sugar_safety() - sugar()) / lead_time_sugar(), ) ) @component.add( name="Flour per Loaf", units="kg/loaf", comp_type="Constant", comp_subtype="Normal" ) def flour_per_loaf(): return 0.3 @component.add( name="Suger per Loaf", units="kg/loaf", comp_type="Constant", comp_subtype="Normal" ) def suger_per_loaf(): return 0.02 @component.add( name="MinSugarWater", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"sugar": 1, "suger_per_loaf": 1, "water_per_loaf": 1, "water": 1}, ) def minsugarwater(): return float(np.minimum(sugar() / suger_per_loaf(), water() / water_per_loaf())) @component.add( name="Yeast Purchase", units="kg", comp_type="Auxiliary", comp_subtype="Normal", depends_on={ "bread_production": 1, "yeast_per_loaf": 1, "yeast_safety": 1, "yeast": 1, "lead_time_yeast": 1, }, ) def yeast_purchase(): return float( np.maximum( 0, (bread_production() * yeast_per_loaf() + yeast_safety() - yeast()) / lead_time_yeast(), ) ) @component.add( name="Labour Efficiency", units="Dmnl", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"available_workers": 1, "workers_required": 1}, ) def labour_efficiency(): return float(np.minimum(1, available_workers() / workers_required())) @component.add( name="Water", units="litres", comp_type="Stateful", comp_subtype="Integ", depends_on={"_integ_water": 1}, other_deps={ "_integ_water": { "initial": {}, "step": {"water_purchase": 1, "water_per_loaf": 1, "bread_production": 1}, } }, ) def water(): return _integ_water() _integ_water = Integ( lambda: water_purchase() - bread_production() * water_per_loaf(), lambda: 2000, "_integ_water", ) @component.add( name="Water Cost", units="$/litre", comp_type="Constant", comp_subtype="Normal" ) def water_cost(): return 0.001 @component.add( name="Lead Time Water", units="days", comp_type="Constant", comp_subtype="Normal" ) def lead_time_water(): return 1 @component.add( name="Lead Time Yeast", units="days", comp_type="Constant", comp_subtype="Normal" ) def lead_time_yeast(): return 1 @component.add( name="Water Purchase", units="litres", comp_type="Auxiliary", comp_subtype="Normal", depends_on={ "bread_production": 1, "water_per_loaf": 1, "water_safety": 1, "water": 1, "lead_time_water": 1, }, ) def water_purchase(): return float( np.maximum( 0, (bread_production() * water_per_loaf() + water_safety() - water()) / lead_time_water(), ) ) @component.add( name="Workers Required", units="workers", comp_type="Constant", comp_subtype="Normal", ) def workers_required(): return 2 @component.add( name="MinFlourYeast", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"flour": 1, "flour_per_loaf": 1, "yeast_per_loaf": 1, "yeast": 1}, ) def minflouryeast(): return float(np.minimum(flour() / flour_per_loaf(), yeast() / yeast_per_loaf())) @component.add( name="MinResource", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"minflouryeast": 1, "minsugarwater": 1}, ) def minresource(): return float(np.minimum(minflouryeast(), minsugarwater())) @component.add( name="Water per Loaf", units="litres/loaf", comp_type="Constant", comp_subtype="Normal", ) def water_per_loaf(): return 0.2 @component.add( name="Waste Bread", units="loaves/Day", comp_type="Constant", comp_subtype="Normal" ) def waste_bread(): return 2 @component.add( name="Raw Material Cost", units="$", comp_type="Auxiliary", comp_subtype="Normal", depends_on={ "flour_cost": 1, "flour_purchase": 1, "sugar_purchase": 1, "sugar_cost": 1, "yeast_purchase": 1, "yeast_cost": 1, "water_purchase": 1, "water_cost": 1, }, ) def raw_material_cost(): return ( flour_cost() * flour_purchase() + sugar_cost() * sugar_purchase() + yeast_cost() * yeast_purchase() + water_cost() * water_purchase() ) @component.add( name="Yeast Safety", units="kg", comp_type="Constant", comp_subtype="Normal" ) def yeast_safety(): return 10 @component.add( name="Sugar Safety", units="kg", comp_type="Constant", comp_subtype="Normal" ) def sugar_safety(): return 20 @component.add( name="Bread", units="loaves", comp_type="Stateful", comp_subtype="Integ", depends_on={"_integ_bread": 1}, other_deps={ "_integ_bread": { "initial": {}, "step": {"bread_production": 1, "waste_bread": 1, "sales": 1}, } }, ) def bread(): return _integ_bread() _integ_bread = Integ( lambda: bread_production() - waste_bread() - sales(), lambda: 0, "_integ_bread" ) @component.add( name="Flour", units="kg", comp_type="Stateful", comp_subtype="Integ", depends_on={"_integ_flour": 1}, other_deps={ "_integ_flour": { "initial": {}, "step": {"flour_purchase": 1, "flour_per_loaf": 1, "bread_production": 1}, } }, ) def flour(): return _integ_flour() _integ_flour = Integ( lambda: flour_purchase() - flour_per_loaf() * bread_production(), lambda: 1000, "_integ_flour", ) @component.add( name="Flour Cost", units="$/kg", comp_type="Constant", comp_subtype="Normal" ) def flour_cost(): return 0.5 @component.add( name="Flour Purchase", units="kg", comp_type="Auxiliary", comp_subtype="Normal", depends_on={ "bread_production": 1, "flour_per_loaf": 1, "flour_safety": 1, "flour": 1, "lead_time_flour": 1, }, ) def flour_purchase(): return float( np.maximum( 0, (bread_production() * flour_per_loaf() + flour_safety() - flour()) / lead_time_flour(), ) ) @component.add( name="Flour Safety", units="kg", comp_type="Constant", comp_subtype="Normal" ) def flour_safety(): return 200 @component.add( name="Labour Cost", units="$", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"wage_rate": 1, "total_labour_hours": 1}, ) def labour_cost(): return wage_rate() * total_labour_hours() @component.add( name="Lead Time Flour", units="days", comp_type="Constant", comp_subtype="Normal" ) def lead_time_flour(): return 1 @component.add( name="Maintainance Cost", units="$", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"maintainance_rate": 1, "money": 1}, ) def maintainance_cost(): return maintainance_rate() * money() @component.add( name="Maintainance Rate", units="fraction/Day", comp_type="Constant", comp_subtype="Normal", ) def maintainance_rate(): return 0.002 @component.add( name="Money", units="$", comp_type="Stateful", comp_subtype="Integ", depends_on={"_integ_money": 1}, other_deps={ "_integ_money": { "initial": {}, "step": { "revenue": 1, "labour_cost": 1, "maintainance_cost": 1, "raw_material_cost": 1, }, } }, ) def money(): return _integ_money() _integ_money = Integ( lambda: revenue() - labour_cost() - maintainance_cost() - raw_material_cost(), lambda: 100000, "_integ_money", ) @component.add( name="Revenue", units="$", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"sales_price": 1, "sales": 1}, ) def revenue(): return sales_price() * sales() @component.add( name="Sales", units="loaves/Day", comp_type="Auxiliary", comp_subtype="Normal", depends_on={"bread": 1, "demand": 1}, ) def sales(): return float(np.minimum(bread(), demand())) @component.add( name="Sales Price", units="$/loaf", comp_type="Constant", comp_subtype="Normal" ) def sales_price(): return 4 @component.add( name="Sugar", units="kg", comp_type="Stateful", comp_subtype="Integ", depends_on={"_integ_sugar": 1}, other_deps={ "_integ_sugar": { "initial": {}, "step": {"sugar_purchase": 1, "suger_per_loaf": 1, "bread_production": 1}, } }, ) def sugar(): return _integ_sugar() _integ_sugar = Integ( lambda: sugar_purchase() - bread_production() * suger_per_loaf(), lambda: 100, "_integ_sugar", ) @component.add( name="Sugar Cost", units="$/kg", comp_type="Constant", comp_subtype="Normal" ) def sugar_cost(): return 0.8 @component.add( name="Total Labour Hours", units="hours/Day", comp_type="Constant", comp_subtype="Normal", ) def total_labour_hours(): return 16 @component.add( name="Wage Rate", units="$/Hour", comp_type="Constant", comp_subtype="Normal" ) def wage_rate(): return 12 @component.add( name="Yeast", units="kg", comp_type="Stateful", comp_subtype="Integ", depends_on={"_integ_yeast": 1}, other_deps={ "_integ_yeast": { "initial": {}, "step": {"yeast_purchase": 1, "yeast_per_loaf": 1, "bread_production": 1}, } }, ) def yeast(): return _integ_yeast() _integ_yeast = Integ( lambda: yeast_purchase() - bread_production() * yeast_per_loaf(), lambda: 50, "_integ_yeast", ) @component.add( name="Yeast Cost", units="$/kg", comp_type="Constant", comp_subtype="Normal" ) def yeast_cost(): return 10 @component.add( name="Yeast per Loaf", units="kg/loaf", comp_type="Constant", comp_subtype="Normal" ) def yeast_per_loaf(): return 0.01