Repository navigation
Conversation
|
The bound this PR gives an extendable asset with no bound of its own is the right answer measured from the Lagrangian side as well, and there is one sentinel left that What the sentinels do to the Lagrangian dual. The four sector-coupled TSSB instances of The cause is the cap, and it reaches the master through the subgradients. In the Lagrangian relaxation of the non-anticipativity rows, the design of a converter that the multiplier makes profitable goes straight to its bound, so the residual of the relaxed row carries the bound itself: 262 of the 311 linearizations of that solve have an infinity norm of exactly Two counter-proofs, on the same tree and with the master configured exactly as it was when it failed:
The sentinel that is left. |
Well, this assumption should be wrong... We are helping the solution but some optima issues could arise with physical |
|
@dmeoli Could you test PyPSA–SMS++ for the new For example, with 50 MW modules, Also, since |
Done in 1f76a36, The second test reads back from the netCDF file, with no SMS++, what the conversion writes: The test found a defect in UCBlock and not in the conversion:
This is the fourth test: the InvestmentBlock form of the same modular network writes a continuous capacity in [70, 180] at 800 €/MW, and its optimum is compared with the continuous PyPSA model (the second row of the table). The test uses the default configuration, i.e., the one of the released SMS++; the values above come from a build of the BundleSolver 2.0 with |
You are right, and it is not only a risk: the physical bound cuts the optimum of one of the test networks. The sentence in the docstring and in the description, that no asset can be used beyond what the demand absorbs, confuses the capacity of an asset with what it produces: a generator produces its capacity times I solved with PyPSA every test network with an extendable asset twice, once with no bound ( On No bound taken from the demand alone can be proved not to cut, and the one that can, i.e., What I propose is to check the bound after solving, instead of trusting it: the generators solve every instance with PyPSA anyway to write its reference, so an asset whose design ends at its bound gets the bound doubled and the instance is solved again, until no design is at its bound. For a linear network this is exact, since a bound that is not active at the optimum of a convex problem has a zero multiplier and does not cut it; for a network with committable units it is the same check, not a proof. The docstring and the description then say what the bound actually is, a starting point verified on the solution. If you agree, I will push it here and regenerate the instances whose bound was active. |
|
| # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
| # - - - - - - - - - - - - - - - - - BSCfg.txt - - - - - - - - - - - - - - - - | ||
| # | ||
| # A txt description of a BlockSolverConfig for the inner UCBlock-style block | ||
| # of an InvestmentBlock, to be solved by a :MILPSolver as the LP relaxation |
There was a problem hiding this comment.
Done in d310a94: the configurations are no longer in pypsa2smspp. Those of the BundleSolver 2.0 for an InvestmentBlock are in config/smspp/InvestmentBlock-BS2 of SPSUnipi/pypsa-eur-instances#16, together with the generators that use them, and the tool templates in SPSUnipi/pySMSpp#116. The PR now carries only the conversion of the modular assets and the bounds of the extendable ones (see the description).
d310a94 to
4659ebf
Compare
davide-f
left a comment
There was a problem hiding this comment.
Well, this assumption should be wrong... We are helping the solution but some optima issues could arise with physical
You are right, and it is not only a risk: the physical bound cuts the optimum of one of the test networks. The sentence in the docstring and in the description, that no asset can be used beyond what the demand absorbs, confuses the capacity of an asset with what it produces: a generator produces its capacity times
p_max_pu, so an intermittent one needs more than the peak of the load just to cover it, and more again when a storage unit takes what it produces in excess.
I solved with PyPSA every test network with an extendable asset twice, once with no bound (mode="none") and once with the physical one, and looked for the assets whose unbounded optimum lies beyond the bound:network unbounded physical asset at the bound 3n_3c_2gext_1lext_1mlext 4.862560e+06 1.090674e+07 wind: 47674 MW against 37336 MW 2n_1c_1gext_1bext_2lext 2.991550e+10 2.991550e+10 H2 Fuel Cell at the bound, same objective the other 9 same same noneOn
3n_3c_2gext_1lext_1mlextthe largestp_max_puof the wind generator is 0.541, so it needs 1.85 times the peak to cover it alone, and the optimum builds 2.5 times the peak because the batteries store the excess. The load of the test networks is drawn at random, so the numbers change from one run to the next, but the bound was active on all 3 draws I tried. The instances of the batches show the same: when the physical bound replaced the 1e7 caps, the reference ofsmspp_3n_3c_2gext_1lext_1mlextwent from 4.682891301e+06 to 1.495190064e+07, i.e., the reference is now the optimum of a network that has been cut. SMS++ and PyPSA still solve the same network there, so the comparison is sound, but it is not the network that was written.
No bound taken from the demand alone can be proved not to cut, and the one that can, i.e.,capital_cost * p_nom_maxat most the cost of a feasible point, is useless here: with the slack units that cost reaches 7e11, and the bounds that come out (1e9 to 1e10 MW) are the same caps that broke the master.
What I propose is to check the bound after solving, instead of trusting it: the generators solve every instance with PyPSA anyway to write its reference, so an asset whose design ends at its bound gets the bound doubled and the instance is solved again, until no design is at its bound. For a linear network this is exact, since a bound that is not active at the optimum of a convex problem has a zero multiplier and does not cut it; for a network with committable units it is the same check, not a proof. The docstring and the description then say what the bound actually is, a starting point verified on the solution. If you agree, I will push it here and regenerate the instances whose bound was active.
An initial comment: @dmeoli / @AlessandroPampado99 let's keep the description always coincise and readable by a human. Details can be added later but it is very hard to review the PRs otherwise.
If I understand correctly, here are are exploring the inclusion of bounds to investment capacities.
Preliminary question: without bounds the lagrangian cannot work? I guess so, I'm asking for confirmation
The heuristic must be light. For sure, initial pypsa optimizations to calibrate the bounds are a no-go.
I'd definitely prefer a heuristic like "1e8/1e9" and add a warning in such cases. We can have other heuristics, but they must be very light both in terms of methodology and code to be maintainable and understandable.
|
Short answers, and I am dropping the calibration runs. Does the Lagrangian need a bound? No. What hurts is not the missing bound, it is a bound written as a big finite number, because the design of an asset the multiplier makes attractive goes straight to it and the bound lands in the subgradient: on So Worth adding that the BundleSolver 2.0 this PR targets scales the rows of the master by default and scales the cuts inside each hard component, which is the cure for rows that differ by orders of magnitude, so a large sentinel is much less dangerous there than it was on the 1.0. That makes the choice a matter of what is simple rather than of what survives. Description shortened. |
|
I like the proposal: do not write the max where pypsa does not specify it. |
…ber of its modules, tested as an xlsx case of the sweep
4659ebf to
a6e9c4f
Compare
|
Already supported, and now that is all the PR does about bounds: Dropped in a6e9c4f: |
|
@dmeoli have you added support for modular capacity expansion in InvestmentBlock? |
|
docs/readthedocs.org:pypsa2smspp — Read the Docs build failed! |
|
@davide-f yes, in both forms (this comment is edited: at first the InvestmentBlock form relaxed the modules). With In the InvestmentBlock form the design of such an asset is now the number of its modules as well: the InvestmentBlock reads a netCDF variable @AlessandroPampado99 the Read the Docs failure is not in the docs: the build of 24/09 started while the branch was being rewritten and stopped on |
|
@AlessandroPampado99 the Read the Docs failure is not in the docs: the build of 24/09 started while the branch was being rewritten and stopped on fatal: reference is not a tree: a6e9c4f. I am restarting it. @dmeoli If it's ok I'll merge it :) |
…teger design too, the number of its modules, and solves it with the BundleSolver of InvestmentBlock/BSPar-int.txt
…AC network into a transport model without Kirchhoff's voltage law
… no capital cost, was fixed at a large capacity before the merge, accepts a preset or a list of presets, and the merged links are read back also per scenario
0b16823 to
a64a002
Compare
…ltage law since the lines have their susceptance, is left out where the solver is a released SMS++, whose DCNetworkBlock finds it infeasible
…e scenarios are in the InnerSolution of the InvestmentBlock, and its design goes to every scenario of the asset; tested against PyPSA on a TSSB and an MSSB
The BundleSolver 2.0 it is written for is now in the develop of SMS++ (#59, on which it was stacked, is merged).
A modular extendable asset. An asset with
p_nom_mod > 0is built by PyPSA in an integer number of modules, and the UCBlock form now writes the design of such an IntermittentUnitBlock as that number, reading the capacity back as the number of modules times their size; the InvestmentBlock form does the same, with the cost and the bounds of the design per module and the asset markedInteger, and the BundleSolver ofInvestmentBlock/BSPar-int.txtkeeping its design integer. It needs UCBlock87edf11f, and for the InvestmentBlock form InvestmentBlocke43b146, BundleSolvere1c624fand SMS++8f41958. The case ismod_1n_2c_2g, whose continuous optimum builds 2.36 modules and whose modular one builds 3, so that rounding would give the wrong answer.The susceptance of the lines. The lines were written with
LineSusceptance0, i.e., as a transport model without Kirchhoff's voltage law, which went unnoticed on networks without cycles of AC lines: on the 20-node networks of power-IT-noUC (30 lines, 12 cycles) SMS++ was 0.08% below PyPSA. They now get1/x_pu_eff(and 0 where the reactance is 0, i.e., a DC line), and SMS++ gives the value of PyPSA to about 1e-5.The batteries of PyPSA-Eur.
merge_linksnever merged their charger and discharger: the discharger has no capital cost, and the extendable assets without a capital cost are fixed at a large capacity before the merge, which only merges an extendable pair. The links that the merge absorbs are now left extendable;merge_linksalso accepts a preset or a list of presets, as its docstring says, and the merged links are read back also in the stochastic case. @AlessandroPampado99, the merged link hasp_min_pu = -efficiencyof the discharger, so that it discharges at mostefficiency * p_nomon the electric side, while the constraint of PyPSA-Eur (p_nomof the charger =efficiency * p_nomof the discharger) lets it dischargep_nomthere: is the factor intended? On power-IT-noUC the battery constraint is not binding, so the values are the same either way.The bounds of the extendable assets. Gone from this PR, as agreed below: an asset PyPSA gives no
p_nom_maxkeeps an infiniteMaxCapacityDesign, which the conversion already writes, and the vector carries a finite entry only where PyPSA has one.The templates of the tools for the BundleSolver 2.0 are in SPSUnipi/pySMSpp#116, and the generators of the SMS++ instances in SPSUnipi/pypsa-eur-instances#16.