Skip to content

Commit

Permalink
Implementation of Standby Modus of fuel cell and electrolyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristofBernsteiner committed Mar 26, 2024
1 parent cce072f commit 9ab5aea
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 47 deletions.
18 changes: 16 additions & 2 deletions examples/Cell4LifeSzenario2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def Cell4Life(
electrolyzer_config = C4L_electrolyzer.C4LElectrolyzerConfig.get_default_config()
electrolyzer_config.source_weight = input_variablen["electrolyzer_source_weight"]["value"]
electrolyzer_config.p_el = input_variablen["p_el_elektrolyzer"]["value"]

electrolyzer_config.p_el_percentage_standby_electrolyzer = input_variablen["p_el_percentage_standby_electrolyzer"]["value"]
my_electrolyzer = C4L_electrolyzer.C4LElectrolyzer(
my_simulation_parameters=my_simulation_parameters, config=electrolyzer_config
)
Expand All @@ -234,7 +234,7 @@ def Cell4Life(
chp_config = generic_CHP.CHPConfig.get_default_config_fuelcell_p_el_based(fuel_cell_power=input_variablen["fuel_cell_power"]["value"])
chp_config.source_weight = input_variablen["init_source_weight_chp"]["value"]
chp_config.h_fuel = input_variablen["h_fuel"]["value"]

chp_config.p_el_percentage_standby_fuelcell = input_variablen["p_el_percentage_standby_fuelcell"]["value"]

my_chp = generic_CHP.SimpleCHP(
my_simulation_parameters=my_simulation_parameters, config=chp_config,
Expand Down Expand Up @@ -403,6 +403,8 @@ def InputParameter():
fuel_cell_power = FuelCellPowerW #Electricity Power of Fuel Cell Power in Watt
fuel_cell_powerUnit = FuelCellPowerWUnit

p_el_percentage_standby_fuelcell = 10 #If fuel cell is running in standby, it needs so much electricity power in % of its electricitiy production power if it is running
p_el_percentage_standby_fuelcellUnit = "%"

del BatteryCapkWh, FuelCellPowerW, BatteryCapkWhUnit, FuelCellPowerWUnit

Expand Down Expand Up @@ -432,6 +434,9 @@ def InputParameter():

p_el_elektrolyzer = fuel_cell_power*2.1 #Electrical Operating Power in Watt
p_el_elektrolyzerUnit = "W"

p_el_percentage_standby_electrolyzer = 10 #if electrolyzer runs in standby, than it needs "p_el_percentage_standby_electrolyzer" (%) electricity power of the operating power
p_el_percentage_standby_electrolyzerUnit = "%"

electrolyzer_source_weight = 999
electrolyzer_source_weightUnit = "-"
Expand Down Expand Up @@ -713,6 +718,15 @@ def InputParameter():
"unit": Usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_minimum_standby_time_in_percentageUnit,
},

"p_el_percentage_standby_electrolyzer": {
"value": p_el_percentage_standby_electrolyzer,
"unit": p_el_percentage_standby_electrolyzerUnit,
},

"p_el_percentage_standby_fuelcell": {
"value": p_el_percentage_standby_fuelcell,
"unit": p_el_percentage_standby_fuelcellUnit,
},


}
Expand Down
26 changes: 17 additions & 9 deletions hisim/components/C4L_electrolyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ class C4LElectrolyzerConfig(cp.ConfigBase):
name: str
loadtype: loadtypes.LoadTypes
unit: loadtypes.Units
p_el: float #Electricity consumption of Electrolyzer in Watt
p_el: float #Electricity consumption of Electrolyzer if electrolyzer is in operating, in Watt
output_description: str

p_el_percentage_standby_electrolyzer: int #if electrolyzer runs in standby, than it needs "p_el_percentage_standby_electrolyzer" (%) electricity power of the electrolyzer operating power

@staticmethod
def get_default_config() -> "C4LElectrolyzerConfig":
Expand All @@ -69,6 +69,7 @@ def get_default_config() -> "C4LElectrolyzerConfig":
loadtype=loadtypes.LoadTypes.HEATING,
unit=loadtypes.Units.WATT,
output_description = "Electrolyzer E-Consumption",
p_el_percentage_standby_electrolyzer = 0,

)
return config
Expand Down Expand Up @@ -270,13 +271,20 @@ def i_simulate(

else:
"""Simulates the component."""

hydrogen_production = self.config.p_el / (3600*40000) #umrechnung von Watt [=Joule/Sekunde, Leistung) p_el in kg/s H2
stsv.set_output_value(self.hydrogen_output_channel, self.state.state * hydrogen_production)
stsv.set_output_value(self.output_needed_electricity, self.state.state * self.config.p_el)
self.processed_state = self.state.clone() #Neu


#Electrolyzer is running, is turned off, or is in standby:

if self.state.state == 0 or self.state.state == 1:
#Running or turned off
hydrogen_production = self.config.p_el / (3600*40000) #umrechnung von Watt [=Joule/Sekunde, Leistung) p_el in kg/s H2
stsv.set_output_value(self.hydrogen_output_channel, self.state.state * hydrogen_production)
stsv.set_output_value(self.output_needed_electricity, self.state.state * self.config.p_el)
self.processed_state = self.state.clone() #Neu
elif self.state.state == 99: #Standby Electrolyzer
#Running in standby, so electrolyzer is NOT producing hydrogen
hydrogen_production = 0
stsv.set_output_value(self.hydrogen_output_channel, hydrogen_production)
stsv.set_output_value(self.output_needed_electricity, self.config.p_el*self.config.p_el_percentage_standby_electrolyzer/100)
self.processed_state = self.state.clone() #Neu

# write values to state

Expand Down
61 changes: 29 additions & 32 deletions hisim/components/controller_predicitve_C4L_electrolyzer_fuelcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class C4LelectrolyzerfuelcellpredictiveControllerConfig(ConfigBase):
def get_default_config_electrolyzerfuelcell() -> "C4LelectrolyzerfuelcellpredictiveControllerConfig":
"""Returns default configuration for the CHP controller."""
config = C4LelectrolyzerfuelcellpredictiveControllerConfig(
name="Electrolyzer FuelCell Controller", source_weight=1, use=LoadTypes.GAS, h2_soc_upper_threshold_electrolyzer=0,h2_soc_lower_threshold_fuelcell = 0 , on_off_SOEC = 0, off_on_SOEC = 0, p_el_elektrolyzer = 0, fuel_cell_power = 0,minstandbytime_electrolyzer=0, minruntime_electrolyzer = 0,minstandbytime_fuelcell = 0,minruntime_fuelcell = 0,minbatterystateofcharge_electrolyzer_turnon=0, maxbatterystateofcharge_fuelcell_turnon = 0, Electrical_power_surplus_related_to_electrolzyer_percentage = 0, Surplus_electrical_amount_related_to_electrolzyer_in_prediction_horizon_in_percentage = 0, usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_prediction_horizon_in_percentage= 0,minbatterystateofcharge_let_electrolyzer_staysturnedon = 0, maxbatterystateofcharge_let_fuelcell_staysturnedon = 0, Surplus_electrical_amount_related_to_electrolzyer_in_minimum_standby_time_in_percentage = 0, Electrical_power_demand_related_to_fuelcell_percentage = 0, Usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_minimum_standby_time_in_percentage = 0)
name="Electrolyzer FuelCell Controller", source_weight=1, use=LoadTypes.GAS, h2_soc_upper_threshold_electrolyzer=0,h2_soc_lower_threshold_fuelcell = 0 , on_off_SOEC = 0, off_on_SOEC = 0, p_el_elektrolyzer = 0, fuel_cell_power = 0,minstandbytime_electrolyzer=0, minruntime_electrolyzer = 0,minstandbytime_fuelcell = 0,minruntime_fuelcell = 0,minbatterystateofcharge_electrolyzer_turnon=0, maxbatterystateofcharge_fuelcell_turnon = 0, Electrical_power_surplus_related_to_electrolzyer_percentage = 0, Surplus_electrical_amount_related_to_electrolzyer_in_prediction_horizon_in_percentage = 0, Usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_prediction_horizon_in_percentage= 0,minbatterystateofcharge_let_electrolyzer_staysturnedon = 0, maxbatterystateofcharge_let_fuelcell_staysturnedon = 0, Surplus_electrical_amount_related_to_electrolzyer_in_minimum_standby_time_in_percentage = 0, Electrical_power_demand_related_to_fuelcell_percentage = 0, Usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_minimum_standby_time_in_percentage = 0)
return config


Expand Down Expand Up @@ -408,9 +408,9 @@ def turn_off_procedure_electrolyzer(self, timestep, pv_prediction_watt, el_consu

if hydrogen_soc > self.config.h2_soc_upper_threshold_electrolyzer: #Is the hydrogen storage tank already filled above the upper limit?
'''Hydrogen tank is already filled up!'''
self.state.RunElectrolyzer = 0 #electrolyzer is not running"off" because, there is not enough fuel cell in the tank
self.state.RunElectrolyzer = 99 #electrolyzer is not running"off" because, there is not enough fuel cell in the tank
print('Hydrogen tank is already full')
self.state.RunElectrolyzer = 0
self.state.RunElectrolyzer = 99
self.state.deactivation_timestep_electrolyzer = timestep
sys.exit()

Expand All @@ -422,15 +422,15 @@ def turn_off_procedure_electrolyzer(self, timestep, pv_prediction_watt, el_consu


else:
#Elektrolyseur wird abgeschalten
#Elektrolyseur wird in den Standby geschalten
'''
There is NOT enoug useable electricity amount in the prediction horizon, which is min stand by time in this case,
to run the electrolyzer, so turn on if there is not to much hydrogen in the tank
There is NOT enoug useable electricity amount in the prediction horizon/minimum stand by time in this case,
to run the electrolyzer
So turn off Electrolyzer and save deactivation timestep!
So turn Electrolyzer in standby mode and save deactivation timestep!
'''
self.state.deactivation_timestep_electrolyzer = timestep
self.state.RunElectrolyzer = 0
self.state.RunElectrolyzer = 99

else:

Expand Down Expand Up @@ -529,7 +529,7 @@ def turn_on_procedure_electrolyzer(self, timestep, pv_prediction_watt, el_consum

if hydrogen_soc > self.config.h2_soc_upper_threshold_electrolyzer: #Is the hydrogen storage tank already filled above the upper limit?
'''Hydrogen tank is already filled up!'''
self.state.RunElectrolyzer = 0 #electrolyzer is not running"off" because, there is not enough fuel cell in the tank
self.state.RunElectrolyzer = 0 #electrolyzer is not running"off" because, there is enough fuel cell in the tank
print('Hydrogen tank is already full')
self.state.RunElectrolyzer = 0
sys.exit()
Expand All @@ -546,22 +546,22 @@ def turn_on_procedure_electrolyzer(self, timestep, pv_prediction_watt, el_consum

else:
#Elektrolyseur läuft weiterhin auf Standby
self.state.RunElectrolyzer = 0
self.state.RunElectrolyzer = 99


else:
#Elektrolyseur läuft weiterhin auf Standby
self.state.RunElectrolyzer = 0
self.state.RunElectrolyzer = 99


else:
#Elektrolyseur läuft weiterhin auf Standby
self.state.RunElectrolyzer = 0
self.state.RunElectrolyzer = 99


else:
#Elektrolyseur läuft weiterhin auf Standby
self.state.RunElectrolyzer = 0
self.state.RunElectrolyzer = 99

def turn_off_procedure_fuelcell(self, timestep, pv_prediction_watt, el_consumption_pred_onlyhouse_watt, BatteryStateOfCharge, General_PhotovoltaicDelivery, General_ElectricityConsumptiom, hydrogen_soc):
''' Turn off procedure started because Fuel Cell is already running
Expand All @@ -578,7 +578,7 @@ def turn_off_procedure_fuelcell(self, timestep, pv_prediction_watt, el_consumpti
Is the Minimum state of charge of battery already reached to turn off Electrolyzer?
'''
if BatteryStateOfCharge*100 < self.config.maxbatterystateofcharge_let_fuelcell_staysturnedon:
if BatteryStateOfCharge*100 < self.config.maxbatterystateofcharge_let_fuelcell_staysturnedon: # [ ]
'''
Fuel Cell stays turned on because battery state of charge threshold to turn off fuel cell is not reached
'''
Expand Down Expand Up @@ -666,15 +666,15 @@ def turn_off_procedure_fuelcell(self, timestep, pv_prediction_watt, el_consumpti


else:
#Fuel Cell wird abgeschalten
#Fuel Cell wird in Standby geschalten
'''
There is NOT enough electricity demand amount in the minimum standby time of fuel cell,
which means, that the fuel cell will be turned off
Please rember deactivation timestep of fuel cell
'''
self.state.deactivation_timestep_fuelcell = timestep
self.state.RunFuelCell = 0
self.state.RunFuelCell = 99
self.state.mode = 0 #Needs the fuel cell: then the global thermal power is calculated; 0 means that global thermal power fuel cell is NOT calculated, 2 means, that the global thermal power is calculated


Expand Down Expand Up @@ -769,7 +769,7 @@ def turn_on_procedure_fuelcell(self, timestep, pv_prediction_watt, el_consumptio
ratio_inpercentage_useableenergyfromfuelcell = 0
ratio_inpercentage_useableenergyfromfuelcell = total_useable_fuelcell_energy_amount_in_prediction_horizon_wh/total_fuelcell_energy_output_amount_in_prediction_horizon_Wh *100

if ratio_inpercentage_useableenergyfromfuelcell >= self.config.usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_prediction_horizon_in_percentage:
if ratio_inpercentage_useableenergyfromfuelcell >= self.config.Usebale_electrical_amount_of_fuelcell_related_to_fuelcell_output_in_prediction_horizon_in_percentage:
'''There is enough electricity demand amount in the prediction horizon, to run the fuel cell, so turn fuel cell on
Start Fuel Cell and save the timestep when Fuel cell is started!
Expand All @@ -783,26 +783,26 @@ def turn_on_procedure_fuelcell(self, timestep, pv_prediction_watt, el_consumptio

else:
#Fuel Cell läuft weiterhin auf Standby
self.state.RunFuelCell = 0
self.state.RunFuelCell = 99
self.state.mode = 0 #Needs the fuel cell: then the global thermal power is calculated; 0 means that global thermal power fuel cell is NOT calculated, 2 means, that the global thermal power is calculated


else:
#Fuel Cell läuft weiterhin auf Standby
self.state.RunFuelCell = 0
self.state.RunFuelCell = 99
self.state.mode = 0 #Needs the fuel cell: then the global thermal power is calculated; 0 means that global thermal power fuel cell is NOT calculated, 2 means, that the global thermal power is calculated


else:
#Fuel Cell läuft weiterhin auf Standby
self.state.RunFuelCell = 0
self.state.RunFuelCell = 99
self.state.mode = 0 #Needs the fuel cell: then the global thermal power is calculated; 0 means that global thermal power fuel cell is NOT calculated, 2 means, that the global thermal power is calculated



else:
#Fuel Cell läuft weiterhin auf Standby
self.state.RunFuelCell = 0
self.state.RunFuelCell = 99
self.state.mode = 0 #Needs the fuel cell: then the global thermal power is calculated; 0 means that global thermal power fuel cell is NOT calculated, 2 means, that the global thermal power is calculated


Expand Down Expand Up @@ -861,10 +861,9 @@ def i_simulate(
#electrolyzer_or_fuelcell_mode = False --> Electrolyzer Season
#electrolyzer_or_fuelcell_mode = True --> Fuel Cell Season

prediction_timesteps = [6]

if electrolyzer_or_fuelcell_mode == False: #ELECTROLYZER SEASON!!!
self.state.RunFuelCell = 0
self.state.RunFuelCell = 0 #Fuel Cell is completely turned off


if self.state.RunElectrolyzer == 1:
Expand All @@ -875,7 +874,7 @@ def i_simulate(



elif self.state.RunElectrolyzer == 0:
elif self.state.RunElectrolyzer == 0 or self.state.RunElectrolyzer == 99:
##Turn On Procedure
'''
The following turn_off_procedure function manipulates the
Expand All @@ -893,28 +892,26 @@ def i_simulate(

else:
#FUEL CELL SEASON!!!
self.state.RunElectrolyzer = 0 #electrolyzer is not running"off" because, it is not the season, where the electrolyzer is allowed to run or there is not enough fuel cell in the tank
self.state.RunElectrolyzer = 0 # Electrolyzer is completely turned off which means, it is NOT running in standby
'''
Predictive Controll Fuel Cell:
# [ ] Fuel Cell --> implementation of prediciton is not done until now
# [x] Fuel Cell --> implementation of prediciton is not done until now
'''
#Forecast needed
if hydrogen_soc > self.config.h2_soc_lower_threshold_fuelcell:

if self.state.RunFuelCell == 1:
self.turn_off_procedure_electrolyzer(timestep, pv_prediction_watt, el_consumption_pred_onlyhouse_watt, BatteryStateOfCharge, General_PhotovoltaicDelivery, General_ElectricityConsumptiom, hydrogen_soc)
self.state.RunFuelCell = 1 #turn on
self.state.mode = 2 #Needs the fuel cell: then the global thermal power is calculated
stsv.set_output_value(self.chp_heatingmode_signal_channel, self.state.mode)
elif self.state.RunFuellCell == 0:
self.turn_on_procedure_fuelcell(self, timestep, pv_prediction_watt, el_consumption_pred_onlyhouse_watt, BatteryStateOfCharge, General_PhotovoltaicDelivery, General_ElectricityConsumptiom, hydrogen_soc):

elif self.state.RunFuelCell == 0 or self.state.RunFuelCell == 99:
self.turn_on_procedure_fuelcell(timestep, pv_prediction_watt, el_consumption_pred_onlyhouse_watt, BatteryStateOfCharge, General_PhotovoltaicDelivery, General_ElectricityConsumptiom, hydrogen_soc)




else:
#There is not enough Hydrogen available in storage
self.state.RunFuelCell = 0
self.state.RunFuelCell = 0 #Fuel Cell wird abgeschalten!
self.state.mode = 0 #Needs the fuel cell: then the global thermal power is calculated


Expand Down
Loading

0 comments on commit 9ab5aea

Please sign in to comment.