23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 | def parameter_bounds_for_calibration(type_fuel_cell, voltage_zone, operating_inputs_1, operating_inputs_2):
"""This function is used to determine the parameter bounds of the fuel cell model for the calibration when a
registered type_fuel_cell is considered.
Parameters
----------
type_fuel_cell : str
Type of fuel cell configuration.
voltage_zone : str
Zone of calibration: "before_voltage_drop", "full".
operating_inputs_1 : dict
Operating inputs for the first fuel cell configuration.
operating_inputs_2 : dict
Operating inputs for the second fuel cell configuration.
Returns
-------
varbound : list
List of the bounds on the parameters to calibrate. Each element is a list containing the minimum and
maximum values of the parameter, and the type of the parameter ('real' or 'int').
gene_space : list
List of dictionaries used to define the bounds of the undetermined parameters for pygad. Each
dictionary contains the 'low' and 'high' values for the parameter, and optionally a 'step' value for
integer parameters.
"""
Pc_des_1, Pc_des_2 = operating_inputs_1['Pc_des'], operating_inputs_2['Pc_des']
if type_fuel_cell == "ZSW-GenStack" or type_fuel_cell == "ZSW-GenStack_Pa_1.61_Pc_1.41" or \
type_fuel_cell == "ZSW-GenStack_Pa_2.01_Pc_1.81" or type_fuel_cell == "ZSW-GenStack_Pa_2.4_Pc_2.2" or \
type_fuel_cell == "ZSW-GenStack_Pa_2.8_Pc_2.6" or type_fuel_cell == "ZSW-GenStack_T_62" or \
type_fuel_cell == "ZSW-GenStack_T_76" or type_fuel_cell == "ZSW-GenStack_T_84":
# Fuel cell physical parameters
Hacl_min, Hacl_max = 6e-6, 10e-6 # m. It is the thickness of the ACL.
Hccl_min, Hccl_max = 10e-6, 20e-6 # m. It is the thickness of the CCL.
Hmem_min, Hmem_max = 10e-6, 20e-6 # m. It is the thickness of the membrane.
epsilon_gdl_min, epsilon_gdl_max = 0.696, 0.880 # It is the anode/cathode GDL porosity, without units.
epsilon_mpl_min, epsilon_mpl_max = 0.32, 0.54 # It is the anode/cathode MPL porosity, without units.
epsilon_cl_min, epsilon_cl_max = 0.40, 0.60 # It is the anode/cathode MPL porosity, without units.
epsilon_mc_min, epsilon_mc_max = 0.15, 0.40 # It is the volume fraction of ionomer in the CL.
# Constants based on the interaction between water and the structure
e_min, e_max = 3, 5 # It is the capillary exponent, and should be an int number.
# Voltage polarization
Re_min, Re_max = 5e-7, 5e-6 # Ω.m². It is the electron conduction resistance of the circuit.
i0_d_c_ref_min, i0_d_c_ref_max = 1e-1, 100 # A.m-2.It is the dry reference exchange current density at the cathode.
i0_h_c_ref_min, i0_h_c_ref_max = 1e-2, 10 # A.m-2.It is the humid reference exchange current density at the cathode.
kappa_co_min, kappa_co_max = 0.01, 40 # A.m-2. It is the crossover correction coefficient.
kappa_c_min, kappa_c_max = 0.25, 4 # It is the overpotential correction exponent.
# The bounds on liquid saturation coefficients are constrained to facilitate calibration.
a_slim_min, a_slim_max = 0.0, 0.25 / min(Pc_des_1/1e5, Pc_des_2/1e5) # It is one of the limit liquid saturation coefficients.
b_slim_min, b_slim_max = 0.05, 0.3 # It is one of the limit liquid saturation coefficients.
a_switch_min, a_switch_max = 0.5, 0.95 # It is one of the limit liquid saturation coefficients.
# Undetermined parameter which is not considered yet (require the use of EIS curves to be calibrated)
C_scl_min, C_sl_max = 2e7, 2e7 # F.m-3. It is the volumetric space-charge layer capacitance.
# Bounds gathering and type
if voltage_zone == "before_voltage_drop":
varbound = [['Hacl', Hacl_min, Hacl_max, 'real'],
['Hccl', Hccl_min, Hccl_max, 'real'],
['Hmem', Hmem_min, Hmem_max, 'real'],
['epsilon_gdl', epsilon_gdl_min, epsilon_gdl_max, 'real'],
['epsilon_mc', epsilon_mc_min, epsilon_mc_max, 'real'],
['e', e_min, e_max, 'int'],
['Re', Re_min, Re_max, 'real'],
['i0_d_c_ref', i0_d_c_ref_min, i0_d_c_ref_max, 'real'],
['kappa_co', kappa_co_min, kappa_co_max, 'real'],
['kappa_c', kappa_c_min, kappa_c_max, 'real']]
else: # voltage_zone == "full"
varbound = [['i0_h_c_ref', i0_h_c_ref_min, i0_h_c_ref_max, 'real'],
['a_slim', a_slim_min, a_slim_max, 'real'],
['b_slim', b_slim_min, b_slim_max, 'real'],
['a_switch', a_switch_min, a_switch_max, 'real']]
gene_space = [] # List used to define the bounds of the undetermined parameters for pygad.
for i in range(len(varbound)):
name, min_val, max_val, type_val = varbound[i]
if type_val == 'int':
gene_space.append({'low': min_val, 'high': max_val, 'step': 1})
else:
gene_space.append({'low': min_val, 'high': max_val})
elif type_fuel_cell == "EH-31_1.5" or type_fuel_cell == "EH-31_2.0" or type_fuel_cell == "EH-31_2.25" or \
type_fuel_cell == "EH-31_2.5":
# Fuel cell physical parameters
Hacl_min, Hacl_max = 8e-6, 20e-6 # m. It is the thickness of the ACL.
Hmem_min, Hmem_max = 15e-6, 50e-6 # m. It is the thickness of the membrane.
epsilon_gdl_min, epsilon_gdl_max = 0.40, 0.95 # It is the anode/cathode GDL porosity, without units.
epsilon_mpl_min, epsilon_mpl_max = 0.30, 0.60 # It is the anode/cathode MPL porosity, without units.
epsilon_cl_min, epsilon_cl_max = 0.12, 0.50 # It is the anode/cathode MPL porosity, without units.
epsilon_mc_min, epsilon_mc_max = 0.15, 0.40 # It is the volume fraction of ionomer in the CL.
epsilon_c_min, epsilon_c_max = 0.15, 0.30 # It is the compression ratio of the GDL.
# Constants based on the interaction between water and the structure
e_min, e_max = 3, 5 # It is the capillary exponent, and should be an int number.
# Voltage polarization
Re_min, Re_max = 5e-7, 5e-6 # Ω.m². It is the electron conduction resistance of the circuit.
i0_d_c_ref_min, i0_d_c_ref_max = 1e-1, 100 # A.m-2.It is the dry reference exchange current density at the cathode.
i0_h_c_ref_min, i0_h_c_ref_max = 1e-2, 10 # A.m-2.It is the humid reference exchange current density at the cathode.
kappa_co_min, kappa_co_max = 0.01, 40 # A.m-2. It is the crossover correction coefficient.
kappa_c_min, kappa_c_max = 0.25, 4 # It is the overpotential correction exponent.
# The bounds on liquid saturation coefficients are constrained to facilitate calibration.
a_slim_min, a_slim_max = 0.0, 0.25 / min(Pc_des_1/1e5, Pc_des_2/1e5) # It is one of the limit liquid saturation coefficients.
b_slim_min, b_slim_max = 0.05, 0.3 # It is one of the limit liquid saturation coefficients.
a_switch_min, a_switch_max = 0.5, 0.95 # It is one of the limit liquid saturation coefficients.
# Undetermined parameter which is not considered yet (require the use of EIS curves to be calibrated)
C_scl_min, C_sl_max = 2e7, 2e7 # F.m-3. It is the volumetric space-charge layer capacitance.
# Bounds gathering and type
if voltage_zone == "before_voltage_drop":
varbound = [['Hacl', Hacl_min, Hacl_max, 'real'],
['Hmem', Hmem_min, Hmem_max, 'real'],
['epsilon_gdl', epsilon_gdl_min, epsilon_gdl_max, 'real'],
['epsilon_mc', epsilon_mc_min, epsilon_mc_max, 'real'],
['e', e_min, e_max, 'int'],
['Re', Re_min, Re_max, 'real'],
['i0_d_c_ref', i0_d_c_ref_min, i0_d_c_ref_max, 'real'],
['kappa_co', kappa_co_min, kappa_co_max, 'real'],
['kappa_c', kappa_c_min, kappa_c_max, 'real']]
else: # voltage_zone == "full"
varbound = [['epsilon_c', epsilon_c_min, epsilon_c_max, 'real'],
['i0_h_c_ref', i0_h_c_ref_min, i0_h_c_ref_max, 'real'],
['a_slim', a_slim_min, a_slim_max, 'real'],
['b_slim', b_slim_min, b_slim_max, 'real'],
['a_switch', a_switch_min, a_switch_max, 'real']]
gene_space = [] # List used to define the bounds of the undetermined parameters for pygad.
for i in range(len(varbound)):
name, min_val, max_val, type_val = varbound[i]
if type_val == 'int':
gene_space.append({'low': min_val, 'high': max_val, 'step': 1})
else:
gene_space.append({'low': min_val, 'high': max_val})
else:
raise ValueError("A correct type_fuel_cell should be given.")
return varbound, gene_space
|