-
Notifications
You must be signed in to change notification settings - Fork 439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When generator sets committable=True, buses_t.marginal_price becomes NaN #146
Comments
@loongmxbt thanks for your report. There had been a similar question on the mailing list a while ago https://groups.google.com/forum/#!searchin/pypsa/shadow|sort:date/pypsa/jdeQHeZljMs/5_YUlWypCQAJ Commitable generators make the problem mixed-integer for which shadow prices are generally not well-defined. You could determine approximate shadow prices by fixing the binary unit commitment variables. The link above has an example notebook. import pypsa
nu = pypsa.Network()
nu.set_snapshots(range(4))
nu.add("Bus","bus")
nu.add("Generator","coal",bus="bus",
committable=True,
p_min_pu=0.3,
marginal_cost=20,
min_down_time=2,
start_up_cost=5000,
p_nom=10000)
nu.add("Generator","gas",bus="bus",
committable=True,
marginal_cost=70,
p_min_pu=0.1,
initial_status=0,
shut_down_cost=25,
p_nom=4000)
nu.add("Load","load",bus="bus",p_set=[3000,800,3000,8000]) Now build a pyomo model corresponding to the model = pypsa.opf.network_lopf_build_model(nu, nu.snapshots) Prepare a opt = pypsa.opf.network_lopf_prepare_solver(nu, solver_name="cbc")
opt.solve(model).write() Since it's a MILP cbc does not report back any dual values model.dual.pprint() But the model.generator_status.pprint() and by fixing it, we get an LP problem, which we can solve again: model.generator_status.fix()
nu.results = opt.solve(model)
nu.results.write() Now all dual variables are available: model.dual.pprint() and we can import them back into the pypsa data-structures pypsa.opf.extract_optimisation_results(nu, nu.snapshots)
print(nu.objective)
print(nu.generators_t.status)
print(nu.generators_t.p)
print(nu.buses_t.marginal_price) |
Please close if this answered your questions! |
Thank you very much! Following your code solves the problem, but I still need some time to fully understand. I'll make another comment when I go through this fix. |
I am following the suggested solution but still struggling to make sense of the result. In the toy example below, I was expecting to see the model to dispatch only gas for the first three periods and then dispatch gas + fuel oil in the last period; this because coal -which I set with a generation cost in between- has a constraint on the minimum up time of four periods and so the model should not let the solution run it for one hour only, Instead, I see the model running coal and simply ignoring the unit commitment constraint. Am I doing anything wrong?
results for dispatch: and consequently marginal prices: |
@aleave at the end of snapshots the minimum up-time is only enforced for the remaining snapshots, if the number of remaining snapshots is less than Read https://pypsa.readthedocs.io/en/latest/optimal_power_flow.html#generator-unit-commitment-constraints |
@fneum thanks for your reply. I am still a bit confused on how to solve this in practice, even if I run the simulation for 5 snapshots with a |
Checklist
master
branch or the latest release. Please indicate:pypsa.version
0.16.0
Describe the Bug
Please provide a description of what the bug is and add a minimal example/command for reproducing the bug.
When there is no Generator set committable=True, everything works fine.
Below is result
When I set Generator.committable=True
Below is result
Error Message
If applicable, paste any terminal output to help illustrating your problem.
In some cases it may also be useful to share your list of installed packages:
conda list
.print(network.buses_t.marginal_price)
Is there anything I miss? I'm really new to PyPSA and stuck here for a while.
The text was updated successfully, but these errors were encountered: