diff --git a/app.py b/app.py
index 3145b7a..35c7b31 100644
--- a/app.py
+++ b/app.py
@@ -1,87 +1,30 @@
+from src.utils import reset_config, set_basic_info, set_sidebar_and_get_params, set_resultados
from src.calculadora import calcula_tensao_critica, calcular_abaco, calcular_v_max
-from src.utils import get_footer, set_chart, set_table
import streamlit as st
-st.set_page_config(
- page_title="Calculadora",
- page_icon=":coffee:",
- layout="wide",
- initial_sidebar_state="expanded"
-)
+reset_config(st)
-st.markdown(get_footer(), unsafe_allow_html=True)
+set_basic_info(st)
-st.title('Calculadora - Tensão Crítica')
-
-st.markdown("""
-
-Feito por: Marcelo Cardozo • [![GitHub](https://cdn.pixabay.com/photo/2022/01/30/13/33/github-6980894_1280.png)](https://github.com/marcelogcardozo)
- • [![LinkedIn](https://scontent.fsdu25-1.fna.fbcdn.net/v/t39.30808-1/267422938_4880673518668256_5792791296770782057_n.png?stp=dst-png_p200x200&_nc_cat=108&ccb=1-7&_nc_sid=754033&_nc_ohc=FzJ49MszpDkAX_b3T44&_nc_ht=scontent.fsdu25-1.fna&cb_e2o_trans=t&oh=00_AfC1YK5ssU0tc3BQcFnYLlPAJFN8jotV5pf9JJc-ANb7pQ&oe=650DDC2B)](https://www.linkedin.com/in/marcelogcardozo/)
-
-Versão: 0.1.0
-""")
-
-st.markdown(
- """
-
- """,
- unsafe_allow_html=True,
-)
-
-st.subheader('Resultados')
-st.divider()
-
-# Parâmetros de entrada
-st.sidebar.title('Parâmetros de Entrada')
-
-st.sidebar.subheader('Dados do Material')
-E = st.sidebar.number_input('Módulo de Elasticidade (GPa)', 0.1, None, 200.0) * 1000
-T_esc = st.sidebar.number_input('Tensão de Escoamento (MPa)', 0.1, None, 250.0)
-
-st.sidebar.subheader('Dados da Seção Transversal')
-A = st.sidebar.number_input('Área (mm²)', 0.0, None, 0.0)
-I = st.sidebar.number_input('Inércia (mm⁴)', 0.0, None, 0.0)
-r = st.sidebar.number_input('Raio de Giração (mm)', 0.0, None, 0.0)
-c = st.sidebar.number_input('Distância da Linha Neutra (mm)', 0.0, None, 0.0)
-
-st.sidebar.subheader('Dados do caso')
-P = st.sidebar.number_input('Carga aplicada (kN)', 0.0, None, 0.0)
-Le = st.sidebar.number_input('Comprimento efetivo do elemento (mm)', 0.1, None, 1000.0)
-e = st.sidebar.number_input('Excentricidade (mm)', 0.0, None, 0.0)
-FS = st.sidebar.number_input('Fator de Segurança', 0.0, None, 0.0)
-
-gerar_abaco_completo = st.sidebar.checkbox('Gerar ábaco completo', value=False, key='gerar_abaco')
-
-if gerar_abaco_completo:
-
- de = st.sidebar.number_input('De', 0.0, 2.0, 0.0)
- ate = st.sidebar.number_input('Até', 0.1, 2.0, 1.0)
-
- razao = st.sidebar.number_input('Razão', 0.1, 2.0, 0.1)
-else:
- de = 0.0
- ate = 1.0
- razao = 0.1
+E, T_esc, A, I, r, c, P, FS, Le, k, e, gerar_abaco_completo, de, ate, razao = set_sidebar_and_get_params(st)
# botao_calcular
if st.sidebar.button('Calcular'):
with st.spinner('Calculando...'):
-
- col1, col2, col3 = st.columns(3)
- col4, col5 = st.columns([0.85, 0.15])
-
- if (I == 0 and r == 0):
- st.error('Inércia e Raio de Giração não podem ser ambos iguais a 0')
+
+ if A == 0:
+ st.error('A área (A) não pode ser iguao a zero.')
+ st.stop()
+ elif (e > 0 and c == 0):
+ st.error('A distância do centroide à fibra mais comprimida (c) não podem ser iguais a zero quando a excentricidade (e) for maior do que zero.')
+ st.stop()
+ elif (r == 0 and I == 0):
+ st.error('O raio de giração (r) ou o momento de inércia (I) devem ser diferentes de zero.')
+ st.stop()
+ elif (Le == 0):
+ st.error('O comprimento efetivo de flambagem (Le) não pode ser igual a zero.')
st.stop()
- elif r == 0:
- r = (I / A) ** (1/2)
ecr2 = (e*c)/r**2
Ler = Le/r
@@ -91,6 +34,7 @@
if (P == 0 and FS > 0):
P = pcr / FS
+
tensao_normal_aplicada = (P * 1000) / A
v_max = calcular_v_max(P, pcr, e)
@@ -99,15 +43,5 @@
abaco = calcular_abaco(T_esc, ecr2, E, gerar_abaco_completo, de, ate, razao)
- col1.latex('P_{cr} = '+f'{pcr:.2f} kN')
- col1.latex(f'P = {P:.2f} kN')
-
- col2.latex('\sigma_{cr} = '+f'{tensao_normal_critica:.2f} MPa')
- col2.latex(f'\sigma = {tensao_normal_aplicada:.2f} MPa')
- col2.latex('V_{max} = '+f'{v_max:.2f} mm')
-
- col3.latex(f'FS = {FS:.2f}')
- col3.latex(f'Método: {"Euler" if e == 0 else "Secante"}')
+ set_resultados(st, pcr, P, tensao_normal_critica, tensao_normal_aplicada, v_max, FS, e, ecr2, abaco, gerar_abaco_completo)
- set_chart(col4, ecr2, abaco, gerar_abaco_completo)
- set_table(col5, ecr2, abaco)
diff --git a/src/utils.py b/src/utils.py
index b6a305f..5ba0e9a 100644
--- a/src/utils.py
+++ b/src/utils.py
@@ -1,46 +1,203 @@
import plotly.graph_objects as go
-def get_footer():
- style = """
-
- """
- return style
-
-def set_chart(col_widget, ecr2_base: float, abaco: dict, gerar_abaco_completo: bool) -> None:
+from math import sqrt
+import numpy as np
+
+def reset_config(st) -> None:
+
+ def _get_footer():
+ style = """
+
+ """
+ return style
- fig = go.Figure()
+ st.set_page_config(
+ page_title="Calculadora",
+ page_icon=":coffee:",
+ layout="wide",
+ initial_sidebar_state="expanded",
+ menu_items = {
+ 'Get Help': 'mailto:marcelo.cardozo.cg@gmail.com?subject=Ajuda%20-%20Calculadora%20de%20Tensão%20Crítica',
+ 'Report a bug': 'mailto:marcelo.cardozo.cg@gmail.com?subject=BUG%20-%20Calculadora%20de%20Tensão%20Crítica',
+ },
+ )
+
+ st.markdown(_get_footer(), unsafe_allow_html=True)
+
+def set_basic_info(st) -> None:
+
+ st.title('Calculadora - Tensão Crítica')
+
+ st.markdown("""
+
+ Feito por: Marcelo Cardozo • [![GitHub](https://cdn.pixabay.com/photo/2022/01/30/13/33/github-6980894_1280.png)](https://github.com/marcelogcardozo)
+ • [![LinkedIn](https://scontent.fsdu25-1.fna.fbcdn.net/v/t39.30808-1/267422938_4880673518668256_5792791296770782057_n.png?stp=dst-png_p200x200&_nc_cat=108&ccb=1-7&_nc_sid=754033&_nc_ohc=FzJ49MszpDkAX_b3T44&_nc_ht=scontent.fsdu25-1.fna&cb_e2o_trans=t&oh=00_AfC1YK5ssU0tc3BQcFnYLlPAJFN8jotV5pf9JJc-ANb7pQ&oe=650DDC2B)](https://www.linkedin.com/in/marcelogcardozo/)
+
+ Versão: 1.0
+ """)
+
+ st.markdown(
+ """
+
+ """,
+ unsafe_allow_html=True,
+ )
+
+ st.subheader('Resultados')
+ st.divider()
+
+def set_sidebar_and_get_params(st) -> tuple:
+
+ def _set_dados_do_material() -> tuple:
+
+ st.sidebar.subheader('Dados do Material')
+ E = st.sidebar.number_input('Módulo de Elasticidade (E) [GPa]', 0.0, None, 200.0) * 1000
+ T_esc = st.sidebar.number_input('Tensão de Escoamento ($\sigma_{y}$) [MPa]', 0.0, None, 250.0)
+
+ return E, T_esc
+
+ def _set_dados_secao_transversal() -> tuple:
+
+ st.sidebar.subheader('Dados da Seção Transversal')
+ A = st.sidebar.number_input('Área (A) [mm²]', 0.0, None, 0.0)
+ col1, col2 = st.sidebar.columns([0.4, 0.6])
+ select_box_I_r = col1.selectbox('Inércia ou Raio de Giração', ['I [mm⁴]', 'r [mm]'], label_visibility='collapsed')
+ value_I_r = col2.number_input('uma_label_qualquer', 0.0, None, 0.0, label_visibility='collapsed')
- for ecr2, pontos in abaco.items():
+ if select_box_I_r == 'I [mm⁴]':
+ I = value_I_r
+ try:
+ r = sqrt(I / A)
+ except ZeroDivisionError:
+ r = 0.0
+ else:
+ r = value_I_r
+ I = A * r**2
- xs = [p.ler for p in pontos]
- ys = [p.pa for p in pontos]
+ c = st.sidebar.number_input('Dist. da LN à Fibra de Maior Compressão (c) [mm]', 0.0, None, 0.0)
- dash = 'dash' if (ecr2 == ecr2_base and gerar_abaco_completo) else None
- line_trace = go.Line(x=xs, y=ys, name=f"{ecr2:.2f}", line=dict(dash=dash))
+ return A, I, r, c
- fig.add_trace(line_trace)
+ def _set_dados_do_caso() -> tuple:
- fig.update_layout(
- title= 'Ábaco de Euler e Secante',
- xaxis_title="Le/r",
- yaxis_title="P/A",
- legend_title="Ecr2",
- yaxis_range=[0, 300.1],
- xaxis_range=[0, 200.1],
- )
+ st.sidebar.subheader('Dados do caso')
+
+ col1, col2 = st.sidebar.columns([0.4, 0.6])
+
+ sbox_P = col1.selectbox('uma_label', ['P [kN]', 'FS'], label_visibility='collapsed') #st.sidebar.number_input('Carga aplicada (P) [kN]', 0.0, None, 0.0)
+ value_P = col2.number_input('uma_label2', 0.0, None, 0.0, label_visibility='collapsed')
+
+ if sbox_P == 'P [kN]':
+ P = value_P
+ FS = 0
+ else:
+ FS = value_P
+ P = 0
+
+ col1, col2 = st.sidebar.columns([0.4, 0.6])
+ sbox_Le = col1.selectbox('Comprimento efetivo do elemento (Le)', ['Le [mm]', 'L [mm]'], label_visibility='collapsed')
+ value_Le = col2.number_input('uma_label_qualquer2', 0.0, None, 0.0, label_visibility='collapsed')
+
+ if sbox_Le == 'L [mm]':
+ k = st.sidebar.select_slider('Coeficiente de Flambagem (k)', [str(round(i,2)) for i in np.arange(0.5, 2.05, 0.05)])
+ Le = float(k) * value_Le
+ else:
+ Le = value_Le
+ k = 1.0
+
+ e = st.sidebar.number_input('Excentricidade (e) [mm]', 0.0, None, 0.0)
+
+ return P, FS, Le, k, e
+
+ def _set_gerar_abaco_completo_params() -> tuple:
+
+ gerar_abaco_completo = st.sidebar.checkbox('Gerar ábaco completo', value=False, key='gerar_abaco')
+
+ if gerar_abaco_completo:
+
+ faixa_ecr2 = st.sidebar.slider(r'Faixa do $ec/r²$', 0.0, 2.0, (0.0, 1.0), 0.1)
+ de = faixa_ecr2[0]
+ ate = faixa_ecr2[1]
+
+ razao = st.sidebar.number_input('Razão', 0.1, 2.0, 0.1)
+ else:
+ de = 0.0
+ ate = 1.0
+ razao = 0.1
+
+ return gerar_abaco_completo, de, ate, razao
+
+ # Parâmetros de entrada
+ st.sidebar.title('Parâmetros de Entrada')
+
+ E, T_esc = _set_dados_do_material()
+ A, I, r, c = _set_dados_secao_transversal()
+ P, FS, Le, k, e = _set_dados_do_caso()
+ abaco_completo, de, ate, razao = _set_gerar_abaco_completo_params()
+
+ return E, T_esc, A, I, r, c, P, FS, Le, k, e, abaco_completo, de, ate, razao
+
+def set_resultados(st, pcr, P, tensao_normal_critica, tensao_normal_aplicada, v_max, FS, e, ecr2, abaco, gerar_abaco_completo) -> None:
+
+ def set_chart(col_widget, ecr2_base: float, abaco: dict, gerar_abaco_completo: bool) -> None:
+
+ fig = go.Figure()
+
+ for ecr2, pontos in abaco.items():
+
+ xs = [p.ler for p in pontos]
+ ys = [p.pa for p in pontos]
+
+ dash = 'dash' if (ecr2 == ecr2_base and gerar_abaco_completo) else None
+ line_trace = go.Scatter(x=xs, y=ys, name=f"{ecr2:.2f}", mode='lines', line=dict(dash=dash))
+
+ fig.add_trace(line_trace)
+
+ fig.update_layout(
+ title= 'Ábaco de Euler e Secante',
+ xaxis_title="Le/r",
+ yaxis_title="P/A",
+ legend_title="Ecr2",
+ yaxis_range=[0, 300.1],
+ xaxis_range=[0, 200.1],
+ )
+
+ col_widget.plotly_chart(fig, use_container_width=True)
+
+ def set_table(col_widget, ecr2, abaco) -> None:
+
+ data_for_dataframe = {
+ 'Le/r': [round(p.ler, 2) for p in abaco[ecr2]],
+ 'P/A': [round(p.pa, 2) for p in abaco[ecr2]],
+ }
+
+ col_widget.dataframe(data_for_dataframe)
+
+ col1, col2, col3 = st.columns(3)
+ col4, col5 = st.columns([0.85, 0.15])
+
+ col1.latex('P_{cr} = '+f'{pcr:.2f} kN')
+ col1.latex(f'P = {P:.2f} kN')
+
+ col2.latex('\sigma_{cr} = '+f'{tensao_normal_critica:.2f} MPa')
+ col2.latex(f'\sigma = {tensao_normal_aplicada:.2f} MPa')
+ col2.latex('V_{max} = '+f'{v_max:.2f} mm')
- col_widget.plotly_chart(fig, use_container_width=True)
+ col3.latex(f'FS = {FS:.2f}')
+ col3.latex(f'Método: {"Euler" if e == 0 else "Secante"}')
+ set_chart(col4, ecr2, abaco, gerar_abaco_completo)
+ set_table(col5, ecr2, abaco)
-def set_table(col_widget, ecr2, abaco) -> None:
- data_for_dataframe = {
- 'Le/r': [round(p.ler, 2) for p in abaco[ecr2]],
- 'P/A': [round(p.pa, 2) for p in abaco[ecr2]],
- }
- col_widget.dataframe(data_for_dataframe)
\ No newline at end of file