naohiro701 commited on
Commit
438ff43
·
verified ·
1 Parent(s): c96b8a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +124 -5
app.py CHANGED
@@ -64,8 +64,8 @@ def optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wi
64
  [(r, g) for r in regions for g in technologies],
65
  lowBound=0, cat='Continuous')
66
  curtailment = pulp.LpVariable.dicts("curtailment",
67
- [(r, t) for r in regions for t in time_steps],
68
- lowBound=0, cat='Continuous')
69
  battery_capacity = pulp.LpVariable("battery_capacity", lowBound=0, cat='Continuous')
70
  battery_charge = pulp.LpVariable.dicts("battery_charge", time_steps, lowBound=0, cat='Continuous')
71
  battery_discharge = pulp.LpVariable.dicts("battery_discharge", time_steps, lowBound=0, cat='Continuous')
@@ -80,12 +80,12 @@ def optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wi
80
  for r in regions:
81
  for t in time_steps:
82
  model += pulp.lpSum([renewable_capacity[(r, g)] * capacity_factor[g][t]
83
- for g in technologies]) + battery_discharge[t] == demand[t] + battery_charge[t] + curtailment[(r,t)], f"DemandConstraint_{r}_{t}"
84
 
85
  if t == 0:
86
  model += SOC[t] == battery_charge[t] * battery_efficiency - battery_discharge[t] * (1 / battery_efficiency), f"SOCUpdate_{t}"
87
  else:
88
- model += SOC[t] == SOC[t-1] + battery_charge[t] * battery_efficiency - battery_discharge[t] * (1 / battery_efficiency), f"SOCUpdate_{t}"
89
 
90
  model += SOC[t] <= battery_capacity, f"SOCUpperBound_{t}"
91
 
@@ -210,4 +210,123 @@ def optimize_energy_system(city_code, solar_cost, onshore_wind_cost, offshore_wi
210
  yaxis=dict(showgrid=True, gridwidth=0.5, gridcolor='lightgray')
211
  )
212
 
213
- return fig_energy, heatmaps, curtailment_values, SOC_normalized, fig_capacity_ranges, renewable_capacity
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  [(r, g) for r in regions for g in technologies],
65
  lowBound=0, cat='Continuous')
66
  curtailment = pulp.LpVariable.dicts("curtailment",
67
+ [(r, t) for r in regions for t in time_steps],
68
+ lowBound=0, cat='Continuous')
69
  battery_capacity = pulp.LpVariable("battery_capacity", lowBound=0, cat='Continuous')
70
  battery_charge = pulp.LpVariable.dicts("battery_charge", time_steps, lowBound=0, cat='Continuous')
71
  battery_discharge = pulp.LpVariable.dicts("battery_discharge", time_steps, lowBound=0, cat='Continuous')
 
80
  for r in regions:
81
  for t in time_steps:
82
  model += pulp.lpSum([renewable_capacity[(r, g)] * capacity_factor[g][t]
83
+ for g in technologies]) + battery_discharge[t] == demand[t] + battery_charge[t] + curtailment[(r, t)], f"DemandConstraint_{r}_{t}"
84
 
85
  if t == 0:
86
  model += SOC[t] == battery_charge[t] * battery_efficiency - battery_discharge[t] * (1 / battery_efficiency), f"SOCUpdate_{t}"
87
  else:
88
+ model += SOC[t] == SOC[t - 1] + battery_charge[t] * battery_efficiency - battery_discharge[t] * (1 / battery_efficiency), f"SOCUpdate_{t}"
89
 
90
  model += SOC[t] <= battery_capacity, f"SOCUpperBound_{t}"
91
 
 
210
  yaxis=dict(showgrid=True, gridwidth=0.5, gridcolor='lightgray')
211
  )
212
 
213
+ return fig_energy, heatmaps, curtailment_values, SOC_normalized, fig_capacity_ranges, renewable_capacity
214
+
215
+ # 資源コストの感度解析を行う関数
216
+ def analyze_cost_sensitivity(renewable_capacity_cost, technologies, renewable_capacity):
217
+ # コストの変動範囲(0.5倍から1.5倍)
218
+ cost_multipliers = np.linspace(0.5, 1.5, 11)
219
+
220
+ # 結果を格納する辞書
221
+ sensitivity_results = {}
222
+
223
+ for tech in technologies:
224
+ # 各技術ごとのコスト変動に対する総コストの変化を計算
225
+ original_cost = renewable_capacity_cost[tech]
226
+ total_costs = []
227
+
228
+ for multiplier in cost_multipliers:
229
+ # コストを変更
230
+ modified_cost = original_cost * multiplier
231
+ # 総コスト = 変更後のコスト * 設備容量
232
+ total_cost = modified_cost * renewable_capacity[('region1', tech)].varValue
233
+ total_costs.append(total_cost)
234
+
235
+ # 技術ごとに結果を保存
236
+ sensitivity_results[tech] = total_costs
237
+
238
+ # 可視化
239
+ fig = go.Figure()
240
+
241
+ for tech, total_costs in sensitivity_results.items():
242
+ fig.add_trace(go.Scatter(
243
+ x=cost_multipliers,
244
+ y=total_costs,
245
+ mode='lines+markers',
246
+ name=f'{tech} Cost Sensitivity'
247
+ ))
248
+
249
+ # グラフのレイアウト
250
+ fig.update_layout(
251
+ title='Cost Sensitivity Analysis: Impact of Cost Changes on Total System Cost',
252
+ xaxis_title='Cost Multiplier (0.5x to 1.5x)',
253
+ yaxis_title='Total System Cost (¥)',
254
+ hovermode='x unified',
255
+ plot_bgcolor='white',
256
+ xaxis=dict(showgrid=True, gridwidth=0.5, gridcolor='lightgray'),
257
+ yaxis=dict(showgrid=True, gridwidth=0.5, gridcolor='lightgray')
258
+ )
259
+
260
+ return fig
261
+
262
+ # Streamlit UI setup
263
+ st.set_page_config(page_title='Renewable Energy System Optimization', layout='wide')
264
+ st.title('Renewable Energy System Optimization')
265
+
266
+ st.markdown("""
267
+ ### Model Overview
268
+
269
+ This application is designed to optimize renewable energy systems for a specific region. The model allows the user to set the costs for different renewable energy technologies and battery storage, as well as minimum and maximum capacity limits for each technology. The optimization uses linear programming to minimize the total cost while ensuring demand is met, incorporating energy storage to help manage intermittency.
270
+
271
+ The renewable technologies considered are:
272
+ - Solar PV
273
+ - Onshore Wind
274
+ - Offshore Wind
275
+ - Run of River (Hydro)
276
+
277
+ The optimization problem aims to balance supply and demand at minimal cost, while also providing flexibility in the form of battery energy storage. Curtailment and battery state of charge are also considered in the model.
278
+
279
+ """)
280
+
281
+ with st.sidebar:
282
+ st.header('Input Parameters')
283
+ city_code = st.text_input("Enter City Code", value=999999)
284
+ solar_cost = st.number_input("Solar Capacity Cost (¥/MW)", value=80.0)
285
+ onshore_wind_cost = st.number_input("Onshore Wind Capacity Cost (¥/MW)", value=120.0)
286
+ offshore_wind_cost = st.number_input("Offshore Wind Capacity Cost (¥/MW)", value=180.0)
287
+ river_cost = st.number_input("River Capacity Cost (¥/MW)", value=1000.0)
288
+ battery_cost = st.number_input("Battery Cost (¥/MWh)", value=80.0)
289
+ yearly_demand = st.number_input("Yearly Power Demand (TWh/year)", value=15.0)
290
+ solar_range = st.slider("Solar Capacity Range (MW)", 0, 10000, (0, 10000))
291
+ wind_range = st.slider("Onshore Wind Capacity Range (MW)", 0, 10000, (0, 10000))
292
+ offshore_wind_range = st.slider("Offshore Wind Capacity Range (MW)", 0, 10000, (0, 10000))
293
+ river_range = st.slider("River Capacity Range (MW)", 0, 10000, (0, 10000))
294
+
295
+ if st.button('Calculate Optimal Energy Mix'):
296
+ fig_energy, heatmaps, curtailment_values, soc_per_hour, fig_capacity_ranges, renewable_capacity = optimize_energy_system(
297
+ city_code, solar_cost, onshore_wind_cost, offshore_wind_cost, river_cost, battery_cost, yearly_demand, solar_range, wind_range, river_range, offshore_wind_range
298
+ )
299
+
300
+ if fig_energy:
301
+ st.plotly_chart(fig_energy, use_container_width=True, height=800)
302
+
303
+ # Additional visualizations
304
+ st.markdown("### Hourly Capacity Factor Heatmaps")
305
+ for fig_heatmap in heatmaps:
306
+ st.plotly_chart(fig_heatmap, use_container_width=True, height=800)
307
+
308
+ st.markdown("### Additional Analysis")
309
+ st.markdown("The following plots provide additional insights into the renewable energy mix, curtailment, and electricity price variations.")
310
+
311
+ # Plot curtailment over time
312
+ curtailment_df = pd.DataFrame({"Time": fig_energy.data[0].x, "Curtailment (MW)": curtailment_values})
313
+ fig_curtailment = px.line(curtailment_df, x='Time', y='Curtailment (MW)', title='Curtailment Over Time', template='plotly_white')
314
+ st.plotly_chart(fig_curtailment, use_container_width=True, height=800)
315
+
316
+ # Plot electricity price variation over time
317
+ soc_df = pd.DataFrame({"Time": fig_energy.data[0].x, "State of charge [%]": soc_per_hour})
318
+ fig_battery_operation = px.line(soc_df, x='Time', y='State of charge [%]', title='State of charge in battery', template='plotly_white')
319
+ st.plotly_chart(fig_battery_operation, use_container_width=True, height=800)
320
+
321
+ # Plot optimized capacity vs. capacity ranges
322
+ st.plotly_chart(fig_capacity_ranges, use_container_width=True, height=800)
323
+
324
+ # Streamlit UIに感度解析ボタンを追加
325
+ if st.button('Analyze Cost Sensitivity'):
326
+ fig_sensitivity = analyze_cost_sensitivity({
327
+ 'solar': solar_cost,
328
+ 'onshore_wind': onshore_wind_cost,
329
+ 'offshore_wind': offshore_wind_cost,
330
+ 'river': river_cost
331
+ }, ['solar', 'onshore_wind', 'offshore_wind', 'river'], renewable_capacity)
332
+ st.plotly_chart(fig_sensitivity, use_container_width=True, height=800)