From 0772e973e3eded30cc71288ac728862d744bc943 Mon Sep 17 00:00:00 2001 From: Even Solbraa <41290109+EvenSol@users.noreply.github.com> Date: Thu, 27 Nov 2025 08:20:21 +0100 Subject: [PATCH] Fix pressure editing handling in water dew point page --- pages/0_TP_flash.py | 8 ++- pages/10_Gas_Hydrate.py | 37 +++++----- pages/30_Water Dew Point.py | 45 +++++++------ pages/40_LNGageing.py | 119 +++++++++++++++++---------------- pages/50_Property Generator.py | 2 + pages/60_Hydrogen.py | 12 ++-- pages/70_Helium.py | 6 +- 7 files changed, 123 insertions(+), 106 deletions(-) diff --git a/pages/0_TP_flash.py b/pages/0_TP_flash.py index eb4d494..d8b413b 100644 --- a/pages/0_TP_flash.py +++ b/pages/0_TP_flash.py @@ -83,11 +83,13 @@ # Check if the dataframe is empty if st.session_state.tp_flash_data.empty: st.error('No data to perform calculations. Please input temperature and pressure values.') + elif (st.edited_dfTP['Pressure (bara)'] <= 0).any(): + st.error('Pressure must be greater than 0 bara. Please update the pressure inputs before running calculations.') else: # Initialize a list to store results results_list = [] neqsim_fluid = fluid_df(st.edited_df, lastIsPlusFraction=isplusfluid, add_all_components=False).autoSelectModel() - + # Iterate over each row and perform calculations for idx, row in st.edited_dfTP.dropna().iterrows(): temp = row['Temperature (C)'] @@ -97,12 +99,12 @@ TPflash(neqsim_fluid) #results_df = st.data_editor(dataFrame(neqsim_fluid)) results_list.append(dataFrame(neqsim_fluid)) - + st.success('Flash calculations finished successfully!') st.subheader("Results:") # Combine all results into a single dataframe combined_results = pd.concat(results_list, ignore_index=True) - + # Display the combined results #st.subheader('Combined TP Flash Results') #st.dataframe(combined_results) diff --git a/pages/10_Gas_Hydrate.py b/pages/10_Gas_Hydrate.py index 33607fe..a171c49 100644 --- a/pages/10_Gas_Hydrate.py +++ b/pages/10_Gas_Hydrate.py @@ -76,23 +76,26 @@ # Check if water's MolarComposition[-] is greater than 0 water_row = st.edited_df[st.edited_df['ComponentName'] == 'water'] # Adjust 'ComponentName' and 'water' as necessary if not water_row.empty and water_row['MolarComposition[-]'].iloc[0] > 0: - neqsim_fluid = fluid_df(st.edited_df, lastIsPlusFraction=False, add_all_components=False).autoSelectModel() - results_list = [] - pres_list = [] - fluid_results_list = [] - for pres in st.edited_dfTP.dropna(): - pressure = pres - pres_list.append(pressure) - neqsim_fluid.setPressure(pressure, 'bara') - results_list.append(hydt(neqsim_fluid)-273.15) - fluid_results_list.append(dataFrame(neqsim_fluid)) - st.session_state['tp_data'] = pd.DataFrame({ - 'Pressure (bara)': pres_list, # Default example pressure - 'Temperature (C)': results_list # Default temperature - }) - st.session_state['tp_data'] = st.session_state['tp_data'].sort_values('Pressure (bara)') - st.success('Hydrate calculation finished successfully!') - combined_results = pd.concat(fluid_results_list, ignore_index=True) + if (st.edited_dfTP['Pressure (bara)'] <= 0).any(): + st.error('Pressure must be greater than 0 bara. Please update the pressure inputs before running calculations.') + else: + neqsim_fluid = fluid_df(st.edited_df, lastIsPlusFraction=False, add_all_components=False).autoSelectModel() + results_list = [] + pres_list = [] + fluid_results_list = [] + for pres in st.edited_dfTP.dropna(): + pressure = pres + pres_list.append(pressure) + neqsim_fluid.setPressure(pressure, 'bara') + results_list.append(hydt(neqsim_fluid)-273.15) + fluid_results_list.append(dataFrame(neqsim_fluid)) + st.session_state['tp_data'] = pd.DataFrame({ + 'Pressure (bara)': pres_list, # Default example pressure + 'Temperature (C)': results_list # Default temperature + }) + st.session_state['tp_data'] = st.session_state['tp_data'].sort_values('Pressure (bara)') + st.success('Hydrate calculation finished successfully!') + combined_results = pd.concat(fluid_results_list, ignore_index=True) if st.session_state.get('refresh', True): st.edited_dfTP2 = st.data_editor( diff --git a/pages/30_Water Dew Point.py b/pages/30_Water Dew Point.py index dbee991..c5ee3a7 100644 --- a/pages/30_Water Dew Point.py +++ b/pages/30_Water Dew Point.py @@ -51,7 +51,7 @@ st.divider() st.edited_dfTP = st.data_editor( - st.session_state.tp_data['Pressure (bara)'].dropna().reset_index(drop=True), + st.session_state.tp_data[['Pressure (bara)']].dropna().reset_index(drop=True), num_rows='dynamic', # Allows dynamic number of rows column_config={ 'Pressure (bara)': st.column_config.NumberColumn( @@ -68,26 +68,29 @@ # Check if water's MolarComposition[-] is greater than 0 water_row = st.edited_df[st.edited_df['ComponentName'] == 'water'] # Adjust 'ComponentName' and 'water' as necessary if not water_row.empty and water_row['MolarComposition[-]'].iloc[0] > 0: - neqsim_fluid = fluid_df(st.edited_df, lastIsPlusFraction=False, add_all_components=False).autoSelectModel() - results_list = [] - results_list2 = [] - pres_list = [] - fluid_results_list = [] - for pres in st.edited_dfTP.dropna(): - pressure = pres - pres_list.append(pressure) - neqsim_fluid.setPressure(pressure, 'bara') - results_list.append(hydt(neqsim_fluid)-273.15) - results_list2.append(waterdewt(neqsim_fluid)-273.15) - fluid_results_list.append(dataFrame(neqsim_fluid)) - st.session_state['tp_data'] = pd.DataFrame({ - 'Pressure (bara)': pres_list, # Default example pressure - 'Hydrate Temperature (C)': results_list, # Default temperature - 'Aqueous Temperature (C)': results_list2 # Default temperature - }) - st.session_state['tp_data'] = st.session_state['tp_data'].sort_values('Pressure (bara)') - st.success('Hydrate calculation finished successfully!') - combined_results = pd.concat(fluid_results_list, ignore_index=True) + pressure_values = st.edited_dfTP['Pressure (bara)'] + if (pressure_values <= 0).any(): + st.error('Pressure must be greater than 0 bara. Please update the pressure inputs before running calculations.') + else: + neqsim_fluid = fluid_df(st.edited_df, lastIsPlusFraction=False, add_all_components=False).autoSelectModel() + results_list = [] + results_list2 = [] + pres_list = [] + fluid_results_list = [] + for pressure in pressure_values.dropna(): + pres_list.append(pressure) + neqsim_fluid.setPressure(pressure, 'bara') + results_list.append(hydt(neqsim_fluid)-273.15) + results_list2.append(waterdewt(neqsim_fluid)-273.15) + fluid_results_list.append(dataFrame(neqsim_fluid)) + st.session_state['tp_data'] = pd.DataFrame({ + 'Pressure (bara)': pres_list, # Default example pressure + 'Hydrate Temperature (C)': results_list, # Default temperature + 'Aqueous Temperature (C)': results_list2 # Default temperature + }) + st.session_state['tp_data'] = st.session_state['tp_data'].sort_values('Pressure (bara)') + st.success('Hydrate calculation finished successfully!') + combined_results = pd.concat(fluid_results_list, ignore_index=True) if st.session_state.get('refresh', True): st.edited_dfTP2 = st.data_editor( diff --git a/pages/40_LNGageing.py b/pages/40_LNGageing.py index b32d7b4..ac48981 100644 --- a/pages/40_LNGageing.py +++ b/pages/40_LNGageing.py @@ -98,64 +98,67 @@ ) if st.button('Simulate Ageing'): if st.edited_df['MolarComposition[-]'].sum() > 0: - # Create fluid from user input - fluid = fluid_df(st.edited_df).autoSelectModel() - fluid.setPressure(pressure_transport, 'bara') - fluid.setTemperature(-160.0, "C") # setting a guessed initial temperature - - # Creating ship system for LNG ageing - ship = jneqsim.fluidmechanics.flowsystem.twophaseflowsystem.shipsystem.LNGship(fluid, volume_initial, BOR / 100.0) - ship.useStandardVersion("", standard_version) - ship.getStandardISO6976().setEnergyRefT(energy_ref_temp) - ship.getStandardISO6976().setVolRefT(volume_ref_temp) - ship.setEndTime(time_transport) - ship.createSystem() - ship.solveSteadyState(0) - ship.solveTransient(0) - ageingresults = ship.getResults("temp") - - ageingresults = ship.getResults("temp") - # Assuming ageingresults is already obtained from the simulation - results = ageingresults[1:] # Data rows - columns = ageingresults[0] # Column headers - - # Clean the column names to ensure uniqueness and handle empty or None values - cleaned_columns = [] - seen = set() - for i, col in enumerate(columns): - new_col = col if col not in (None, '') else f"Unnamed_{i}" - if new_col in seen: - new_col = f"{new_col}_{i}" - seen.add(new_col) - cleaned_columns.append(new_col) - - # Creating DataFrame from results with cleaned column names - resultsDF = pd.DataFrame([[float(str(j).replace(',', '')) for j in i] for i in results], columns=cleaned_columns) - resultsDF.columns = ['time', 'temperature','WI','GCV','density','volume','C1','C2','C3','iC4','nC4','iC5','nC5','C6','N2','energy', 'GCV_mass', 'gC1','gC2','gC3','giC4','gnC4','giC5','gnC5','gC6','gN2'] - - # Display the DataFrame - #print(resultsDF.head()) # or use st.dataframe(resultsDF) in Streamlit - - # Displaying the results DataFrame in Streamlit - st.subheader('Ageing Simulation Results') - st.dataframe(resultsDF) - - # Function to convert DataFrame to Excel and offer download - def convert_df_to_excel(df): - output = BytesIO() - with pd.ExcelWriter(output, engine='xlsxwriter') as writer: - df.to_excel(writer, index=False) - processed_data = output.getvalue() - return processed_data - - # Download button for the results in Excel format - # if st.button('Download Results as Excel'): - excel_data = convert_df_to_excel(resultsDF) - st.download_button(label='📥 Download Excel', - data=excel_data, - file_name='lng_ageing_results.xlsx', - mime='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') - st.divider() + if pressure_transport <= 0: + st.error('Transport pressure must be greater than 0 bara. Please update the pressure before running calculations.') + else: + # Create fluid from user input + fluid = fluid_df(st.edited_df).autoSelectModel() + fluid.setPressure(pressure_transport, 'bara') + fluid.setTemperature(-160.0, "C") # setting a guessed initial temperature + + # Creating ship system for LNG ageing + ship = jneqsim.fluidmechanics.flowsystem.twophaseflowsystem.shipsystem.LNGship(fluid, volume_initial, BOR / 100.0) + ship.useStandardVersion("", standard_version) + ship.getStandardISO6976().setEnergyRefT(energy_ref_temp) + ship.getStandardISO6976().setVolRefT(volume_ref_temp) + ship.setEndTime(time_transport) + ship.createSystem() + ship.solveSteadyState(0) + ship.solveTransient(0) + ageingresults = ship.getResults("temp") + + ageingresults = ship.getResults("temp") + # Assuming ageingresults is already obtained from the simulation + results = ageingresults[1:] # Data rows + columns = ageingresults[0] # Column headers + + # Clean the column names to ensure uniqueness and handle empty or None values + cleaned_columns = [] + seen = set() + for i, col in enumerate(columns): + new_col = col if col not in (None, '') else f"Unnamed_{i}" + if new_col in seen: + new_col = f"{new_col}_{i}" + seen.add(new_col) + cleaned_columns.append(new_col) + + # Creating DataFrame from results with cleaned column names + resultsDF = pd.DataFrame([[float(str(j).replace(',', '')) for j in i] for i in results], columns=cleaned_columns) + resultsDF.columns = ['time', 'temperature','WI','GCV','density','volume','C1','C2','C3','iC4','nC4','iC5','nC5','C6','N2','energy', 'GCV_mass', 'gC1','gC2','gC3','giC4','gnC4','giC5','gnC5','gC6','gN2'] + + # Display the DataFrame + #print(resultsDF.head()) # or use st.dataframe(resultsDF) in Streamlit + + # Displaying the results DataFrame in Streamlit + st.subheader('Ageing Simulation Results') + st.dataframe(resultsDF) + + # Function to convert DataFrame to Excel and offer download + def convert_df_to_excel(df): + output = BytesIO() + with pd.ExcelWriter(output, engine='xlsxwriter') as writer: + df.to_excel(writer, index=False) + processed_data = output.getvalue() + return processed_data + + # Download button for the results in Excel format + # if st.button('Download Results as Excel'): + excel_data = convert_df_to_excel(resultsDF) + st.download_button(label='📥 Download Excel', + data=excel_data, + file_name='lng_ageing_results.xlsx', + mime='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + st.divider() """ Units: diff --git a/pages/50_Property Generator.py b/pages/50_Property Generator.py index 79edbab..cfaed5e 100644 --- a/pages/50_Property Generator.py +++ b/pages/50_Property Generator.py @@ -384,6 +384,8 @@ def main(): total_molar_frac = st.edited_df["MolarComposition[-]"].sum() if total_molar_frac <= 0: st.error("Total Molar Composition must be greater than 0.") + elif min_pres <= 0 or max_pres <= 0: + st.error("Pressure range values must be greater than 0 bara. Please update the minimum and maximum pressure inputs.") else: # 2) Normalize fluid composition normalized_df = st.edited_df.copy() diff --git a/pages/60_Hydrogen.py b/pages/60_Hydrogen.py index 3706185..1794986 100644 --- a/pages/60_Hydrogen.py +++ b/pages/60_Hydrogen.py @@ -74,11 +74,13 @@ if st.button('Run Hydrogen Property Calculations'): if st.session_state.tp_flash_data.empty: st.error('No data to perform calculations. Please input temperature and pressure values.') + elif (st.session_state.tp_flash_data['Pressure (bara)'] <= 0).any(): + st.error('Pressure must be greater than 0 bara. Please update the pressure inputs before running calculations.') else: results_list = [] neqsim_fluid = fluid("srk") # Use SRK EoS neqsim_fluid.addComponent('hydrogen', 1.0, "mol/sec") # Add hydrogen component - + for idx, row in st.session_state.tp_flash_data.iterrows(): temp = row['Temperature (C)'] pressure = row['Pressure (bara)'] @@ -88,11 +90,11 @@ neqsim_fluid.initThermoProperties() neqsim_fluid.getPhase(0).getPhysicalProperties().setViscosityModel("Muzny_mod") neqsim_fluid.initPhysicalProperties() - - + + # Check number of phases num_phases = neqsim_fluid.getNumberOfPhases() - + if num_phases > 0: phase = neqsim_fluid.getPhase(0) try: @@ -130,7 +132,7 @@ break else: st.error("No valid phases found for Leachman model calculations.") - + st.success('Hydrogen property calculations completed!') st.subheader("Results:") combined_results = pd.DataFrame(results_list) diff --git a/pages/70_Helium.py b/pages/70_Helium.py index 6e4340f..9bafdc0 100644 --- a/pages/70_Helium.py +++ b/pages/70_Helium.py @@ -59,11 +59,13 @@ if st.button('Run Helium Property Calculations'): if st.session_state.tp_flash_data.empty: st.error('No data to perform calculations. Please input temperature and pressure values.') + elif (st.session_state.tp_flash_data['Pressure (bara)'] <= 0).any(): + st.error('Pressure must be greater than 0 bara. Please update the pressure inputs before running calculations.') else: results_list = [] neqsim_fluid = fluid("srk") # Use SRK EoS (VEGA EoS needs implementation) neqsim_fluid.addComponent('helium', 1.0, "mol/sec") # Add helium component - + for idx, row in st.session_state.tp_flash_data.iterrows(): temp = row['Temperature (C)'] pressure = row['Pressure (bara)'] @@ -74,7 +76,7 @@ neqsim_fluid.getPhase(0).getPhysicalProperties().setViscosityModel("KTA_mod") neqsim_fluid.initPhysicalProperties() - + # Check number of phases num_phases = neqsim_fluid.getNumberOfPhases() #st.write(f"Number of detected phases: {num_phases}")