Skip to content

Commit

Permalink
Commit versão 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelogcardozo committed Sep 20, 2023
1 parent ecfabcc commit 07124fe
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 117 deletions.
102 changes: 18 additions & 84 deletions app.py
Original file line number Diff line number Diff line change
@@ -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(
"""
<style>
img {
width: 25px; /* Define a largura da imagem */
height: 25px; /* Define a altura da imagem */
border-radius: 50%; /* Cria um efeito de círculo */
}
</style>
""",
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
Expand All @@ -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)
Expand All @@ -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)
223 changes: 190 additions & 33 deletions src/utils.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,203 @@
import plotly.graph_objects as go

def get_footer():
style = """
<style>
# MainMenu {visibility: hidden;}
footer {visibility: hidden;}
.stApp { bottom: 0px; }
</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 = """
<style>
# MainMenu {visibility: hidden;}
footer {visibility: hidden;}
.stApp { bottom: 0px; }
</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:[email protected]?subject=Ajuda%20-%20Calculadora%20de%20Tensão%20Crítica',
'Report a bug': 'mailto:[email protected]?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 &bull; [![GitHub](https://cdn.pixabay.com/photo/2022/01/30/13/33/github-6980894_1280.png)](https://github.com/marcelogcardozo)
&bull; [![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(
"""
<style>
img {
width: 25px; /* Define a largura da imagem */
height: 25px; /* Define a altura da imagem */
border-radius: 50%; /* Cria um efeito de círculo */
}
</style>
""",
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)

0 comments on commit 07124fe

Please sign in to comment.