|
| 1 | +"""Example 09: Multiunit Thermal Plant |
| 2 | +
|
| 3 | +This example demonstrates a thermal power plant constructed from two 50 MW OCGT units. |
| 4 | +The power setpoints are split unequally between the two units to demonstrate the ability of the |
| 5 | +model to specify setpoints of individual units. |
| 6 | +""" |
| 7 | + |
| 8 | +from hercules.hercules_model import HerculesModel |
| 9 | +from hercules.utilities_examples import prepare_output_directory |
| 10 | + |
| 11 | +prepare_output_directory() |
| 12 | + |
| 13 | + |
| 14 | +# Declare the open loop control setpoint sequence used for demonstration. |
| 15 | +class OpenLoopController: |
| 16 | + """Controller implementing the unit power setpoints in open loop.""" |
| 17 | + |
| 18 | + def __init__(self, h_dict): |
| 19 | + # Access total rated capacity from h_dict, as well as capacities of individual units |
| 20 | + self.rated_capacity = h_dict["thermal_power_plant"]["rated_capacity"] |
| 21 | + self.unit_1_capacity = h_dict["thermal_power_plant"]["OCGT1"]["rated_capacity"] |
| 22 | + self.unit_2_capacity = h_dict["thermal_power_plant"]["OCGT2"]["rated_capacity"] |
| 23 | + self.unit_3_capacity = h_dict["thermal_power_plant"]["OCGT3"]["rated_capacity"] |
| 24 | + |
| 25 | + def step(self, h_dict): |
| 26 | + current_time = h_dict["time"] |
| 27 | + |
| 28 | + # Determine power setpoint based on time |
| 29 | + if current_time < 10 * 60: # 10 minutes in seconds |
| 30 | + # Before 10 minutes: run all three units at full capacity |
| 31 | + self.power_setpoint_1 = self.unit_1_capacity |
| 32 | + self.power_setpoint_2 = self.unit_2_capacity |
| 33 | + self.power_setpoint_3 = self.unit_3_capacity |
| 34 | + elif current_time < 20 * 60: # 20 minutes in seconds |
| 35 | + # Between 10 and 20 minutes: shut down unit 1, leave units 2 & 3 |
| 36 | + self.power_setpoint_1 = 0.0 |
| 37 | + elif current_time < 40 * 60: # 40 minutes in seconds |
| 38 | + # Shut down units 2 & 3 |
| 39 | + self.power_setpoint_2 = 0.0 |
| 40 | + self.power_setpoint_3 = 0.0 |
| 41 | + elif current_time < 120 * 60: # 120 minutes in seconds |
| 42 | + # Between 40 and 120 minutes: signal to run at full capacity |
| 43 | + self.power_setpoint_1 = self.unit_1_capacity |
| 44 | + self.power_setpoint_2 = self.unit_2_capacity |
| 45 | + self.power_setpoint_3 = self.unit_3_capacity |
| 46 | + elif current_time < 180 * 60: # 180 minutes in seconds |
| 47 | + # Between 120 and 180 minutes: reduce power of unit 1 to 50% of rated capacity |
| 48 | + self.power_setpoint_1 = 0.5 * self.unit_1_capacity |
| 49 | + elif current_time < 210 * 60: # 210 minutes in seconds |
| 50 | + # Between 180 and 210 minutes: reduce power of unit 1 to 10% of rated capacity |
| 51 | + self.power_setpoint_1 = 0.1 * self.unit_1_capacity |
| 52 | + elif current_time < 240 * 60: # 240 minutes in seconds |
| 53 | + # Between 210 and 240 minutes: move both units to 50% of rated capacity |
| 54 | + self.power_setpoint_1 = 0.5 * self.unit_1_capacity |
| 55 | + self.power_setpoint_2 = 0.5 * self.unit_2_capacity |
| 56 | + self.power_setpoint_3 = 0.5 * self.unit_3_capacity |
| 57 | + else: |
| 58 | + # After 240 minutes: shut down |
| 59 | + self.power_setpoint_1 = 0.0 |
| 60 | + self.power_setpoint_2 = 0.0 |
| 61 | + self.power_setpoint_3 = 0.0 |
| 62 | + |
| 63 | + # Update the h_dict with the power setpoints for each unit and return |
| 64 | + h_dict["thermal_power_plant"]["power_setpoints"] = [ |
| 65 | + self.power_setpoint_1, |
| 66 | + self.power_setpoint_2, |
| 67 | + self.power_setpoint_3, |
| 68 | + ] |
| 69 | + |
| 70 | + return h_dict |
| 71 | + |
| 72 | + |
| 73 | +# Runscript |
| 74 | +if __name__ == "__main__": |
| 75 | + # Initialize the Hercules model |
| 76 | + hmodel = HerculesModel("hercules_input.yaml") |
| 77 | + |
| 78 | + # Instantiate the controller and assign to the Hercules model |
| 79 | + hmodel.assign_controller(OpenLoopController(hmodel.h_dict)) |
| 80 | + |
| 81 | + # Run the simulation |
| 82 | + hmodel.run() |
| 83 | + |
| 84 | + hmodel.logger.info("Process completed successfully") |
0 commit comments