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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 | def main_frame(root, canvas):
"""This function creates the main graphical elements, such as labels, entry widgets, radio buttons, and buttons.
It arranges them in the application window (root). It also initializes the choice dictionary variables for various
parameters and settings.
Parameters:
-----------
root : ThemedTk
The main application window where the graphical elements will be placed.
canvas : tk.Canvas
The canvas where the main graphical elements will be placed.
"""
# Create a custom styles
style = ttk.Style()
style.configure('Custom.TFrame', background='#f5f6f7')
style.configure('Blue.TButton', foreground='blue', font=('cmr10', 10, 'bold')) # Set the font color to blue
style.configure('Green.TButton', foreground='green', font=('cmr10', 10, 'bold')) # Set the font color to green
style.configure('Red.TButton', foreground='red', font=('cmr10', 10, 'bold')) # Set the font color to red
style.configure('Black.TButton', foreground='black', font=('cmr10', 10, 'bold')) # Set the font color to black
style.configure('Big.TButton', font=('cmr10', 12, 'bold'))
# Create control variables to track the visibility state of some frame
show_info_undetermined_parameters = tk.BooleanVar(value=False)
show_info_current_density_parameters = tk.BooleanVar(value=False)
show_info_computing_parameters = tk.BooleanVar(value=False)
# Create the frames to hold the different set of information
# Fuel cell type and operating conditions
operating_conditions_frame = ttk.Frame(root, style='Custom.TFrame')
operating_conditions_frame.grid(row=1, column=0, padx=5, pady=5)
# Accessible physical parameters
accessible_parameters_frame = ttk.Frame(root, style='Custom.TFrame')
accessible_parameters_frame.grid(row=3, column=0, padx=5, pady=5)
# Undetermined physical parameters
undetermined_parameters_frame = ttk.Frame(root, style='Custom.TFrame')
undetermined_parameters_frame.grid(row=5, column=0, padx=5, pady=5)
undetermined_parameters_frame.grid_remove() # Hide the frame by default
# Current density parameters
current_density_parameters_frame = ttk.Frame(root, style='Custom.TFrame')
current_density_parameters_frame.grid(row=7, column=0, padx=5, pady=5)
current_density_parameters_frame.grid_remove() # Hide the frame by default
# Computing parameters
computing_parameters_frame = ttk.Frame(root, style='Custom.TFrame')
computing_parameters_frame.grid(row=9, column=0, padx=5, pady=5)
computing_parameters_frame.grid_remove() # Hide the frame by default
# Model possibilities and current density choice
model_possibilities_frame = ttk.Frame(root, style='Custom.TFrame')
model_possibilities_frame.grid(row=11, column=0, padx=5, pady=5)
# Import the current density parameters from the settings file for default value
(step_current_parameters, pola_current_parameters, pola_current_for_cali_parameters, i_EIS, ratio_EIS, f_EIS, t_EIS,
current_density) = current_density_parameters()
f_power_min_EIS, f_power_max_EIS, nb_f_EIS, nb_points_EIS = f_EIS
# Create the choice dictionaries
choice_operating_conditions = \
{'Temperature - Tfc (°C)': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 2, 'label_column': 1},
'Anode pressure - Pa (bar)': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 2, 'label_column': 3},
'Cathode pressure - Pc (bar)': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 2, 'label_column': 5},
'Anode stoichiometry - Sa': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 3, 'label_column': 1},
'Cathode stoichiometry - Sc': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 3, 'label_column': 3},
'Anode humidity - Φa': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 4, 'label_column': 1},
'Cathode humidity - Φc': {'value': tk.DoubleVar(operating_conditions_frame), 'label_row': 4, 'label_column': 3}}
choice_accessible_parameters = \
{'AGC thickness - Hagc (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 1, 'label_column': 1},
'CGC thickness - Hcgc (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 1, 'label_column': 3},
'AGC width - Wagc (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 1, 'label_column': 5},
'CGC width - Wcgc (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 2, 'label_column': 1},
'GC cumulated length - Lgc (m)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 2, 'label_column': 3},
'Active area - Aact (cm²)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 2, 'label_column': 5}}
choice_undetermined_parameters = \
{'GDL thickness - Hgdl (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 0, 'label_column': 1},
'MPL thickness - Hmpl (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 0, 'label_column': 3},
'ACL thickness - Hacl (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 0, 'label_column': 5},
'CCL thickness - Hccl (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 1, 'label_column': 1},
'Membrane thickness - Hmem (µm)': {'value': tk.DoubleVar(accessible_parameters_frame), 'label_row': 1, 'label_column': 3},
'GDL porosity - ε_gdl': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 1, 'label_column': 5},
'CL porosity - ε_cl': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 1, 'label_column': 5},
'MPL porosity - ε_mpl': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 2, 'label_column': 1},
'Ionomer volume fraction - ε_mc': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 2, 'label_column': 3},
'Compression ratio - ε_c': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 2, 'label_column': 5},
'Capillary exponent - e': {'value': tk.IntVar(undetermined_parameters_frame), 'label_row': 3, 'label_column': 1},
'Electron resistance\n- Re (µΩ.m²)': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 4, 'label_column': 1},
'Reference exchange current\ndensity - i0_c_ref (A/m²)': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 4, 'label_column': 3},
'Crossover correction coefficient\n- κ_co (mol/(m.s.Pa))': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 4, 'label_column': 5},
'Overpotential correction\nexponent - κ_c': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 5, 'label_column': 1},
'Limit liquid saturation\ncoefficient - a_slim': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 5, 'label_column': 3},
'Limit liquid saturation\ncoefficient - b_slim': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 5, 'label_column': 5},
'Limit liquid saturation\ncoefficient - a_switch': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 6, 'label_column': 1},
'Volumetric space-charge layer\ncapacitance - C_scl (F/cm³)': {'value': tk.DoubleVar(undetermined_parameters_frame), 'label_row': 6, 'label_column': 3}}
choice_current_density_parameters = \
{'Stabilisation time\n- Δt_ini_step (min)': {'value': tk.DoubleVar(current_density_parameters_frame, step_current_parameters['delta_t_ini_step']/60),
'label_row': 0, 'label_column': 3},
'Loading time\n- Δt_load_step (s)': {'value': tk.DoubleVar(current_density_parameters_frame, step_current_parameters['delta_t_load_step']),
'label_row': 0, 'label_column': 5},
'Breaking time\n- Δt_break_step (min)': {'value': tk.DoubleVar(current_density_parameters_frame, step_current_parameters['delta_t_break_step']/60),
'label_row': 1, 'label_column': 3},
'Current density step\n- i_step (A/cm²)': {'value': tk.DoubleVar(current_density_parameters_frame, step_current_parameters['i_step']/1e4),
'label_row': 1, 'label_column': 5},
'Stabilisation time\n- Δt_ini_pola (min)': {'value': tk.DoubleVar(current_density_parameters_frame, pola_current_parameters['delta_t_ini_pola']/60),
'label_row': 2, 'label_column': 3},
'Loading time\n- Δt_load_pola (s)': {'value': tk.DoubleVar(current_density_parameters_frame, pola_current_parameters['delta_t_load_pola']),
'label_row': 2, 'label_column': 5},
'Breaking time\n- Δt_break_pola (min)': {'value': tk.DoubleVar(current_density_parameters_frame, pola_current_parameters['delta_t_break_pola']/60),
'label_row': 3, 'label_column': 3},
'Current density step\n- Δi_pola (A/cm²)': {'value': tk.DoubleVar(current_density_parameters_frame, pola_current_parameters['delta_i_pola']/1e4),
'label_row': 3, 'label_column': 5},
'Maximum current density\n- i_max_pola (A/cm²)': {'value': tk.DoubleVar(current_density_parameters_frame, 1.5),
'label_row': 4, 'label_column': 3},
'Static current\n- i_EIS (A/cm²)': {'value': tk.DoubleVar(current_density_parameters_frame, i_EIS),
'label_row': 5, 'label_column': 3},
'Current ratio\n- ratio_EIS (%)': {'value': tk.DoubleVar(current_density_parameters_frame, ratio_EIS),
'label_row': 5, 'label_column': 5},
'Number of points\ncalculated - nb_points_EIS': {'value': tk.IntVar(current_density_parameters_frame, nb_points_EIS),
'label_row': 6, 'label_column': 3},
'Power of the\ninitial frequency\n- f_power_min_EIS': {'value': tk.IntVar(current_density_parameters_frame, f_power_min_EIS),
'label_row': 6, 'label_column': 5},
'Power of the\nfinal frequency\n- f_power_max_EIS': {'value': tk.IntVar(current_density_parameters_frame, f_power_max_EIS),
'label_row': 7, 'label_column': 3},
'Number of frequencies\ntested - nb_f_EIS': {'value': tk.IntVar(current_density_parameters_frame, nb_f_EIS),
'label_row': 7, 'label_column': 5}}
choice_computing_parameters = \
{'Time for dynamic\ndisplay - Δt_dyn_step (s)': {'value': tk.DoubleVar(computing_parameters_frame, 300),
'label_row': 0, 'label_column': 1},
'Purge time - t_purge (s)': {'value': tk.DoubleVar(computing_parameters_frame, 0.6),
'label_row': 0, 'label_column': 3},
'Time between two purges\n- Δt_purge (s)': {'value': tk.DoubleVar(computing_parameters_frame, 15),
'label_row': 0, 'label_column': 5},
'Number of GDL nodes - n_gdl': {'value': tk.IntVar(computing_parameters_frame, 5),
'label_row': 1, 'label_column': 1}}
choice_buttons = \
{'type_fuel_cell': {'value': tk.StringVar(operating_conditions_frame, 'Enter your specifications'),
'label_row': 0},
'type_auxiliary': {'value': tk.IntVar(model_possibilities_frame, 2), 'label_row': 1},
'type_control': {'value': tk.IntVar(model_possibilities_frame, 0), 'label_row': 2},
'type_purge': {'value': tk.IntVar(model_possibilities_frame, 0), 'label_row': 3},
'type_display': {'value': tk.IntVar(model_possibilities_frame, 1), 'label_row': 4},
'type_plot': {'value': tk.IntVar(model_possibilities_frame, 0), 'label_row': 5}}
# Displays operating conditions and physical parameters on the screen (without their values)
# Display the dropdown menu buttons
ttk.Button(root, text='Undetermined physical parameters', style='Big.TButton',
command=lambda: toggle_info(undetermined_parameters_frame, show_info_undetermined_parameters, canvas)). \
grid(row=4, column=0, padx=5, pady=5)
ttk.Button(root, text='Current density parameters', style='Big.TButton',
command=lambda: toggle_info(current_density_parameters_frame, show_info_current_density_parameters,
canvas)). \
grid(row=6, column=0, padx=5, pady=5)
ttk.Button(root, text='Computing parameters', style='Big.TButton',
command=lambda: toggle_info(computing_parameters_frame, show_info_computing_parameters, canvas)). \
grid(row=8, column=0, padx=5, pady=5)
# Display the labels
display_parameter_labels(operating_conditions_frame, accessible_parameters_frame, undetermined_parameters_frame,
current_density_parameters_frame, computing_parameters_frame, choice_operating_conditions,
choice_accessible_parameters, choice_undetermined_parameters,
choice_current_density_parameters, choice_computing_parameters)
# Displays the value of the operating conditions and physical parameters on the screen.
display_parameters_value(operating_conditions_frame, accessible_parameters_frame, undetermined_parameters_frame,
current_density_parameters_frame, computing_parameters_frame, choice_operating_conditions,
choice_accessible_parameters, choice_undetermined_parameters,
choice_current_density_parameters, choice_computing_parameters)
# Display the radiobuttons on the screen
display_radiobuttons(model_possibilities_frame, choice_buttons)
# Display the 'type of fuel cell' widget on the screen.
ttk.Label(operating_conditions_frame, text='Fuel cell:', font=('cmr10', 12, 'bold')). \
grid(row=0, column=0, columnspan=2)
ttk.OptionMenu(operating_conditions_frame, choice_buttons['type_fuel_cell']['value'],
'Enter your specifications', 'Enter your specifications', 'EH-31 1.5 bar (2021)',
'EH-31 2.0 bar (2021)', 'EH-31 2.25 bar (2021)', 'EH-31 2.5 bar (2021)', 'Linhao Fan (2010)',
command=lambda value: changeValue(operating_conditions_frame, accessible_parameters_frame,
undetermined_parameters_frame, current_density_parameters_frame,
computing_parameters_frame, choice_operating_conditions,
choice_accessible_parameters, choice_undetermined_parameters,
choice_current_density_parameters, choice_computing_parameters,
choice_buttons)). \
grid(row=0, column=2, columnspan=2)
# Display the action buttons to select the type of current density to be applied.
ttk.Label(model_possibilities_frame, text='Current density:', font=('cmr10', 12, 'bold')). \
grid(row=6, column=0, columnspan=2, sticky="w")
current_button = {'Step curve': 0, 'Pola curve': 1, 'EIS curve': 2}
# Button to generate the step curve
ttk.Button(model_possibilities_frame, text='Step curve', style='Blue.TButton',
command=lambda: control_current_button(choice_operating_conditions, choice_accessible_parameters,
choice_undetermined_parameters, choice_current_density_parameters,
choice_computing_parameters, choice_buttons,
current_button['Step curve'])) \
.grid(row=6, column=2, padx=10, pady=20)
# Button to generate the Pola curve
ttk.Button(model_possibilities_frame, text='Pola curve', style='Green.TButton',
command=lambda: control_current_button(choice_operating_conditions, choice_accessible_parameters,
choice_undetermined_parameters, choice_current_density_parameters,
choice_computing_parameters, choice_buttons,
current_button['Pola curve'])) \
.grid(row=6, column=3, padx=10, pady=20)
# Button to generate the EIS curve
ttk.Button(model_possibilities_frame, text='EIS curve', style='Red.TButton',
command=lambda: control_current_button(choice_operating_conditions, choice_accessible_parameters,
choice_undetermined_parameters, choice_current_density_parameters,
choice_computing_parameters, choice_buttons,
current_button['EIS curve'])) \
.grid(row=6, column=4, padx=10, pady=20)
# About button
ttk.Button(model_possibilities_frame, text='About', style='Black.TButton', command=about) \
.grid(row=6, column=5, ipadx=12)
# Ensure the frame sizes are updated
root.update_idletasks()
set_equal_width(operating_conditions_frame, accessible_parameters_frame, undetermined_parameters_frame,
current_density_parameters_frame, computing_parameters_frame, model_possibilities_frame)
|