-
Notifications
You must be signed in to change notification settings - Fork 14
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
Wp flex changed reinforcement #395
Conversation
This reverts commit 43552cf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @birgits ,
I left a few comments, but in general I think everything is good and this PR can be merged with minor changes. I do not fully understand the enhanced reinforcement so there, I have to trust that everything is correct.
Thanks for these improvements 👍
The costs don't convey the actual costs but are an estimation, as | ||
the real number of parallel lines needed is not determined and the whole feeder | ||
length is used instead of the length over two-thirds of the feeder. | ||
If False, the severity of each feeder's voltage issue is set to be the same. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really the severity, that is set to be the same or rather the weights?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's actually the severity. It is here set to 1. We could also change that to maybe use the maximum voltage deviation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is no specific reason to do so, I would probably change it, so it is consistent with the overloading. Or why would we handle the voltage deviation differently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was set to 1 before and I just left it as it was, but was also wondering about it. I changed it now so that the maximum voltage deviation in the feeder is used.
@@ -661,7 +959,9 @@ def get_most_critical_time_steps( | |||
steps = loading_scores[:num_steps_loading].index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this has not changed but I was wondering whether it might be interesting to know how many timesteps there were to begin with, if you choose to run only a limited number of timesteps. So maybe add an else-statement to the previous if statement with a logger.info(f"{num_steps_loading} of a total {len(loading_scores)} relevant time steps are chosen for the reinforcement evaluation.")? This way, the user can at least see which share of the relevant time steps is evaluated in the end. Same comment for line 975 with a limited number of voltage issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I added it!
if weight_by_costs: | ||
# weight line violations with expansion costs | ||
costs = _costs_per_line_and_transformer(edisgo_obj) | ||
crit_lines_score = crit_lines_score * costs.loc[crit_lines_score.columns] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a thought and not required for this PR, but might be an enhancement. Would it not make sense to apply np.ceil and round to the next integer value (after subtracting 1)? After all it is more an integer decision, how many new lines we need and does not depend on the severity of the overloading in between integer values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. I thought about for a while and I think both the way we do it now and what you are suggesting are not really correct as the relative loading doesn't convey the number of additional lines needed to solve the problem.
E.g. when there are two 1 MW lines and the loading is 3.2 MW, then we would need two more lines of the same type to solve the problem. So in that case subtracting 1 and ceiling would not be correct, because relative loading is 1.6 and subtracting 1 and ceiling would only yield 1 line. But when there is only one 1 MW line and the loading is 3.2 MW, then subtracting 1 and ceiling would yield the right number of lines.
The correct way would probably be to use the absolute overloading and the s_nom of the standard line in the respective voltage level. But I think since this should just be an estimation of the costs I would leave it like it is for now. I will make a ToDo there, so we can maybe change it at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah true, I did not think of parallel lines. Yes I guess it is fine for now and we can think about adapting it some other time.
) | ||
assert len(res_reduced.i_res) == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general in this test, I feel like there are not many things that are being tested against. Is everything covered in other tests or might it be an idea to at least specify the length of the equipment changes or total costs that we would expect with every mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alot more is for the reinforcement tested in the EDisGo class tests. At this point I just wanted to check, whether the usage of two time steps is followed through throughout the reinforcement. Do you still think more tests need to be added or is it okay?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah then it is probably okay. It seems like it is never tested for specific values (e.g. the sum of reinforcement costs in a specific case). Is that on purpose? Would we not want to be able to detect if something changes with the values as well, not just the number of reinforced elements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not on purpose and could be added some time. I would rather test the content of equipment changes then, because the costs function test already tests the derivation of the costs from the equipment changes. I'll add a ToDo for now.
edisgo/flex_opt/reinforce_grid.py
Outdated
@@ -737,6 +766,7 @@ def reinforce(): | |||
"reinforcement." | |||
) | |||
selected_timesteps = converging_timesteps | |||
troubleshooting_mode = troubleshooting_mode_set | |||
reinforce() | |||
|
|||
# Run reinforcement for time steps that did not converge after initial reinforcement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this did not change with this PR and it is a very specific case but I would add a "and not converging_timesteps.empty" in the if-statement above. Otherwise you run the same function twice which is unnecessary. If no timesteps converged, there is no reinforcement and the situation does not change for the other timesteps that do not converge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what you mean here, sorry. The if statement above this line is already if not converging_timesteps.empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean to add the respective statement here:
eDisGo/edisgo/flex_opt/reinforce_grid.py
Line 773 in 70c3264
if not non_converging_timesteps.empty: |
It is just in the case that no timesteps converged, it is unnecessary to run lines 774-780, because the timesteps did not converge before and the grid did not change. So it is certain that the timesteps will not converge again. So instead of "if not non_converging_timesteps.empty:", I would write "if not non_converging_timesteps.empty and not converging_timesteps.empty:"
Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! I changed it now, so that it is only tried to be reinforced in case it was previously reinforced for converged time steps.
setup.py
Outdated
"pandas >= 1.4.0", | ||
# newer pandas versions don't work with specified sqlalchemy versions, but upgrading | ||
# sqlalchemy leads to new errors.. should be fixed at some point | ||
"pandas < 2.2.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this requirement should also be added to the yml files, for all windows users :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I added it.
edisgo/flex_opt/reinforce_grid.py
Outdated
@@ -746,6 +776,7 @@ def reinforce(): | |||
"reinforcement." | |||
) | |||
selected_timesteps = non_converging_timesteps | |||
troubleshooting_mode = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to be honest. I dont get why troubleshooting is turned off in between. But then again, I am also not very familiar with the enhanced_reinforce_grid. I trust this is correct, but dont feel like I understand enough to properly assess this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I turned off troubleshooting mode, as in case power flow still not converges for all time steps, we want to go straight to the iterative grid reinforcement instead of running the power flow with reduced time series until it converges in get_most_critical_time_steps(). However, now that I think of it a bit more, the troubleshooting mode probably never makes sense for the grid reinforcement because it is only used to determine the most critical time steps, but in power flows afterwards in reinforce_grid() it would still results in convergence issues. Or can you think of a case where it might be helpful to have that parameter in the reinforcement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the top of my head, I cannot think of any.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I set the default to False, as it makes more sense. The user can still set it to True if he or she wants to.
Thank you so much @AnyaHe for your valuable comments. I implemented some of your suggestions and also have a few points I would like to discuss further. See comments above :) |
…f grid has beed reinforced in between
…grid reinforcement
Stackoverflow links for some reason now fail when checked with github actions, even though the link is correct. They are therefore for now ignored.
Thanks @birgits for addressing all the comments and the improvements in this PR. From my side, you can merge now. Great work! :) |
Description
This PR mainly changes the implementation of
reduced_analysis
.reduced_analysis
can be used to conduct the grid reinforcement on a reduced number of time steps to avoid running the power flow for all time steps, including ones without grid issues, and thus speed up calculations. As it was implemented so far, thereduced_analysis
could not be used to run the reinforcement for single LV grids or a subset of time steps. The latter is needed to use it in thecatch_convergence_reinforce_grid
function to conduct grid reinforcement for the converged time steps first.The PR also now allows to weight time steps by estimated grid expansion costs analogous to how it was already possible in the selection of the most critical time intervals. This can be useful to further reduce the number of time steps to the most relevant ones.
Further, a fixes small bug in selection of time intervals.
Type of change
Checklist:
pre-commit
hooksNew and adjusted code includes type hinting nowI have made corresponding changes to the documentation