1"""
2Created on 8 mrt. 2011
3
4.. codeauthor:: jhkwakkel <j.h.kwakkel (at) tudelft (dot) nl>
5 epruyt <e.pruyt (at) tudelft (dot) nl>
6"""
7
8from math import exp
9
10from ema_workbench.connectors.vensim import VensimModel
11from ema_workbench.em_framework import (
12 RealParameter,
13 CategoricalParameter,
14 TimeSeriesOutcome,
15 perform_experiments,
16)
17from ema_workbench.util import ema_logging
18
19
20class ScarcityModel(VensimModel):
21 def returnsToScale(self, x, speed, scale):
22 return (x * 1000, scale * 1 / (1 + exp(-1 * speed * (x - 50))))
23
24 def approxLearning(self, x, speed, scale, start):
25 x = x - start
26 loc = 1 - scale
27 a = (x * 10000, scale * 1 / (1 + exp(speed * x)) + loc)
28 return a
29
30 def f(self, x, speed, loc):
31 return (x / 10, loc * 1 / (1 + exp(speed * x)))
32
33 def priceSubstite(self, x, speed, begin, end):
34 scale = 2 * end
35 start = begin - scale / 2
36
37 return (x + 2000, scale * 1 / (1 + exp(-1 * speed * x)) + start)
38
39 def run_model(self, scenario, policy):
40 """Method for running an instantiated model structure"""
41 kwargs = scenario
42 loc = kwargs.pop("lookup_shortage_loc")
43 speed = kwargs.pop("lookup_shortage_speed")
44 lookup = [self.f(x / 10, speed, loc) for x in range(0, 100)]
45 kwargs["shortage price effect lookup"] = lookup
46
47 speed = kwargs.pop("lookup_price_substitute_speed")
48 begin = kwargs.pop("lookup_price_substitute_begin")
49 end = kwargs.pop("lookup_price_substitute_end")
50 lookup = [self.priceSubstite(x, speed, begin, end) for x in range(0, 100, 10)]
51 kwargs["relative price substitute lookup"] = lookup
52
53 scale = kwargs.pop("lookup_returns_to_scale_speed")
54 speed = kwargs.pop("lookup_returns_to_scale_scale")
55 lookup = [self.returnsToScale(x, speed, scale) for x in range(0, 101, 10)]
56 kwargs["returns to scale lookup"] = lookup
57
58 scale = kwargs.pop("lookup_approximated_learning_speed")
59 speed = kwargs.pop("lookup_approximated_learning_scale")
60 start = kwargs.pop("lookup_approximated_learning_start")
61 lookup = [self.approxLearning(x, speed, scale, start) for x in range(0, 101, 10)]
62 kwargs["approximated learning effect lookup"] = lookup
63
64 super().run_model(kwargs, policy)
65
66
67if __name__ == "__main__":
68 ema_logging.log_to_stderr(ema_logging.DEBUG)
69
70 model = ScarcityModel("scarcity", wd="./models/scarcity", model_file="MetalsEMA.vpm")
71
72 model.outcomes = [
73 TimeSeriesOutcome("relative_market_price", variable_name="relative market price"),
74 TimeSeriesOutcome("supply_demand_ratio", variable_name="supply demand ratio"),
75 TimeSeriesOutcome("real_annual_demand", variable_name="real annual demand"),
76 TimeSeriesOutcome(
77 "produced_of_intrinsically_demanded", variable_name="produced of intrinsically demanded"
78 ),
79 TimeSeriesOutcome("supply", variable_name="supply"),
80 TimeSeriesOutcome(
81 "Installed_Recycling_Capacity", variable_name="Installed Recycling Capacity"
82 ),
83 TimeSeriesOutcome(
84 "Installed_Extraction_Capacity", variable_name="Installed Extraction Capacity"
85 ),
86 ]
87
88 model.uncertainties = [
89 RealParameter(
90 "price_elasticity_of_demand", 0, 0.5, variable_name="price elasticity of demand"
91 ),
92 RealParameter(
93 "fraction_of_maximum_extraction_capacity_used",
94 0.6,
95 1.2,
96 variable_name="fraction of maximum extraction capacity used",
97 ),
98 RealParameter(
99 "initial_average_recycling_cost", 1, 4, variable_name="initial average recycling cost"
100 ),
101 RealParameter(
102 "exogenously_planned_extraction_capacity",
103 0,
104 15000,
105 variable_name="exogenously planned extraction capacity",
106 ),
107 RealParameter(
108 "absolute_recycling_loss_fraction",
109 0.1,
110 0.5,
111 variable_name="absolute recycling loss fraction",
112 ),
113 RealParameter("normal_profit_margin", 0, 0.4, variable_name="normal profit margin"),
114 RealParameter(
115 "initial_annual_supply", 100000, 120000, variable_name="initial annual supply"
116 ),
117 RealParameter("initial_in_goods", 1500000, 2500000, variable_name="initial in goods"),
118 RealParameter(
119 "average_construction_time_extraction_capacity",
120 1,
121 10,
122 variable_name="average construction time extraction capacity",
123 ),
124 RealParameter(
125 "average_lifetime_extraction_capacity",
126 20,
127 40,
128 variable_name="average lifetime extraction capacity",
129 ),
130 RealParameter(
131 "average_lifetime_recycling_capacity",
132 20,
133 40,
134 variable_name="average lifetime recycling capacity",
135 ),
136 RealParameter(
137 "initial_extraction_capacity_under_construction",
138 5000,
139 20000,
140 variable_name="initial extraction capacity under construction",
141 ),
142 RealParameter(
143 "initial_recycling_capacity_under_construction",
144 5000,
145 20000,
146 variable_name="initial recycling capacity under construction",
147 ),
148 RealParameter(
149 "initial_recycling_infrastructure",
150 5000,
151 20000,
152 variable_name="initial recycling infrastructure",
153 ),
154 # order of delay
155 CategoricalParameter(
156 "order_in_goods_delay", (1, 4, 10, 1000), variable_name="order in goods delay"
157 ),
158 CategoricalParameter(
159 "order_recycling_capacity_delay",
160 (1, 4, 10),
161 variable_name="order recycling capacity delay",
162 ),
163 CategoricalParameter(
164 "order_extraction_capacity_delay",
165 (1, 4, 10),
166 variable_name="order extraction capacity delay",
167 ),
168 # uncertainties associated with lookups
169 RealParameter("lookup_shortage_loc", 20, 50, variable_name="lookup shortage loc"),
170 RealParameter("lookup_shortage_speed", 1, 5, variable_name="lookup shortage speed"),
171 RealParameter(
172 "lookup_price_substitute_speed", 0.1, 0.5, variable_name="lookup price substitute speed"
173 ),
174 RealParameter(
175 "lookup_price_substitute_begin", 3, 7, variable_name="lookup price substitute begin"
176 ),
177 RealParameter(
178 "lookup_price_substitute_end", 15, 25, variable_name="lookup price substitute end"
179 ),
180 RealParameter(
181 "lookup_returns_to_scale_speed",
182 0.01,
183 0.2,
184 variable_name="lookup returns to scale speed",
185 ),
186 RealParameter(
187 "lookup_returns_to_scale_scale", 0.3, 0.7, variable_name="lookup returns to scale scale"
188 ),
189 RealParameter(
190 "lookup_approximated_learning_speed",
191 0.01,
192 0.2,
193 variable_name="lookup approximated learning speed",
194 ),
195 RealParameter(
196 "lookup_approximated_learning_scale",
197 0.3,
198 0.6,
199 variable_name="lookup approximated learning scale",
200 ),
201 RealParameter(
202 "lookup_approximated_learning_start",
203 30,
204 60,
205 variable_name="lookup approximated learning start",
206 ),
207 ]
208
209 results = perform_experiments(model, 1000)