# -*- coding: utf-8 -*-
"""
/***************************************************************************
 Sewercalc
                                 A QGIS plugin
 Plugin para dimensionamento de redes coletoras de esgoto 
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2025-02-07
        git sha              : $Format:%H$
        copyright            : (C) 2025 by Wanderilo  Lima
        email                : Wanderilo Lima
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""


import math

def Diametro(Q, i, n, Calc_diam, DN_tab):
    if  Calc_diam == "D75" :
        # Subcrítico
        D75 = ((3.52 * n * (Q / math.sqrt(i)))**(0.375))  # m
        DN = min([dn for dn in DN_tab.keys() if dn > (D75 * 1000) ], default=None) / 1000   # m
        escoamento = "SUBCRÍTICO"
        caract_calc = "D75"
        return D75, DN, escoamento, caract_calc
        
    elif Calc_diam == "D50" :
        # Supercrítico
        D50 = ((6.44 * n * (Q / math.sqrt(i)))**(0.375)) # m
        DN = min([dn for dn in DN_tab.keys() if dn > (D50 * 1000) ], default=None) / 1000  # m
        escoamento = "SUPERCRÍTICO"
        caract_calc = "D50"
        return D50, DN, escoamento, caract_calc

def geometria_conduto(h, DN):
    theta = 2 * math.acos(1 - (2 * h / DN))
    Am = (DN**2 / 8) * (theta - math.sin(theta))
    Pm = DN * theta / 2
    return Am, Pm

def velocidade_manning(Am, Pm, i, n):
    Rh = Am / Pm
    V = round((1 / n) * (Rh ** (2 / 3)) * (i ** 0.5), 6)
    return V

def calcular_altura_lamina(Q, i, n, DN, tol=1e-6):
    h_min = 0.001
    h_max = DN
    h_aprox = 0

    while h_max - h_min > tol:
        h_aprox = (h_min + h_max) / 2
        Am, Pm = geometria_conduto(h_aprox, DN)
        V = velocidade_manning(Am, Pm, i, n)
        Q_calc = Am * V

        if Q_calc < Q:
            h_min = h_aprox
        else:
            h_max = h_aprox

    return h_aprox

def calcular_parametros(Qi, Qf, i, n, CTM, CTJ, RM, Rmin, L, T, Calc_Diam, db_tabela):
    iteracao = 0
    max_iteracoes = 1000
    V_fim = 0
    V_critica = 0

    while iteracao < max_iteracoes:
        
        D, DN, escoamento, caract_calc = Diametro(Qf, i, n, Calc_Diam, db_tabela)

        # Calcular alturas da lâmina d'água
        h_ini = calcular_altura_lamina(Qi, i, n, DN)
        h_fim = calcular_altura_lamina(Qf, i, n, DN)

        # Calcular a geometria e a velocidade do fluxo
        A_ini, P_ini = geometria_conduto(h_ini, DN)
        A_fim, P_fim = geometria_conduto(h_fim, DN)
        V_ini = velocidade_manning(A_ini, P_ini, i, n)
        V_fim = velocidade_manning(A_fim, P_fim, i, n)

        # Calcular a velocidade crítica
        V_critica = round(6 * math.sqrt(9.81 * (A_fim / P_fim)), 6)

        # Parâmetros
        T_trativa = 10000 * (A_ini / P_ini) * i
        RJ = CTJ - (CTM - RM - (L * i))

        # Condições de parada
        if RJ >= Rmin and T_trativa >= T:
            break 

        # Ajustar a inclinação
        i += 0.00001 

        iteracao += 1

    return {
        'i': i,
        'D': D,
        'DN': DN,
        'Rh_ini': A_ini / P_ini,
        'Rh_fim': A_fim / P_fim,
        'y_ini': h_ini,
        'y_fim': h_fim,
        'V_ini': V_ini,
        'V_fim': V_fim,
        'T': T_trativa,
        'Vc': V_critica,
        'RJ': RJ,
        'Caract_calc': caract_calc,
        'Escoamento': escoamento
    }




'''
resultados = calcular_parametros(5.90, 9.71, 0.0001, 0.01, 99.61, 99.75, 0.90, 0.9, 31.12, 0.6, DN_tab)
def print_tabela(tabela):
    for chave, valor in tabela.items():
        print(f"Chave: {chave} | Valor: {valor}")


print('*'*60, "\n"," "*25 , "PVs"," "*25,"\n",'*'*60)
print_tabela(resultados)'''