Desenvolva um programa em Python que permita calcular a altura do fluido
em função do volume do tanque elíptico. O programa deve:
- Definir os parâmetros geométricos do tanque (
);
- Calcular a área molhada
da elipse para diferentes valores de
;
- Determinar o volume acumulado
;
- Gerar um gráfico mostrando a variação de
em função de
;
- Permitir a entrada de novos valores de
pelo usuário e retornar o volume correspondente.
Passo 1
O que o exercício pede (resumido e claro):
- Construir um programa em Python que permita calcular a altura do fluido
em função do volume do tanque elíptico — mais precisamente: dado um calcular o volume . - O programa deve:
- Definir os parâmetros geométricos do tanque:
(diâmetro vertical), (diâmetro horizontal) e (comprimento do tanque). - Calcular a área molhada da seção elíptica
para diferentes valores de . - Determinar o volume acumulado
. - Gerar um gráfico mostrando a variação de
em função de . - Permitir a entrada de novos valores de
pelo usuário e retornar o volume correspondente.
- Definir os parâmetros geométricos do tanque:
Informações fornecidas e convenções que vou usar sem perguntar:
- O tanque tem seção transversal elíptica com diâmetros
(vertical) e (horizontal). - Vou medir
a partir do ponto mais baixo da elipse (ou seja, → vazio; → cheio). - O volume total para um determinado
é .
Passo 2
Entendendo a geometria da elipse — derivação da área molhada
passo a passo (a parte matemática):
- Definições das grandezas geométricas:
- Colocamos a elipse centrada na origem com equação
O fundo da elipse corresponde a e o topo a . Um nível de líquido (medido a partir do fundo) corresponde à coordenada vertical O domínio válido é - A largura da elipse em uma altura
é com Então a área do segmento da base até é - Para calcular essa integral, fazemos a substituição
. Então: Com e , obtemos - Usando
e integrando, - Substituindo
, obtemos a fórmula final prática: Essa expressão verifica os casos extremos: -
. -
(área total da elipse).
-
- O volume associado é simplesmente
Passo 3
Como implementar isso numericamente de forma estável e conveniente em Python (boas práticas rápidas):
- Observações numéricas:
- Ao calcular
é importante garantir que seu argumento esteja em . Por causa de erros numéricos, vamos usar um truncamento com . - A expressão
pode ser calculada com diretamente.
- Ao calcular
- Algoritmo para a função que calcula
: - Recebe
(pode ser escalar ou array), e . - Calcula
e . - Calcula
. - Calcula argumento para arcsin:
e aplica . -
. -
.
- Recebe
- Em seguida
. - Vamos escrever funções vetorizadas (usando NumPy) para permitir plot e entrada múltipla de
.
Passo 4
Como gerar o gráfico
em função de
:
- Gera um vetor de alturas
uniformemente espaçadas em , por exemplo com 300 pontos. - Calcula
para cada ponto (vetorizado). - Usa matplotlib para plotar
no eixo vertical e no eixo horizontal. Coloca título, rótulos e grid. - Opcionalmente plota uma linha indicando o volume total quando
.
Passo 5
Interação com o usuário para entrada de novos valores de
:
- Permitir que o usuário digite um único
ou vários separados por vírgula. - Para cada
verificar se pertence ao intervalo . Se inválido, avisar e pular. - Calcular e imprimir
e com formatação amigável (por exemplo, 3 casas decimais). - Repetir até o usuário digitar uma palavra de saída (por exemplo “sair” ou pressionar Enter sem valor).
Passo 6
Código Python completo pronto para uso (explicação curta dos blocos no código):
- O código a seguir implementa:
- funções: compute_area(h, Dmax, Dmin), compute_volume(h, Dmax, Dmin, L);
- rotina de plotagem plot_V_vs_h(Dmax, Dmin, L);
- loop interativo ask_user_loop(Dmax, Dmin, L);
- um bloco principal com exemplo de parâmetros iniciais que o usuário pode modificar.
Resposta
#!/usr/bin/env python3
"""
Programa para cálculo da área molhada A(h) e do volume V(h) de um tanque com
seção transversal elíptica. Também gera gráfico V x h e permite entrada
interativa de valores de h.
Como usar:
- Execute o script.
- No bloco principal você pode ajustar D_max, D_min e L.
- O script plota V(h) e depois entra em modo interativo para consultar volumes.
"""
import numpy as np
import matplotlib.pyplot as plt
def compute_area(h, D_max, D_min):
"""
Calcula a área molhada A(h) da seção elíptica até a altura h medida a partir do fundo.
Parâmetros:
h : escalar ou array de alturas (mesma unidade de D_max)
D_max : diâmetro vertical da elipse (altura total)
D_min : diâmetro horizontal da elipse (largura)
Retorna:
A(h) : área(s) correspondente(s) (mesma unidade^2)
Observações:
- h deve estar no intervalo [0, D_max]. Se for array, cada elemento deve obedecer.
"""
a = D_max / 2.0 # semi-eixo vertical
b = D_min / 2.0 # semi-eixo horizontal
# Converte h em array numpy para suportar vetorização
h_arr = np.asarray(h, dtype=float)
# Coordenada y_h correspondente (origem no centro da elipse): y_h = -a + h
y_h = -a + h_arr
# argumento para arcsin: u = y_h / a
# clip para evitar valores ligeiramente fora de [-1,1] por erros numéricos
u = np.clip(y_h / a, -1.0, 1.0)
theta_h = np.arcsin(u) # em radianos
# A(h) = a*b*(theta_h + sin(2*theta_h)/2 + pi/2)
A = a * b * (theta_h + 0.5 * np.sin(2.0 * theta_h) + 0.5 * np.pi)
# Para valores de h fora do intervalo [0, 2a] (ou seja [0, D_max]) colocamos 0 ou área total
# Isso torna a função tolerante a entradas fora do intervalo.
full_area = np.pi * a * b
if np.isscalar(h):
if h < 0:
return 0.0
if h > D_max:
return full_area
else:
# vetor: ajustar extremos
A = np.where(h_arr <= 0.0, 0.0, A)
A = np.where(h_arr >= D_max, full_area, A)
return A
def compute_volume(h, D_max, D_min, L):
"""
Volume V(h) = A(h) * L
"""
A = compute_area(h, D_max, D_min)
return A * L
def plot_V_vs_h(D_max, D_min, L, npoints=300, show=True, savepath=None):
"""
Gera gráfico de V(h) para h variando de 0 a D_max.
"""
h_vals = np.linspace(0.0, D_max, npoints)
V_vals = compute_volume(h_vals, D_max, D_min, L)
plt.figure(figsize=(8,5))
plt.plot(h_vals, V_vals, '-b', lw=2, label='V(h) = A(h)·L')
plt.xlabel('Altura do fluido h (mesma unidade de D_max)')
plt.ylabel('Volume V(h) (unidade^3)')
plt.title('Variação do volume V em função da altura h')
plt.grid(True)
plt.legend()
if savepath:
plt.savefig(savepath, dpi=150)
if show:
plt.show()
def ask_user_loop(D_max, D_min, L):
"""
Loop interativo que permite ao usuário entrar com valores de h e obter o volume.
O usuário pode digitar:
- um número (ex: 0.5)
- vários números separados por vírgula (ex: 0.2, 1.0, 2.3)
- 'sair' ou linha vazia para encerrar
"""
prompt = (
"\nDigite um valor de h (ou vários separados por vírgula) para calcular V(h),\n"
"ou digite 'sair' para encerrar.\n"
f"Intervalo válido: 0 <= h <= {D_max}\n"
"Entrada: "
)
while True:
s = input(prompt).strip()
if s == "" or s.lower() == "sair":
print("Encerrando. Até a próxima!")
break
# tenta separar por vírgula
parts = [p.strip() for p in s.split(',') if p.strip() != ""]
hs = []
ok = True
for p in parts:
try:
val = float(p.replace(',', '.')) # aceita vírgula decimal também
hs.append(val)
except ValueError:
print(f"Entrada inválida: '{p}'. Tente novamente.")
ok = False
break
if not ok:
continue
hs_arr = np.array(hs, dtype=float)
# valida intervalo
for i, hh in enumerate(hs_arr):
if hh < 0.0 or hh > D_max:
print(f" Atenção: h={hh} está fora do intervalo [0, {D_max}]. Ignorando esse valor.")
# calcula volumes (a função trata valores fora do intervalo também, mas avisamos)
Vs = compute_volume(hs_arr, D_max, D_min, L)
for hh, vv in zip(hs_arr, Vs):
# Impressão com 3 casas decimais
print(f" h = {hh:.6g} -> V = {vv:.6g} (unidade^3)")
def main():
# Exemplo de parâmetros iniciais (você pode alterar aqui)
D_max = 2.0 # exemplo: 2 metros (altura)
D_min = 1.0 # exemplo: 1 metro (largura)
L = 5.0 # comprimento do tanque em metros
print("Parâmetros do tanque:")
print(f" D_max = {D_max}")
print(f" D_min = {D_min}")
print(f" L = {L}")
# Plot V(h)
plot_V_vs_h(D_max, D_min, L, npoints=400)
# Modo interativo
ask_user_loop(D_max, D_min, L)
if __name__ == "__main__":
main()