mdl convert
This commit is contained in:
parent
9d7064f762
commit
6775dfcb27
|
@ -0,0 +1,3 @@
|
|||
import pysd
|
||||
|
||||
model = pysd.read_vensim('./vensim/bes.mdl')
|
Binary file not shown.
|
@ -0,0 +1,692 @@
|
|||
"""
|
||||
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
|
Loading…
Reference in New Issue