Variable Marginal Cost for Unit Commitment

122 views
Skip to first unread message

SALMAN TARIQ

unread,
Mar 27, 2023, 2:51:17 AM3/27/23
to pypsa
Dear Fabian,

I am using Pypsa for generation scheduling purpose. In literature, for Unit Commitment or Generation Scheduling, the marginal costs of generators are defined as a function of output power. But in Pypsa we have constant marginal cost. Thus verification of scheduling results become very difficult. Can you please modify the code to incorporate the quadratic cost function for generators?

Thank you

Salman Tariq
University of Malaya

Fabian Neumann

unread,
Mar 27, 2023, 2:53:33 AM3/27/23
to pypsa
Hi Salman,

PyPSA currently does not support marginal cost terms as a function of power output. You're right.

We would welcome a pull request if you want to tackle this issue but don't have the resources to implement it for you.

Best wishes,

Fabian N

최지웅

unread,
Mar 30, 2023, 12:24:02 AM3/30/23
to pypsa
Hi everyone,

I am using pypsa to optimize power system operation.

I added the "PowExpression()" function provided by Pyomo to the objective function to apply the generator's cost function as a quadratic formula.
```
for sn, marginal_cost in zip(snapshots, marginal_cost_it):
gen_mc, gen_a, gen_b, gen_c, su_mc, st_mc, link_mc = marginal_cost

weight = network.snapshot_weightings.objective[sn]
## Original generator cost
'''for gen in network.generators.index:
coefficient = gen_mc.at[gen] * weight
objective.variables.extend([(coefficient, model.generator_p[gen, sn])])'''

# apply quadratic cost
for gen in network.generators.index:
coefficient = (gen_a.at[gen]) * weight
a = PowExpression([model.generator_p[gen, sn], 2])
print(a)
objective.variables.extend([(coefficient, a)])
for gen in network.generators.index:
coefficient = (gen_b.at[gen]) * weight
objective.variables.extend([(coefficient, model.generator_p[gen, sn])])
```

It was confirmed that the quadratic equation was applied to the objective function as follows.
```
... + 0.0*generator_p[G0,2022-10-25 18:30:00]**2 + 0.0*generator_p[G1,2022-10-25 18:30:00]**2 + 0.0*generator_p[G2,2022-10-25 18:30:00]**2 + 0.0*generator_p[G3,2022-10-25 18:30:00]**2 + 0.0*generator_p[G4,2022-10-25 18:30:00]**2 + 0.394*generator_p[G9,2022-10-25 18:30:00]**2 + 0.394*generator_p[G10,2022-10-25 18:30:00]**2 + ...
```
However, the following error occurred.
```
INFO:pypsa.opf:Solving model using gurobi
Traceback (most recent call last):
  File "C:/Users/aaa/Desktop/2023 춘계학술대회/code/test_V10.0/jeju_curtail_main.py", line 16, in <module>
    uc.opf('net/' + str(i), i)  # pypsa network  path folder
  File "C:\Users\aaa\Desktop\2023 춘계학술대회\code\test_V10.0\uc.py", line 102, in opf
    pyomo=True,
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pypsa\components.py", line 768, in lopf
    return network_lopf(self, **args)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pypsa\opf.py", line 2471, in network_lopf
    extra_postprocessing=extra_postprocessing,
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pypsa\opf.py", line 2330, in network_lopf_solve
    options=solver_options
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\opt\base\solvers.py", line 570, in solve
    self._presolve(*args, **kwds)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\solvers\plugins\solvers\GUROBI.py", line 234, in _presolve
    ILMLicensedSystemCallSolver._presolve(self, *args, **kwds)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\opt\solver\shellcmd.py", line 209, in _presolve
    OptSolver._presolve(self, *args, **kwds)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\opt\base\solvers.py", line 670, in _presolve
    **kwds)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\opt\base\solvers.py", line 722, in _convert_problem
    **kwds)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\opt\base\convert.py", line 101, in convert_problem
    problem_files, symbol_map = converter.apply(*tmp, **tmpkw)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\solvers\plugins\converter\model.py", line 82, in apply
    io_options=io_options)
  File "C:\Users\aaa\anaconda3\envs\py3.7\lib\site-packages\pyomo\core\base\block.py", line 1979, in write
    io_options)
  File "pyomo\repn\plugins\cpxlp.pyx", line 158, in pyomo.repn.plugins.cpxlp.ProblemWriter_cpxlp.__call__
  File "pyomo\repn\plugins\cpxlp.pyx", line 159, in pyomo.repn.plugins.cpxlp.ProblemWriter_cpxlp.__call__
  File "pyomo\repn\plugins\cpxlp.pyx", line 160, in pyomo.repn.plugins.cpxlp.ProblemWriter_cpxlp.__call__
  File "pyomo\repn\plugins\cpxlp.pyx", line 514, in pyomo.repn.plugins.cpxlp.ProblemWriter_cpxlp._print_model_LP
  File "pyomo\repn\standard_repn.pyx", line 289, in pyomo.repn.standard_repn.generate_standard_repn
AttributeError: 'PowExpression' object has no attribute 'fixed'
```

I think neither pypsa nor pyomo support quadratic expressions.

is there a solution to apply the quadratic equation to the objective function?

2023년 3월 27일 월요일 오후 3시 53분 33초 UTC+9에 fn...@mail.tu-berlin.de님이 작성:
Message has been deleted

SALMAN TARIQ

unread,
Apr 4, 2023, 5:54:13 AM4/4/23
to pypsa
Hi everyone,

Instead of changing the source code of PyPSA, I used the trick to modify objective function (before solution). In "lopf()" I defined extra
_functionality function. Then I modified objective function by introducing penalty terms as follows.
model.penalty = pyo.Expression(expr=0.100 * model.generator_p[("Gen 1", sn)] + 10.00)
model.objective = pyo.Objective(expr=model.objective + model.penalty1)

BTW I am using "Linear marginal cost" instead of quadratic production cost. This method works fine

SALMAN TARIQ

unread,
May 27, 2024, 11:40:29 PMMay 27
to SALMAN TARIQ, pypsa
Dear Fabian,
I am planning to perform stochastic generation Scheduling through Pypsa, in which I have to define scenarios above snapshots. I will edit my offline Pypsa repository (cloned for development purposes). 
Can you please guide me where should I define the scenarios, so that they can be accessible to components (e.g. generators and storages) like snapshots?
I mean I want to add the layer of scenarios over snapshots where each scenario will have all snapshots.

Best Regards
Salman Tariq 

--
You received this message because you are subscribed to a topic in the Google Groups "pypsa" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pypsa/M3VR3svMRSw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pypsa+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/pypsa/e195bcbe-4495-44a2-9f91-84c9483ff7c2n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages