Hey Marissa,
1. You are right, this might seem counter-intuitive. The line expansion is solved in an iterative process where `s_nom` (capacity) and `x_pu` (impedance) are updated in each iteration. In case we were only updating the impedance (which carries the necessary information), we would end up with a wrong s_nom/x_pu ratio. This is why we are updating both.
2. The information that you are looking for is in s_nom_min which is the 'starting point' of the transmission capacities. You also have the option to track the iteration by setting `track_iterations` to True in config.yaml -> solving -> options. This will store the s_nom of each iteration under n.lines.s_nom_opt_{#itertation}. The starting point is stored under n.lines.s_nom_opt_0 (which should be the same as n.lines.s_nom_min).
3. Good point. This also comes from the iterative process.
Probably it would be helpful to store `objective_constant` for
each iteration if `track_iterations` is True (you can raise a
pypsa issue on that if you want :) ). For now you can manually
reconstruct the objective constant by summing over the nominal
attribute for all components except for lines where you take the
lower bound something like this
nom_attr = pypsa.descriptors.nominal_attrs.items()
constant = 0Hope that helped!
Best,
Fabian H
--
You received this message because you are subscribed to the Google Groups "pypsa" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pypsa+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/pypsa/e8726cd9-1f2b-4b38-9c5b-a1f2a2d19474o%40googlegroups.com.
nom_attr = pypsa.descriptors.nominal_attrs.items()constant = []
for c, attr in nom_attr:
if c in n.passive_branch_components:attr += '_min'
constant_int = (n.df(c)[attr] @ n.df(c).capital_cost)constant.append(constant_int)constant2 = []
for c, attr in nom_attr:
attr += '_opt'constant_opt = (n.df(c)[attr] @ n.df(c).capital_cost)constant2.append(constant_opt)Objective = 0Objective += (sum(constant2)-sum(constant))Gen_opex = sum(n.generators_t.p.sum()*n.generators.marginal_cost)Storage_opex = sum((n.storage_units_t.p_dispatch).sum()*n.storage_units.marginal_cost)
Objective += (Gen_opex + Storage_opex)
print("Total system cost:",(Objective)/1e9, "billion euros")print("n.objective output:", n.objective/1e9, "billion euros")print("Difference between self calculated objective & objective function output:", (Objective-n.objective)/1e9, "billion euros")lines_costs=(n.lines.s_nom_opt*n.lines.capital_cost).sum()-(n.lines.s_nom_min*n.lines.capital_cost).sum()print("Additional line costs:", lines_costs/1e9, "billion euros")
Total system cost: 46.70154794014095 billion euros n.objective output: 45.27161382643129 billion euros Difference between self calculated objective & objective function output: 1.4299341137096557 billion euros Additional line costs: 1.4299340498999469 billion euros
Hey Marissa,
you're welcome :) The difference you mention is not due to a
wrong calculation but rather to an 'inaccuracy' of the solver.
It's of order 10^-6 which is the default solver tolerance, see
config.yaml -> solver -> FeasibilityTol & BarConvTol. If
you want higher accuracy you should tweak these tolerances (not
sure which one of those exactly), or switch to crossover > 0
(which takes a long time however to solve).
Best,
Fabian
--
You received this message because you are subscribed to the Google Groups "pypsa" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pypsa+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/pypsa/601f0aa8-e902-437e-954d-aa2361772269o%40googlegroups.com.