Skip to content

Add combined-cycle gas turbine class with default values#206

Open
genevievestarke wants to merge 17 commits intoNatLabRockies:developfrom
genevievestarke:feature/add_ccgt
Open

Add combined-cycle gas turbine class with default values#206
genevievestarke wants to merge 17 commits intoNatLabRockies:developfrom
genevievestarke:feature/add_ccgt

Conversation

@genevievestarke
Copy link
Collaborator

@genevievestarke genevievestarke commented Feb 23, 2026

Add a class for a combined-cycle gas turbine with default operation values.

To-do:

  • Create class
  • Create example
  • Create tests
  • Update documentation
  • Remove Example 08 docs and update Example 07 to include CCGT

@genevievestarke
Copy link
Collaborator Author

Quick question I ran into when implementing an example @paulf81 @misi9170 : Do we want to count start-up time and shut-down time in the time_in_state variable? It currently is included.

In the open cycle gas turbine, it doesn't matter a whole lot, but in the combined cycle, the times are much longer (180 minutes for a cold start), and a minimum up time of 4 hours, which means that the cold start is 3/4 of the minimum up time just to start up. I think the minimum up time should be computed from when the unit starts producing power rather than when it starts it's warm up. Thoughts?

@paulf81
Copy link
Collaborator

paulf81 commented Feb 27, 2026

Quick question I ran into when implementing an example @paulf81 @misi9170 : Do we want to count start-up time and shut-down time in the time_in_state variable? It currently is included.

In the open cycle gas turbine, it doesn't matter a whole lot, but in the combined cycle, the times are much longer (180 minutes for a cold start), and a minimum up time of 4 hours, which means that the cold start is 3/4 of the minimum up time just to start up. I think the minimum up time should be computed from when the unit starts producing power rather than when it starts it's warm up. Thoughts?

Hi @genevievestarke , I think that's how it works now. For example in the cold start state:

        # ====================================================================
        # STATE: COLD_STARTING
        # ====================================================================
        elif self.state == self.STATES.COLD_STARTING:
            # Check if startup should be aborted
            if power_setpoint <= 0:
                self.state = self.STATES.OFF
                self.time_in_state = 0.0
                self.power_output = 0.0
                return 0.0

            # Check if readying time is complete
            if self.time_in_state < self.cold_readying_time:
                return 0.0

            # Ramp up using run_up_rate
            startup_power = (self.time_in_state - self.cold_readying_time) * self.run_up_rate

            # Check if ramping is complete
            if startup_power >= self.P_min:
                self.state = self.STATES.ON
                self.time_in_state = 0.0
                return startup_power

            # Limit to below P_max (edge case)
            startup_power = np.clip(startup_power, 0, self.P_max)

            return startup_power

You can see that when ramping is complete and it transitions to STATES.ON, self.time_in_state is then reset to 0.

@genevievestarke
Copy link
Collaborator Author

Hi @genevievestarke , I think that's how it works now. For example in the cold start state:

Ah, yep, you're right @paulf81 ! I went back a verified that in the example and it all looks to be working.

@misi9170
Copy link
Collaborator

Perhaps an idea is to add the CCGT response to example 07 so that the OCGT and CCGT responses can be compared side by side, rather than have a separate example?

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