|
12 | 12 | from __future__ import division
|
13 | 13 |
|
14 | 14 | import os
|
| 15 | + |
| 16 | +import pandas as pd |
15 | 17 | from pyomo.environ import *
|
16 | 18 |
|
17 | 19 | dependencies = 'switch_model.timescales', 'switch_model.balancing.load_zones',\
|
@@ -61,7 +63,7 @@ def define_components(mod):
|
61 | 63 | the perspective of the central grid. We currently prohibit injections into
|
62 | 64 | the central grid because it would create a mathematical loophole for
|
63 | 65 | "spilling power" and we currently lack use cases that need this. We cannot
|
64 |
| - use a single unsigned variable for this without introducing errrors in |
| 66 | + use a single unsigned variable for this without introducing errors in |
65 | 67 | calculating Local T&D line losses. WithdrawFromCentralGrid is added to the
|
66 | 68 | load_zone power balance, and has a corresponding expression from the
|
67 | 69 | perspective of the distributed node:
|
@@ -217,3 +219,54 @@ def load_inputs(mod, switch_data, inputs_dir):
|
217 | 219 | filename=os.path.join(inputs_dir, 'load_zones.tab'),
|
218 | 220 | auto_select=True,
|
219 | 221 | param=(mod.existing_local_td, mod.local_td_annual_cost_per_mw))
|
| 222 | + |
| 223 | +def post_solve(instance, outdir): |
| 224 | + """ |
| 225 | + Export results. |
| 226 | +
|
| 227 | + local_td_energy_balance_wide.csv is a wide table of energy balance |
| 228 | + components for every zone and timepoint. Each component registered with |
| 229 | + Distributed_Power_Injections and Distributed_Power_Withdrawals will become |
| 230 | + a column. Values of Distributed_Power_Withdrawals will be multiplied by -1 |
| 231 | + during export. The columns in this file can vary based on which modules |
| 232 | + are included in your model. |
| 233 | + |
| 234 | + local_td_energy_balance.csv is the same data in "tidy" form with a constant |
| 235 | + number of columns. |
| 236 | +
|
| 237 | + """ |
| 238 | + wide_dat = [] |
| 239 | + for z,t in instance.ZONE_TIMEPOINTS: |
| 240 | + record = {"load_zone": z, "timestamp": t} |
| 241 | + for component in instance.Distributed_Power_Injections: |
| 242 | + record[component] = value(getattr(instance, component)[z, t]) |
| 243 | + for component in instance.Distributed_Power_Withdrawals: |
| 244 | + record[component] = value(-1.0 * getattr(instance, component)[z, t]) |
| 245 | + wide_dat.append(record) |
| 246 | + wide_df = pd.DataFrame(wide_dat) |
| 247 | + wide_df.set_index(["load_zone", "timestamp"], inplace=True) |
| 248 | + wide_df.to_csv(os.path.join(outdir, "local_td_energy_balance_wide.csv")) |
| 249 | + |
| 250 | + normalized_dat = [] |
| 251 | + for z,t in instance.ZONE_TIMEPOINTS: |
| 252 | + for component in instance.Distributed_Power_Injections: |
| 253 | + record = { |
| 254 | + "load_zone": z, |
| 255 | + "timestamp": t, |
| 256 | + "component": component, |
| 257 | + "injects_or_withdraws": "injects", |
| 258 | + "value": value(getattr(instance, component)[z, t]) |
| 259 | + } |
| 260 | + normalized_dat.append(record) |
| 261 | + for component in instance.Distributed_Power_Withdrawals: |
| 262 | + record = { |
| 263 | + "load_zone": z, |
| 264 | + "timestamp": t, |
| 265 | + "component": component, |
| 266 | + "injects_or_withdraws": "withdraws", |
| 267 | + "value": value(-1.0 * getattr(instance, component)[z, t]) |
| 268 | + } |
| 269 | + normalized_dat.append(record) |
| 270 | + df = pd.DataFrame(normalized_dat) |
| 271 | + df.set_index(["load_zone", "timestamp", "component"], inplace=True) |
| 272 | + df.to_csv(os.path.join(outdir, "local_td_energy_balance.csv")) |
0 commit comments