Skip to content

Commit

Permalink
Merge pull request #316 from JuliaGawlick/costbreakdown
Browse files Browse the repository at this point in the history
Additional cost variables to enable break down of costs
  • Loading branch information
thushara2020 committed Jul 13, 2023
2 parents 6368500 + db16afc commit 564888d
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
52 changes: 52 additions & 0 deletions urbs/features/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ def add_storage(m):
m.sto_ep_ratio_tuples,
rule=def_storage_energy_power_ratio_rule,
doc='storage capacity = storage power * storage E2P ratio')
m.def_specific_storage_cost = pyomo.Constraint(
m.sto_tuples,
m.cost_type,
rule=specific_storage_cost,
doc='Break down of costs per storage unit to cost type and stf')

return m

Expand Down Expand Up @@ -297,6 +302,53 @@ def storage_cost(m, cost_type):
m.storage_dict['cost_factor'][s]
for tm in m.tm
for s in m.sto_tuples)


def specific_storage_cost(m, stf, sit, sto, com, cost_type):
"""returns storage costs broke down to the different cost types"""
if cost_type == 'Invest':
cost_spec_storage = (m.cap_sto_p_new[stf, sit, sto, com] *
m.storage_dict['inv-cost-p'][stf, sit, sto, com] *
m.storage_dict['invcost-factor'][stf, sit, sto, com] +
m.cap_sto_c_new[stf, sit, sto, com] *
m.storage_dict['inv-cost-c'][stf, sit, sto, com] *
m.storage_dict['invcost-factor'][stf, sit, sto, com])
if m.mode['int']:
cost_spec_storage -= (m.cap_sto_p_new[stf, sit, sto, com] *
m.storage_dict['inv-cost-p'][stf, sit, sto, com] *
m.storage_dict['overpay-factor'][stf, sit, sto, com] +
m.cap_sto_c_new[stf, sit, sto, com] *
m.storage_dict['inv-cost-c'][stf, sit, sto, com] *
m.storage_dict['overpay-factor'][stf, sit, sto, com])
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
elif cost_type == 'Fixed':
cost_spec_storage = ((m.cap_sto_p[stf, sit, sto, com] * m.storage_dict['fix-cost-p'][stf, sit, sto, com] +
m.cap_sto_c[stf, sit, sto, com] * m.storage_dict['fix-cost-c'][stf, sit, sto, com]) *
m.storage_dict['cost_factor'][stf, sit, sto, com])
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
elif cost_type == 'Variable':
cost_spec_storage = sum(m.e_sto_con[tm, stf, sit, sto, com] * m.weight *
m.storage_dict['var-cost-c'][stf, sit, sto, com] *
m.storage_dict['cost_factor'][stf, sit, sto, com] +
(m.e_sto_in[tm, stf, sit, sto, com] + m.e_sto_out[tm, stf, sit, sto, com]) *
m.weight * m.storage_dict['var-cost-p'][stf, sit, sto, com] *
m.storage_dict['cost_factor'][stf, sit, sto, com]
for tm in m.tm)
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
elif cost_type == 'Fuel':
cost_spec_storage=0
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
elif cost_type == 'Environmental':
cost_spec_storage = 0
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
elif cost_type == 'Revenue':
cost_spec_storage = 0
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
elif cost_type == 'Purchase':
cost_spec_storage = 0
return m.storage_costs[stf, sit, sto, com, cost_type] == cost_spec_storage
else:
raise NotImplementedError("Unknown cost type.")


def op_sto_tuples(sto_tuple, m):
Expand Down
60 changes: 60 additions & 0 deletions urbs/features/transmission.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ def add_transmission(m):
m.tra_tuples,
rule=res_transmission_symmetry_rule,
doc='total transmission capacity must be symmetric in both directions')

m.def_specific_transmission_cost = pyomo.Constraint(
m.tra_tuples,
m.cost_type,
rule=specific_transmission_cost,
doc='main cost function of transmission by cost type by process and stf')

return m

Expand Down Expand Up @@ -232,6 +238,12 @@ def add_transmission_dc(m):
m.tra_tuples_tp,
rule=res_transmission_symmetry_rule,
doc='total transmission capacity must be symmetric in both directions')

m.def_specific_transmission_cost = pyomo.Constraint(
m.tra_tuples,
m.cost_type,
rule=specific_transmission_cost,
doc='main cost function of transmission by cost type by process and stf')

return m

Expand Down Expand Up @@ -388,6 +400,54 @@ def transmission_cost(m, cost_type):
for t in m.tra_tuples)


# transmission cost function broke down to the individual cost types and links
def specific_transmission_cost(m, stf, sit, sit_, tra, com, cost_type):
"""returns transmission costs broke down to the different cost types"""
if cost_type == 'Invest':
cost_spec_transmission = (m.cap_tra_new[stf, sit, sit_, tra, com] *
m.transmission_dict['inv-cost'][stf, sit, sit_, tra, com] *
m.transmission_dict['invcost-factor'][stf, sit, sit_, tra, com])
if m.mode['int']:
cost_spec_transmission -= (m.cap_tra_new[stf, sit, sit_, tra, com] *
m.transmission_dict['inv-cost'][stf, sit, sit_, tra, com] *
m.transmission_dict['overpay-factor'][stf, sit, sit_, tra, com])
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission
elif cost_type == 'Fixed':
cost_spec_transmission = (
m.cap_tra[stf, sit, sit_, tra, com] * m.transmission_dict['fix-cost'][stf, sit, sit_, tra, com] *
m.transmission_dict['cost_factor'][stf, sit, sit_, tra, com])
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission

elif cost_type == 'Variable':
if m.mode['dpf']:
cost_spec_transmission = sum(m.e_tra_in[tm, stf, sit, sit_, tra, com] * m.weight *
m.transmission_dict['var-cost'][stf, sit, sit_, tra, com] *
m.transmission_dict['cost_factor'][stf, sit, sit_, tra, com]
for tm in m.tm) + \
(m.e_tra_abs[tm, stf, sit, sit_, tra, com] * m.weight *
m.transmission_dict['var-cost'][stf, sit, sit_, tra, com] *
m.transmission_dict['cost_factor'][stf, sit, sit_, tra, com]
for tm in m.tm)
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission
else:
cost_spec_transmission = sum(m.e_tra_in[tm, stf, sit, sit_, tra, com] * m.weight *
m.transmission_dict['var-cost'][stf, sit, sit_, tra, com] *
m.transmission_dict['cost_factor'][stf, sit, sit_, tra, com]
for tm in m.tm)
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission
elif cost_type == 'Fuel':
cost_spec_transmission = 0
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission
elif cost_type == 'Environmental':
cost_spec_transmission = 0
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission
elif cost_type == 'Revenue':
cost_spec_transmission = 0
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission
elif cost_type == 'Purchase':
cost_spec_transmission = 0
return m.transmission_costs[stf, sit, sit_, tra, com, cost_type] == cost_spec_transmission

def op_tra_tuples(tra_tuple, m):
""" s.a. op_pro_tuples
"""
Expand Down
76 changes: 76 additions & 0 deletions urbs/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,13 @@ def create_model(data, dt=1, timesteps=None, objective='cost',
m.cost_type,
rule=def_costs_rule,
doc='main cost function by cost type')

# specific cost calculation allows to identify individual contributors to the cost function.
m.def_specific_process_costs = pyomo.Constraint(
m.pro_tuples,
m.cost_type,
rule=def_specific_process_costs_rule,
doc='main cost function of processes by cost type by process and stf')

# objective and global constraints
if m.obj.value == 'cost':
Expand Down Expand Up @@ -823,6 +830,75 @@ def def_costs_rule(m, cost_type):
raise NotImplementedError("Unknown cost type.")


def def_specific_process_costs_rule(m, stf, sit, pro, cost_type):
# Calculate total costs by cost type per process and stf. This allows to easily identify the biggest contributors to the cost functions.

if cost_type == 'Invest':
cost_spec = \
(m.cap_pro_new[stf, sit, pro] *
m.process_dict['inv-cost'][stf, sit, pro] *
m.process_dict['invcost-factor'][stf, sit, pro])

if m.mode['int']:
#import pdb;pdb.set_trace()
cost_spec -= \
(m.cap_pro_new[stf, sit, pro] *
m.process_dict['inv-cost'][stf, sit, pro] *
m.process_dict['overpay-factor'][stf, sit, pro])

return m.process_costs[stf, sit, pro, cost_type] == cost_spec

elif cost_type == 'Fixed':
cost_spec = \
(m.cap_pro[stf, sit, pro] * m.process_dict['fix-cost'][stf, sit, pro] *
m.process_dict['cost_factor'][stf, sit, pro]
)

return m.process_costs[stf, sit, pro, cost_type] == cost_spec

elif cost_type == 'Variable':
cost_spec = \
sum(m.tau_pro[tm, stf, sit, pro] * m.weight *
m.process_dict['var-cost'][stf, sit, pro] *
m.process_dict['cost_factor'][stf, sit, pro]
for tm in m.tm)

return m.process_costs[stf, sit, pro, cost_type] == cost_spec

elif cost_type == 'Fuel':
return m.process_costs[stf, sit, pro, cost_type] == \
sum(
m.e_pro_in[(tm, st, si, pro, co)] * m.weight *
m.commodity_dict['price'][st, si, co, co_type] *
m.commodity_dict['cost_factor'][st, si, co, co_type]
for tm in m.tm for (st, si, co, co_type) in m.com_tuples
if st == stf
if si == sit
if ((stf, sit, pro, co) in m.pro_input_tuples) and co_type == "Stock")

elif cost_type == 'Environmental':
return m.process_costs[stf, sit, pro, cost_type] == \
sum(
m.e_pro_out[(tm, st, si, pro, co)] * m.weight *
m.commodity_dict['price'][st, si, co, co_type] *
m.commodity_dict['cost_factor'][st, si, co, co_type]
for tm in m.tm for (st, si, co, co_type) in m.com_tuples
if st == stf
if si == sit
if ((stf, sit, pro, co) in m.pro_output_tuples) and co_type == "Env")


# Revenue and Purchase costs defined in BuySellPrice.py
elif cost_type == 'Revenue':
return m.process_costs[stf, sit, pro, cost_type] == revenue_costs(m)

elif cost_type == 'Purchase':
return m.process_costs[stf, sit, pro, cost_type] == purchase_costs(m)

else:
raise NotImplementedError("Unknown cost type.")


def cost_rule(m):
return pyomo.summation(m.costs)

Expand Down

0 comments on commit 564888d

Please sign in to comment.