Skip to content
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

Turbine node and parameter #144

Merged
merged 15 commits into from
May 12, 2024

Conversation

s-simoncelli
Copy link
Contributor

I moved the implementation of the turbine components in a new branch because both the parameter and node have the same dependencies.

  • The HydropowerTargetParameter is now initialised with a dedicated struct to reduce the number of inputs to new()
  • The TurbineNode accepts target which sets the max_flow using the inverse hydropower equation. Do we want to let the user set the max_flow and min_flow fields if the target is not set? These are private now.
  • I need to add a boolean field to let the user set the target as min_flow instead of max_flow.
  • The TurbineNode::create_metric() function is still a WIP. The derived metric uses TurbineData to get the data it needs to calculate the power. However, because water_elevation (L163) is a DynamicFloatValue, I need to load it as Metric but I don't have access to the schema, domain, tables, etc. Have I implemented it correctly or does the create_metric signature needs to be changed?

@jetuk
Copy link
Member

jetuk commented Mar 13, 2024

I've not thorough read this yet. Is it still draft, or is it ready for review?

I moved the implementation of the turbine components in a new branch because both the parameter and node have the same dependencies.

Great!

The HydropowerTargetParameter is now initialised with a dedicated struct to reduce the number of inputs to new()

Sounds like a good idea.

The TurbineNode accepts target which sets the max_flow using the inverse hydropower equation. Do we want to let the user set the max_flow and min_flow fields if the target is not set? These are private now.

What happens if the user specifies "target" and "max_flow" in the schema? Is this allowed? Does it take the minimum? Same for a "min_flow". I would say these fields should be removed from the schema if they are not used.

I need to add a boolean field to let the user set the target as min_flow instead of max_flow.

Another option would be an enum (I'm not sure about the names):

enum TargetType {
  MaxFlow  // Applies target as a max_flow
  MinFlow  // Applies target as a min_flow
  Fixed  // Applies target as both (like a catchment)
}

The TurbineNode::create_metric() function is still a WIP. The derived metric uses TurbineData to get the data it needs to calculate the power. However, because water_elevation (L163) is a DynamicFloatValue, I need to load it as Metric but I don't have access to the schema, domain, tables, etc. Have I implemented it correctly or does the create_metric signature needs to be changed?

I'll take a look at this. I was expecting some complication here as this is a not quite like anything currently implemented.

@jetuk
Copy link
Member

jetuk commented Mar 21, 2024

@s-simoncelli are you still working on this as a draft or do you want me to review it?

@s-simoncelli
Copy link
Contributor Author

s-simoncelli commented Mar 21, 2024

It’s ready except for the power metric calculation. You can review it :)

@s-simoncelli s-simoncelli marked this pull request as ready for review March 21, 2024 10:40
@jetuk jetuk self-requested a review March 21, 2024 11:11
@jetuk
Copy link
Member

jetuk commented Mar 27, 2024

@s-simoncelli I've had a look at this. I think it is good. In order to solve the issue in the create_metric method I've wanted to refactor a few things first. Most of those are done now (e.g. #148 ). The only other one is simplifying metrics in the schema. I am going to work on that next. Once done we can fix this branch and see if it fits together better.

@s-simoncelli
Copy link
Contributor Author

I merged the new changes from the main branche and I pass now &LoadArgs to the metric functions so that I can use it in the turbuine node.

Copy link
Member

@jetuk jetuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've merged main into here again. It was a bit fiddly but is working.

There's a couple of improvements to make before merge.

It would be nice to have a test model with the turbine node / parameter included to verify some of the values.

energy_unit_conversion: f64,
density: f64,
) -> f64 {
let mut head = water_elevation - turbine_elevation;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simplify this function to just accept head: f64. It's only use already calculates the head value and sets turbine_elevation to zero.

/// Calculate the produced power from the flow using the hydropower equation
pub fn hydropower_calculation(
flow: f64,
water_elevation: f64,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same for this function.

// Bound the flow if required
if let Some(max_flow) = &self.max_flow {
q = q.min(max_flow.get_value(model, state)?);
} else if let Some(min_flow) = &self.min_flow {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

        // Bound the flow if required
        if let Some(max_flow) = &self.max_flow {
            q = q.min(max_flow.get_value(model, state)?);
        } 
        if let Some(min_flow) = &self.min_flow {
            q = q.max(min_flow.get_value(model, state)?);
        }

I think this should be two independent if blocks, not an if-else-if.

@jetuk
Copy link
Member

jetuk commented May 7, 2024

I've applied the changes I suggestion as they were only minor. I'm tempted to merge this now, and fix-up any issues, examples, etc later. @Batch21 do you agree?

@Batch21
Copy link
Contributor

Batch21 commented May 7, 2024

I've applied the changes I suggestion as they were only minor. I'm tempted to merge this now, and fix-up any issues, examples, etc later. @Batch21 do you agree?

yeah, I agree

@jetuk jetuk merged commit 5f50093 into pywr:main May 12, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants