mjolnir1122 commited on
Commit
eada9ac
·
verified ·
1 Parent(s): 576f06d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +614 -0
app.py ADDED
@@ -0,0 +1,614 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ import requests
7
+ import json
8
+ import os
9
+ from dotenv import load_dotenv
10
+ import plotly.express as px
11
+ import plotly.graph_objects as go
12
+ from datetime import datetime
13
+
14
+ # Load environment variables
15
+ load_dotenv()
16
+ GROQ_API_KEY = os.getenv('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')
17
+
18
+ # Page configuration
19
+ st.set_page_config(
20
+ page_title="Hydrogen Production Optimizer",
21
+ page_icon="⚡",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # Custom CSS
27
+ st.markdown("""
28
+ <style>
29
+ .main {
30
+ padding: 1rem;
31
+ }
32
+ .stButton>button {
33
+ width: 100%;
34
+ background-color: #4CAF50;
35
+ color: white;
36
+ }
37
+ .stTabs [data-baseweb="tab-list"] {
38
+ gap: 10px;
39
+ }
40
+ .stTabs [data-baseweb="tab"] {
41
+ padding: 10px;
42
+ border-radius: 4px 4px 0px 0px;
43
+ }
44
+ h1, h2, h3 {
45
+ color: #1E88E5;
46
+ }
47
+ .highlight {
48
+ background-color: #f0f8ff;
49
+ padding: 1rem;
50
+ border-radius: 0.5rem;
51
+ border-left: 5px solid #1E88E5;
52
+ }
53
+ </style>
54
+ """, unsafe_allow_html=True)
55
+
56
+ # Helper functions for calculations
57
+ def calculate_h2_production(method, water_quantity, energy_input, current_density, voltage):
58
+ """Calculate hydrogen production based on input parameters"""
59
+ # Conversion factors and efficiencies for different methods
60
+ method_efficiencies = {
61
+ "Alkaline Electrolysis": 0.65,
62
+ "PEM Electrolysis": 0.75,
63
+ "SOEC": 0.85
64
+ }
65
+
66
+ # Basic Faraday's law calculation (simplified)
67
+ # Assuming ideal conditions and standard molar volume
68
+ faraday_constant = 96485 # C/mol
69
+ molar_mass_h2 = 2.02 # g/mol
70
+
71
+ # Adjusting efficiency based on method
72
+ efficiency = method_efficiencies[method]
73
+
74
+ # Calculate total charge (Q = I * t)
75
+ # Assuming current_density is in A/cm² and we convert water_quantity to surface area
76
+ surface_area = water_quantity * 0.1 # Simplified conversion
77
+ current = current_density * surface_area # Total current in A
78
+
79
+ # Assuming energy_input helps determine operation time
80
+ time_hours = energy_input / (voltage * current) # Time in hours
81
+
82
+ # Calculate hydrogen production using Faraday's Law
83
+ moles_h2 = (current * time_hours * 3600 * efficiency) / (2 * faraday_constant)
84
+ mass_h2 = moles_h2 * molar_mass_h2 # grams
85
+ volume_h2 = moles_h2 * 22.4 # Standard liters
86
+
87
+ return {
88
+ "production_rate_g_per_hour": mass_h2 / time_hours,
89
+ "total_production_g": mass_h2,
90
+ "total_production_L": volume_h2,
91
+ "efficiency": efficiency,
92
+ "operation_time_hours": time_hours
93
+ }
94
+
95
+ def calculate_cost(method, water_cost, water_purification_cost, energy_source, energy_input, h2_production):
96
+ """Calculate the cost of hydrogen production"""
97
+ # Energy costs by source ($/kWh)
98
+ energy_costs = {
99
+ "Grid Electricity": 0.12,
100
+ "Solar": 0.08,
101
+ "Wind": 0.06,
102
+ "Nuclear": 0.10,
103
+ "Hydroelectric": 0.07
104
+ }
105
+
106
+ # Operational costs by method ($/kg H2)
107
+ operational_costs = {
108
+ "Alkaline Electrolysis": 1.2,
109
+ "PEM Electrolysis": 1.5,
110
+ "SOEC": 1.8
111
+ }
112
+
113
+ # Calculate water cost
114
+ total_water_cost = water_cost * (h2_production["total_production_g"] / 1000) # $/kg
115
+
116
+ # Calculate purification cost
117
+ total_purification_cost = water_purification_cost * (h2_production["total_production_g"] / 1000) # $/kg
118
+
119
+ # Calculate energy cost
120
+ energy_cost_rate = energy_costs[energy_source]
121
+ total_energy_cost = energy_cost_rate * energy_input # $
122
+
123
+ # Calculate operational cost
124
+ operational_cost_rate = operational_costs[method]
125
+ total_operational_cost = operational_cost_rate * (h2_production["total_production_g"] / 1000) # $
126
+
127
+ # Calculate total cost
128
+ total_cost = total_water_cost + total_purification_cost + total_energy_cost + total_operational_cost
129
+
130
+ # Calculate cost per kg of H2
131
+ cost_per_kg = total_cost / (h2_production["total_production_g"] / 1000) if h2_production["total_production_g"] > 0 else 0
132
+
133
+ return {
134
+ "water_cost": total_water_cost,
135
+ "purification_cost": total_purification_cost,
136
+ "energy_cost": total_energy_cost,
137
+ "operational_cost": total_operational_cost,
138
+ "total_cost": total_cost,
139
+ "cost_per_kg": cost_per_kg
140
+ }
141
+
142
+ def call_groq_api(user_inputs, production_data, cost_data):
143
+ """Call Groq API with Llama 3 to analyze production parameters and provide recommendations"""
144
+
145
+ if not GROQ_API_KEY:
146
+ return {"error": "Groq API key not found. Please set the GROQ_API_KEY environment variable."}
147
+
148
+ # Format inputs for the API
149
+ prompt = f"""
150
+ As a hydrogen production expert, analyze the following electrolysis parameters and provide recommendations for optimization:
151
+
152
+ Input Parameters:
153
+ - Water Source: {user_inputs['water_source']}
154
+ - Production Method: {user_inputs['production_method']}
155
+ - Energy Source: {user_inputs['energy_source']}
156
+ - Current Density: {user_inputs['current_density']} A/cm²
157
+ - Voltage: {user_inputs['voltage']} V
158
+ - Membrane Material: {user_inputs['membrane']}
159
+ - Electrode Materials: {user_inputs['electrodes']}
160
+
161
+ Production Results:
162
+ - Production Rate: {production_data['production_rate_g_per_hour']:.2f} g/hour
163
+ - Total Production: {production_data['total_production_g']:.2f} g
164
+ - Efficiency: {production_data['efficiency'] * 100:.1f}%
165
+ - Operation Time: {production_data['operation_time_hours']:.2f} hours
166
+
167
+ Cost Analysis:
168
+ - Water Cost: ${cost_data['water_cost']:.2f}
169
+ - Purification Cost: ${cost_data['purification_cost']:.2f}
170
+ - Energy Cost: ${cost_data['energy_cost']:.2f}
171
+ - Operational Cost: ${cost_data['operational_cost']:.2f}
172
+ - Total Cost: ${cost_data['total_cost']:.2f}
173
+ - Cost per kg H₂: ${cost_data['cost_per_kg']:.2f}
174
+
175
+ Please provide:
176
+ 1. An efficiency assessment of the current setup
177
+ 2. Three specific recommendations to improve efficiency
178
+ 3. Three specific recommendations to reduce costs
179
+ 4. An ideal parameter configuration based on the provided inputs
180
+
181
+ Format your response as a structured JSON with the following fields:
182
+ {
183
+ "efficiency_assessment": "text analysis",
184
+ "efficiency_recommendations": ["recommendation1", "recommendation2", "recommendation3"],
185
+ "cost_recommendations": ["recommendation1", "recommendation2", "recommendation3"],
186
+ "ideal_parameters": {
187
+ "current_density": value,
188
+ "voltage": value,
189
+ "membrane": "recommendation",
190
+ "electrodes": "recommendation",
191
+ "energy_source": "recommendation"
192
+ },
193
+ "estimated_improvement": {
194
+ "efficiency_increase": "percentage",
195
+ "cost_reduction": "percentage"
196
+ }
197
+ }
198
+ """
199
+
200
+ try:
201
+ # API call to Groq
202
+ headers = {
203
+ "Authorization": f"Bearer {GROQ_API_KEY}",
204
+ "Content-Type": "application/json"
205
+ }
206
+
207
+ payload = {
208
+ "messages": [
209
+ {"role": "user", "content": prompt}
210
+ ],
211
+ "model": "llama3-70b-8192",
212
+ "temperature": 0.5,
213
+ "max_tokens": 1024,
214
+ "response_format": {"type": "json_object"}
215
+ }
216
+
217
+ response = requests.post(
218
+ "https://api.groq.com/openai/v1/chat/completions",
219
+ headers=headers,
220
+ json=payload
221
+ )
222
+
223
+ if response.status_code == 200:
224
+ response_data = response.json()
225
+ # Extract JSON from the response
226
+ try:
227
+ recommendations_json = json.loads(response_data["choices"][0]["message"]["content"])
228
+ return recommendations_json
229
+ except json.JSONDecodeError:
230
+ return {"error": "Failed to parse API response as JSON"}
231
+ else:
232
+ return {"error": f"API call failed with status code {response.status_code}: {response.text}"}
233
+
234
+ except Exception as e:
235
+ return {"error": f"Error calling Groq API: {str(e)}"}
236
+
237
+ # Main application
238
+ def main():
239
+ # Sidebar for inputs
240
+ st.sidebar.image("https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Creative-Tail-Objects-flask.svg/256px-Creative-Tail-Objects-flask.svg.png", width=100)
241
+ st.sidebar.title("H₂ Production Parameters")
242
+
243
+ # Water parameters
244
+ st.sidebar.subheader("Water Parameters")
245
+ water_source = st.sidebar.selectbox("Water Source", ["Tap Water", "Deionized Water", "Seawater", "Wastewater", "Ultrapure Water"])
246
+ water_cost = st.sidebar.number_input("Water Cost ($/m³)", min_value=0.1, max_value=50.0, value=2.0, step=0.1)
247
+ water_purification_cost = st.sidebar.number_input("Water Purification Cost ($/m³)", min_value=0.0, max_value=100.0, value=5.0, step=0.5)
248
+ water_quantity = st.sidebar.number_input("Water Quantity (L)", min_value=1.0, max_value=10000.0, value=100.0, step=10.0)
249
+
250
+ # Electrolysis parameters
251
+ st.sidebar.subheader("Electrolysis Parameters")
252
+ production_method = st.sidebar.selectbox("Production Method", ["Alkaline Electrolysis", "PEM Electrolysis", "SOEC"])
253
+ current_density = st.sidebar.slider("Current Density (A/cm²)", min_value=0.1, max_value=2.0, value=0.5, step=0.1)
254
+ voltage = st.sidebar.slider("Voltage (V)", min_value=1.4, max_value=5.0, value=2.0, step=0.1)
255
+
256
+ # Materials
257
+ membrane = st.sidebar.selectbox("Membrane Material", ["Nafion", "Zirfon", "Ceramic", "PBI", "SPEEK"])
258
+ electrodes = st.sidebar.selectbox("Electrode Materials", ["Platinum", "Nickel", "Iridium Oxide", "Stainless Steel", "Carbon-based"])
259
+
260
+ # Energy parameters
261
+ st.sidebar.subheader("Energy Parameters")
262
+ energy_source = st.sidebar.selectbox("Energy Source", ["Grid Electricity", "Solar", "Wind", "Nuclear", "Hydroelectric"])
263
+ energy_input = st.sidebar.number_input("Energy Input (kWh)", min_value=1.0, max_value=10000.0, value=100.0, step=10.0)
264
+
265
+ # Collect user inputs
266
+ user_inputs = {
267
+ "water_source": water_source,
268
+ "water_cost": water_cost,
269
+ "water_purification_cost": water_purification_cost,
270
+ "water_quantity": water_quantity,
271
+ "production_method": production_method,
272
+ "current_density": current_density,
273
+ "voltage": voltage,
274
+ "membrane": membrane,
275
+ "electrodes": electrodes,
276
+ "energy_source": energy_source,
277
+ "energy_input": energy_input
278
+ }
279
+
280
+ # Main content area
281
+ st.title("Hydrogen Production Analysis & Optimization")
282
+ st.markdown("Analyze and optimize your hydrogen production process with AI-driven recommendations")
283
+
284
+ # Process button
285
+ analyze_button = st.button("Analyze Production Parameters")
286
+
287
+ if analyze_button:
288
+ with st.spinner("Calculating production parameters and generating AI recommendations..."):
289
+ # Calculate production
290
+ production_data = calculate_h2_production(
291
+ production_method,
292
+ water_quantity,
293
+ energy_input,
294
+ current_density,
295
+ voltage
296
+ )
297
+
298
+ # Calculate cost
299
+ cost_data = calculate_cost(
300
+ production_method,
301
+ water_cost,
302
+ water_purification_cost,
303
+ energy_source,
304
+ energy_input,
305
+ production_data
306
+ )
307
+
308
+ # Get AI recommendations
309
+ ai_recommendations = call_groq_api(user_inputs, production_data, cost_data)
310
+
311
+ # Display results in tabs
312
+ tabs = st.tabs(["Production Analysis", "Cost Analysis", "AI Recommendations", "Visualization"])
313
+
314
+ # Tab 1: Production Analysis
315
+ with tabs[0]:
316
+ st.header("Hydrogen Production Analysis")
317
+
318
+ # Key metrics in columns
319
+ col1, col2, col3 = st.columns(3)
320
+ with col1:
321
+ st.metric("Production Rate", f"{production_data['production_rate_g_per_hour']:.2f} g/hour")
322
+ st.metric("Total H₂ Produced", f"{production_data['total_production_g']:.2f} g")
323
+
324
+ with col2:
325
+ st.metric("Volume of H₂", f"{production_data['total_production_L']:.2f} L")
326
+ st.metric("Operation Time", f"{production_data['operation_time_hours']:.2f} hours")
327
+
328
+ with col3:
329
+ st.metric("System Efficiency", f"{production_data['efficiency']*100:.1f}%")
330
+ energy_consumption = energy_input / (production_data['total_production_g']/1000)
331
+ st.metric("Energy Consumption", f"{energy_consumption:.2f} kWh/kg H₂")
332
+
333
+ # Detailed production information
334
+ st.subheader("Process Details")
335
+ process_df = pd.DataFrame({
336
+ "Parameter": ["Production Method", "Current Density", "Voltage", "Membrane", "Electrodes",
337
+ "Water Source", "Water Quantity", "Energy Source", "Energy Input"],
338
+ "Value": [production_method, f"{current_density} A/cm²", f"{voltage} V", membrane, electrodes,
339
+ water_source, f"{water_quantity} L", energy_source, f"{energy_input} kWh"]
340
+ })
341
+ st.table(process_df)
342
+
343
+ # Tab 2: Cost Analysis
344
+ with tabs[1]:
345
+ st.header("Cost Analysis")
346
+
347
+ # Key metrics
348
+ col1, col2 = st.columns(2)
349
+ with col1:
350
+ st.metric("Total Production Cost", f"${cost_data['total_cost']:.2f}")
351
+ st.metric("Cost per kg H₂", f"${cost_data['cost_per_kg']:.2f}")
352
+
353
+ # Cost breakdown
354
+ st.subheader("Cost Breakdown")
355
+ cost_data_viz = {
356
+ "Category": ["Water", "Purification", "Energy", "Operation"],
357
+ "Cost ($)": [
358
+ cost_data["water_cost"],
359
+ cost_data["purification_cost"],
360
+ cost_data["energy_cost"],
361
+ cost_data["operational_cost"]
362
+ ]
363
+ }
364
+ cost_df = pd.DataFrame(cost_data_viz)
365
+
366
+ # Create cost breakdown chart
367
+ fig = px.pie(
368
+ cost_df,
369
+ values="Cost ($)",
370
+ names="Category",
371
+ title="Cost Distribution",
372
+ color_discrete_sequence=px.colors.sequential.Blues_r
373
+ )
374
+ st.plotly_chart(fig, use_container_width=True)
375
+
376
+ # Detailed cost table
377
+ st.subheader("Detailed Cost Breakdown")
378
+ detailed_cost_df = pd.DataFrame({
379
+ "Cost Component": ["Water Cost", "Water Purification", "Energy Cost", "Operational Cost", "Total Cost"],
380
+ "Amount ($)": [
381
+ f"${cost_data['water_cost']:.2f}",
382
+ f"${cost_data['purification_cost']:.2f}",
383
+ f"${cost_data['energy_cost']:.2f}",
384
+ f"${cost_data['operational_cost']:.2f}",
385
+ f"${cost_data['total_cost']:.2f}"
386
+ ],
387
+ "Percentage": [
388
+ f"{cost_data['water_cost']/cost_data['total_cost']*100:.1f}%",
389
+ f"{cost_data['purification_cost']/cost_data['total_cost']*100:.1f}%",
390
+ f"{cost_data['energy_cost']/cost_data['total_cost']*100:.1f}%",
391
+ f"{cost_data['operational_cost']/cost_data['total_cost']*100:.1f}%",
392
+ "100%"
393
+ ]
394
+ })
395
+ st.table(detailed_cost_df)
396
+
397
+ # Tab 3: AI Recommendations
398
+ with tabs[2]:
399
+ st.header("AI-Driven Recommendations")
400
+
401
+ if "error" in ai_recommendations:
402
+ st.error(f"Error getting AI recommendations: {ai_recommendations['error']}")
403
+ else:
404
+ # Efficiency Assessment
405
+ st.subheader("Efficiency Assessment")
406
+ st.markdown(f"<div class='highlight'>{ai_recommendations['efficiency_assessment']}</div>", unsafe_allow_html=True)
407
+
408
+ # Recommendations
409
+ col1, col2 = st.columns(2)
410
+ with col1:
411
+ st.subheader("Efficiency Recommendations")
412
+ for i, rec in enumerate(ai_recommendations['efficiency_recommendations'], 1):
413
+ st.markdown(f"**{i}.** {rec}")
414
+
415
+ with col2:
416
+ st.subheader("Cost Reduction Recommendations")
417
+ for i, rec in enumerate(ai_recommendations['cost_recommendations'], 1):
418
+ st.markdown(f"**{i}.** {rec}")
419
+
420
+ # Ideal parameters
421
+ st.subheader("Ideal Parameter Configuration")
422
+ ideal_params = ai_recommendations['ideal_parameters']
423
+
424
+ param_comparison = pd.DataFrame({
425
+ "Parameter": ["Current Density (A/cm²)", "Voltage (V)", "Membrane", "Electrodes", "Energy Source"],
426
+ "Current Value": [
427
+ current_density,
428
+ voltage,
429
+ membrane,
430
+ electrodes,
431
+ energy_source
432
+ ],
433
+ "Recommended Value": [
434
+ ideal_params['current_density'],
435
+ ideal_params['voltage'],
436
+ ideal_params['membrane'],
437
+ ideal_params['electrodes'],
438
+ ideal_params['energy_source']
439
+ ]
440
+ })
441
+ st.table(param_comparison)
442
+
443
+ # Estimated improvements
444
+ st.subheader("Estimated Improvements")
445
+ col1, col2 = st.columns(2)
446
+ with col1:
447
+ st.metric("Efficiency Increase", ai_recommendations['estimated_improvement']['efficiency_increase'])
448
+ with col2:
449
+ st.metric("Cost Reduction", ai_recommendations['estimated_improvement']['cost_reduction'])
450
+
451
+ # Tab 4: Visualization
452
+ with tabs[3]:
453
+ st.header("Production Visualization")
454
+
455
+ # Create comparison data
456
+ methods = ["Alkaline Electrolysis", "PEM Electrolysis", "SOEC"]
457
+ production_rates = []
458
+ costs_per_kg = []
459
+
460
+ for method in methods:
461
+ # Calculate for each method
462
+ prod_data = calculate_h2_production(
463
+ method,
464
+ water_quantity,
465
+ energy_input,
466
+ current_density,
467
+ voltage
468
+ )
469
+
470
+ cost_result = calculate_cost(
471
+ method,
472
+ water_cost,
473
+ water_purification_cost,
474
+ energy_source,
475
+ energy_input,
476
+ prod_data
477
+ )
478
+
479
+ production_rates.append(prod_data['production_rate_g_per_hour'])
480
+ costs_per_kg.append(cost_result['cost_per_kg'])
481
+
482
+ # Create comparison charts
483
+ col1, col2 = st.columns(2)
484
+
485
+ with col1:
486
+ # Production rate comparison
487
+ fig1 = px.bar(
488
+ x=methods,
489
+ y=production_rates,
490
+ title="Production Rate Comparison",
491
+ labels={"x": "Production Method", "y": "Production Rate (g/hour)"},
492
+ color=production_rates,
493
+ color_continuous_scale="Blues"
494
+ )
495
+ st.plotly_chart(fig1, use_container_width=True)
496
+
497
+ with col2:
498
+ # Cost comparison
499
+ fig2 = px.bar(
500
+ x=methods,
501
+ y=costs_per_kg,
502
+ title="Cost per kg Comparison",
503
+ labels={"x": "Production Method", "y": "Cost ($/kg)"},
504
+ color=costs_per_kg,
505
+ color_continuous_scale="Reds_r"
506
+ )
507
+ st.plotly_chart(fig2, use_container_width=True)
508
+
509
+ # Efficiency vs Cost scatter plot
510
+ efficiencies = [0.65, 0.75, 0.85] # Method efficiencies
511
+
512
+ fig3 = px.scatter(
513
+ x=efficiencies,
514
+ y=costs_per_kg,
515
+ size=production_rates,
516
+ text=methods,
517
+ title="Efficiency vs Cost Trade-off",
518
+ labels={"x": "Efficiency", "y": "Cost ($/kg)"},
519
+ color=methods
520
+ )
521
+
522
+ # Add a vertical line for current efficiency
523
+ current_efficiency = production_data['efficiency']
524
+ fig3.add_shape(
525
+ type="line",
526
+ x0=current_efficiency,
527
+ y0=0,
528
+ x1=current_efficiency,
529
+ y1=max(costs_per_kg) * 1.1,
530
+ line=dict(color="red", width=2, dash="dash")
531
+ )
532
+
533
+ # Add annotation for current efficiency
534
+ fig3.add_annotation(
535
+ x=current_efficiency,
536
+ y=max(costs_per_kg) * 0.9,
537
+ text="Current Efficiency",
538
+ showarrow=True,
539
+ arrowhead=1
540
+ )
541
+
542
+ st.plotly_chart(fig3, use_container_width=True)
543
+
544
+ # Current density vs production rate
545
+ current_densities = np.linspace(0.1, 2.0, 10)
546
+ production_results = []
547
+
548
+ for cd in current_densities:
549
+ prod_data = calculate_h2_production(
550
+ production_method,
551
+ water_quantity,
552
+ energy_input,
553
+ cd,
554
+ voltage
555
+ )
556
+ production_results.append(prod_data['production_rate_g_per_hour'])
557
+
558
+ fig4 = px.line(
559
+ x=current_densities,
560
+ y=production_results,
561
+ title=f"Impact of Current Density on {production_method} Production Rate",
562
+ labels={"x": "Current Density (A/cm²)", "y": "Production Rate (g/hour)"},
563
+ markers=True
564
+ )
565
+
566
+ # Add a vertical line for current current density
567
+ fig4.add_shape(
568
+ type="line",
569
+ x0=current_density,
570
+ y0=0,
571
+ x1=current_density,
572
+ y1=max(production_results) * 1.1,
573
+ line=dict(color="green", width=2, dash="dash")
574
+ )
575
+
576
+ st.plotly_chart(fig4, use_container_width=True)
577
+
578
+ # Add a simulation over time
579
+ st.subheader("Production Simulation Over Time")
580
+
581
+ # Create time series data
582
+ hours = list(range(0, int(production_data['operation_time_hours']) + 1))
583
+ if len(hours) > 1:
584
+ production_over_time = [h * production_data['production_rate_g_per_hour'] for h in hours]
585
+
586
+ fig5 = px.line(
587
+ x=hours,
588
+ y=production_over_time,
589
+ title="Cumulative Hydrogen Production Over Time",
590
+ labels={"x": "Time (hours)", "y": "Cumulative Production (g)"},
591
+ markers=True
592
+ )
593
+ st.plotly_chart(fig5, use_container_width=True)
594
+ else:
595
+ st.info("Operation time too short for meaningful time series visualization.")
596
+
597
+ # Export results button
598
+ st.download_button(
599
+ label="Export Results as CSV",
600
+ data=pd.DataFrame({
601
+ "Parameter": ["Production Method", "Water Source", "Current Density (A/cm²)", "Voltage (V)",
602
+ "Production Rate (g/h)", "Total Production (g)", "Efficiency (%)",
603
+ "Total Cost ($)", "Cost per kg ($/kg)"],
604
+ "Value": [production_method, water_source, current_density, voltage,
605
+ production_data['production_rate_g_per_hour'], production_data['total_production_g'],
606
+ production_data['efficiency']*100, cost_data['total_cost'], cost_data['cost_per_kg']]
607
+ }).to_csv(index=False),
608
+ file_name=f"hydrogen_production_analysis_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
609
+ mime="text/csv"
610
+ )
611
+
612
+ # Run the app
613
+ if __name__ == "__main__":
614
+ main()