module CANAL_GERAL

! sigla = CANAL_GER_

! objetivo: resolver o Escoamento Quase-Unidimensional em Canais

! Versão original 1.0 (Dez 1996)

! programador: Carlos Henrique Marchi
! local:       SINMEC/UFSC - Florianópolis - SC

! Versão atual    2.0 (28 Jan 00)

! última alteração =   24 Jun 09

!-------------------------------------------------

! RELAÇÃO DAS ROTINAS DESTE MÓDULO:

  ! CANAL_GER_escreve_texto
  ! CANAL_GER_executa
  ! CANAL_GER_graficos
  ! CANAL_GER_le_dados
  ! CANAL_GER_le_inicio
  ! CANAL_GER_le_parede
  ! CANAL_GER_saida_rex

!-------------------------------------------------

! rotinas onde são lidos ARQUIVOS de dados neste MÓDULO:

  ! CANAL_GER_le_dados
  ! CANAL_GER_le_inicio
  ! CANAL_GER_le_parede

!-------------------------------------------------

! rotinas onde são gerados ARQUIVOS neste MÓDULO:

  ! CANAL_GER_executa
  ! CANAL_GER_saida_rex

!-------------------------------------------------

use DADOS

use PAREDES

use CANAL_ARQUIVO        ! versão 1.2 (19 Jan 00)

use EXATO_CANAL    ! versão 1.0 (31 Jan 00)

use CANAL_NOMES    ! (19 Jan 00)

use CANAL_NUMERICO_GERAL ! versão 1.0 (11 Abr 00)

use CANAL_PLOTA          ! versão 1.2 (19 Jan 00)

! -----------------------------------------------

implicit none

! -----------------------------------------------

contains

! -----------------------------------------------

  subroutine CANAL_GER_escreve_texto

    call CANAL_ARQUIVO_escreve_campo_1D ( unit_main_can,   & ! unidade de arquivo para escrever
                            w_p_can,                 & ! freqüência de escrita
                            '*** pressão ***                                    ', & ! 50 colunas
                            ' ponto',                & !  6 colunas
                            'x (m)                ', & ! 21 colunas
                            'p (Pa)               ', & ! 21 colunas
                            1,                       & ! número do ponto inicial
                            nx,                      & ! número de dados a escrever
                            xp_can,                  & ! coordenada espacial
                            p_can                    ) ! variável a escrever


    call CANAL_ARQUIVO_escreve_campo_1D ( unit_main_can,   & ! unidade de arquivo para escrever
                            w_T_can,                 & ! freqüência de escrita
                            '*** temperatura ***                                ', & ! 50 colunas
                            ' ponto',                & !  6 colunas
                            'x (m)                ', & ! 21 colunas
                            'T (K)                ', & ! 21 colunas
                            1,                       & ! número do ponto inicial
                            nx,                      & ! número de dados a escrever
                            xp_can,                  & ! coordenada espacial
                            T_can                    ) ! variável a escrever


    call CANAL_ARQUIVO_escreve_campo_1D ( unit_main_can,   & ! unidade de arquivo para escrever
                            w_u_can,                     & ! freqüência de escrita
                            '*** velocidade nodal ***                           ', & ! 50 colunas
                            ' ponto',                & !  6 colunas
                            'x (m)                ', & ! 21 colunas
                            'u (m/s)              ', & ! 21 colunas
                            1,                       & ! número do ponto inicial
                            nx,                      & ! número de dados a escrever
                            xp_can,                  & ! coordenada espacial
                            u_can                    ) ! variável a escrever


    call CANAL_ARQUIVO_escreve_campo_1D ( unit_main_can,   & ! unidade de arquivo para escrever
                            w_ro_can,                & ! freqüência de escrita
                            '*** massa específica ***                           ', & ! 50 colunas
                            ' ponto',                & !  6 colunas
                            'x (m)                ', & ! 21 colunas
                            'ro (kg/m3)           ', & ! 21 colunas
                            1,                       & ! número do ponto inicial
                            nx,                      & ! número de dados a escrever
                            xp_can,                  & ! coordenada espacial
                            ro_can                   ) ! variável a escrever

  end subroutine CANAL_GER_escreve_texto 

! -----------------------------------------------

  subroutine CANAL_GER_executa

    ! lê dados de inicialização do programa CANAL
    call CANAL_GER_le_inicio ( unit_aux_can, inicio_can )

    ! dados do módulo ARQUIVO
    call CANAL_ARQUIVO_le_inicio ( unit_aux_can, arquivo_nome_inicio_modulo_can )
    call CANAL_ARQUIVO_passa_caso ( nome_caso_can )

    ! dados do módulo CANAL_GERAL
    if ( (itg_rhg == 1).and.(lista_canal_ger_can == 1) ) call CANAL_ARQUIVO_notepad_abre_dado ( nome_canal_ger_can )
    if ( le_canal_ger_can    == 1 ) call CANAL_GER_le_dados ( unit_aux_can, nome_canal_ger_can )
    if ( copia_canal_ger_can == 1 ) call CANAL_ARQUIVO_copia_arquivo ( nome_canal_ger_can )

    ! dados do programa PAREDE
!    call CANAL_GER_le_parede
    allocate ( xp_can(nx),   bp_can(nx),   tp_can(nx),   ep_can(nx),   dp_can(nx),  sp_can(nx), sap_can(nx), sbp_can(nx) )
    allocate ( xe_can(nx-1), re_can(nx-1), le_can(nx-1), ee_can(nx-1), se_can(nx-1) )

    xe_can = xe_par
    xp_can = xp_par
    re_can = re_par
    le_can = le_par
    bp_can = bp_par
    tp_can = tp_par
    ee_can = ee_par
    ep_can = ep_par
    dp_can = dp_par
    se_can = se_par
    sp_can = sp_par
    sap_can = sap_par
    sbp_can = sbp_par

    ! dados do módulo EXATO_CANAL
    call EXATO_CANAL_le_inicio ( unit_aux_can, exato_canal_nome_inicio_modulo_can )

    ! *** ALOCAÇÃO DE MEMÓRIA ***
    allocate ( p_can(nx), T_can(nx), u_can(nx), ro_can(nx) )

    ! solução analítica do problema e 
    ! condição inicial do modelo numérico

    call EXATO_CANAL_inicio_1 ( nx, n_canais, fm_can, sp_can, u_can, p_can, T_can, ro_can )

    ! solução numérica com propriedades constantes

    if ( modelo_can /= 1 ) call CANAL_NUM_GER_le_inicio ( unit_aux_can, num_ger_nome_inicio_modulo_can )

    if ( modelo_can == 2 ) &
       call CANAL_NUM_GER_executa ( unit_aux_can, nx,        n_canais,  modelo_can, num_cte_nome_inicio_modulo_can, xe_can,  &
                              xp_can,       se_can,    sp_can,    dp_can,     le_can,                         sbp_can, &
                              sap_can,      tp_can,    re_can,    ep_can,     ee_can,                         bp_can,  &
                              fm_can,       r_qwc_can, q_sai_can, u_can,      p_can,                          T_can,   &
                              ro_can,       itg_can,   itgmax_can )

    ! solução numérica com propriedades variáveis

    if ( modelo_can == 3 ) &
       call CANAL_NUM_GER_executa ( unit_aux_can, nx,        n_canais,  modelo_can, num_var_nome_inicio_modulo_can, xe_can,  &
                              xp_can,       se_can,    sp_can,    dp_can,     le_can,                         sbp_can, &
                              sap_can,      tp_can,    re_can,    ep_can,     ee_can,                         bp_can,  &
                              fm_can,       r_qwc_can, q_sai_can, u_can,      p_can,                          T_can,   &
                              ro_can,       itg_can,   itgmax_can )

    ! ----------------------------------------

    ! *** GERAÇÃO DOS ARQUIVOS DE SAÍDA ***

    if ( w_lista_can == 1 .and. itg_rhg == itg_rhg_max ) then
   
       call CANAL_ARQUIVO_cria_arquivo ( unit_main_can, trim(nome_caso_can)//'.canal.txt' )

       write ( unit_main_can, 1 ) titulo_can
       1 format ( /, t5, a100, // )

       call CANAL_ARQUIVO_escreve_data_hora ( unit_main_can )

       write(unit_main_can,2) p_can(1)-p_can(nx), T_can(1)
       2 format(/,1pe25.15,' = pressão do escoamento: saída - entrada (Pa)',/,  &
                  1pe25.15,' = temperatura do escoamento na saída dos canais (K)')

       write(unit_main_can,3) q_sai_can, r_qwc_can
       3 format(/,1pe25.15,' = taxa de transf.calor advectivo na saída dos canais (W)',/, &
                  1pe25.15,' = razão q_wall / q_advectivo na saída dos canais',/)

       call CANAL_GER_escreve_texto

       close ( unit_main_can )

       if ( lista_caso_can == 1 ) &
          call CANAL_ARQUIVO_notepad_abre_saida ( unit_aux_can, trim(nome_caso_can)//'.canal.txt' )

    end if

    if ( itg_rhg == itg_rhg_max ) then

       if ( modelo_can /= 3 ) call CANAL_GER_saida_rex ( unit_aux_can, p_can(1)-p(nx), T_can(1) )

       if ( lista_rex_can == 1 ) &
          call CANAL_ARQUIVO_notepad_abre_dado ( trim(nome_caso_can)//'.canal.num' )

       if ( w_grafico /= 0 ) call CANAL_GER_graficos

    end if

  end subroutine CANAL_GER_executa

!-------------------------------------------------

  subroutine CANAL_GER_graficos

    call CANAL_PLOTA_copia_Wgnuplot

    ! dados do módulo PLOTA: nomes dos casos a plotar (sem as extensões)
    call CANAL_PLOTA_le_inicio ( unit_aux_can, plota_nome_inicio_modulo_can )

    ! gráfico da pressão

    if ( g_p_can == 1 ) then
       call CANAL_ARQUIVO_grava_campo_1D ( unit_aux_can,             & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.pressao.dat', & ! nome do arquivo
                             w_p_can,                          & ! freqüência de escrita
                             1,                                & ! número do ponto inicial
                             nx,                               & ! número de dados a escrever
                             xp_can,                           & ! dados da coluna 1
                             p_can                             ) ! dados da coluna 2
    end if

    if ( g_p_can == 2 ) then
       call CANAL_ARQUIVO_grava_campo_e_tubeira ( unit_aux_can,      & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.pressao.dat', & ! nome do arquivo a gravar
                             w_p_can,                          & ! freqüência de escrita
                             1,                                & ! número do ponto inicial do campo
                             nx,                               & ! número do ponto final do campo
                             xp_can,                           & ! dados da coluna 1
                             p_can,                            & ! dados da coluna 2
                             xe_can,                           & ! coordenada espacial da face da tubeira
                             re_can                            ) ! raio da face da tubeira
    end if

    if ( g_p_can == 1 .or. g_p_can == 2 ) then
       call CANAL_PLOTA_gera_nomes ( unit_aux_can, '.pressao.dat' )
       call CANAL_PLOTA_le_dados_gnu (  unit_aux_can, 'canal.pressao.grafico.ent' )
       call CANAL_PLOTA_gera_gnu ( unit_aux_can, trim(nome_caso_can)//'.pressao.grafico.gnu' )
       call CANAL_PLOTA_executa_Wgnuplot ( unit_aux_can, trim(nome_caso_can)//'.pressao.grafico.gnu' )
    end if

    ! gráfico da temperatura

    if ( g_T_can == 1 ) then
       call CANAL_ARQUIVO_grava_campo_1D ( unit_aux_can,             & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.temperatura.dat', & ! nome do arquivo
                             w_T_can,                          & ! freqüência de escrita
                             1,                                & ! número do ponto inicial
                             nx,                               & ! número de dados a escrever
                             xp_can,                           & ! dados da coluna 1
                             T_can                             ) ! dados da coluna 2
    end if

    if ( g_T_can == 2 ) then
       call CANAL_ARQUIVO_grava_campo_e_tubeira ( unit_aux_can,      & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.temperatura.dat', & ! nome do arquivo a gravar
                             w_T_can,                          & ! freqüência de escrita
                             1,                                & ! número do ponto inicial do campo
                             nx,                               & ! número do ponto final do campo
                             xp_can,                           & ! dados da coluna 1
                             T_can,                            & ! dados da coluna 2
                             xe_can,                           & ! coordenada espacial da face da tubeira
                             re_can                            ) ! raio da face da tubeira
    end if

    if ( g_T_can == 1 .or. g_T_can == 2 ) then
       call CANAL_PLOTA_gera_nomes ( unit_aux_can, '.temperatura.dat' )
       call CANAL_PLOTA_le_dados_gnu (  unit_aux_can, 'canal.temperatura.grafico.ent' )
       call CANAL_PLOTA_gera_gnu ( unit_aux_can, trim(nome_caso_can)//'.temperatura.grafico.gnu' )
       call CANAL_PLOTA_executa_Wgnuplot ( unit_aux_can, trim(nome_caso_can)//'.temperatura.grafico.gnu' )
    end if

    ! gráfico da velocidade

    if ( g_u_can == 1 ) then
       call CANAL_ARQUIVO_grava_campo_1D ( unit_aux_can,             & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.velocidade.dat', & ! nome do arquivo
                             w_u_can,                          & ! freqüência de escrita
                             1,                                & ! número do ponto inicial
                             nx,                               & ! número de dados a escrever
                             xp_can,                           & ! dados da coluna 1
                             u_can                             ) ! dados da coluna 2
    end if

    if ( g_u_can == 2 ) then
       call CANAL_ARQUIVO_grava_campo_e_tubeira ( unit_aux_can,      & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.velocidade.dat', & ! nome do arquivo a gravar
                             w_u_can,                          & ! freqüência de escrita
                             1,                                & ! número do ponto inicial do campo
                             nx,                               & ! número do ponto final do campo
                             xp_can,                           & ! dados da coluna 1
                             u_can,                            & ! dados da coluna 2
                             xe_can,                           & ! coordenada espacial da face da tubeira
                             re_can                            ) ! raio da face da tubeira
    end if

    if ( g_u_can == 1 .or. g_u_can == 2 ) then
       call CANAL_PLOTA_gera_nomes ( unit_aux_can, '.velocidade.dat' )
       call CANAL_PLOTA_le_dados_gnu (  unit_aux_can, 'canal.velocidade.grafico.ent' )
       call CANAL_PLOTA_gera_gnu ( unit_aux_can, trim(nome_caso_can)//'.velocidade.grafico.gnu' )
       call CANAL_PLOTA_executa_Wgnuplot ( unit_aux_can, trim(nome_caso_can)//'.velocidade.grafico.gnu' )
    end if

    ! gráfico da massa_especifica

    if ( g_ro_can == 1 ) then
       call CANAL_ARQUIVO_grava_campo_1D ( unit_aux_can,             & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.massa_especifica.dat', & ! nome do arquivo
                             w_ro_can,                         & ! freqüência de escrita
                             1,                                & ! número do ponto inicial
                             nx,                               & ! número de dados a escrever
                             xp_can,                           & ! dados da coluna 1
                             ro_can                             ) ! dados da coluna 2
    end if

    if ( g_ro_can == 2 ) then
       call CANAL_ARQUIVO_grava_campo_e_tubeira ( unit_aux_can,      & ! unidade de arquivo para escrever
                             trim(nome_caso_can)//'.massa_especifica.dat', & ! nome do arquivo a gravar
                             w_ro_can,                         & ! freqüência de escrita
                             1,                                & ! número do ponto inicial do campo
                             nx,                               & ! número do ponto final do campo
                             xp_can,                           & ! dados da coluna 1
                             ro_can,                           & ! dados da coluna 2
                             xe_can,                           & ! coordenada espacial da face da tubeira
                             re_can                            ) ! raio da face da tubeira
    end if

    if ( g_ro_can == 1 .or. g_ro_can == 2 ) then
       call CANAL_PLOTA_gera_nomes ( unit_aux_can, '.massa_especifica.dat' )
       call CANAL_PLOTA_le_dados_gnu (  unit_aux_can, 'canal.massa_especifica.grafico.ent' )
       call CANAL_PLOTA_gera_gnu ( unit_aux_can, trim(nome_caso_can)//'.massa_especifica.grafico.gnu' )
       call CANAL_PLOTA_executa_Wgnuplot ( unit_aux_can, trim(nome_caso_can)//'.massa_especifica.grafico.gnu' )
    end if

  end subroutine CANAL_GER_graficos

! -----------------------------------------------

  subroutine CANAL_GER_le_dados ( unit, nome )

    integer,      intent(in) :: unit ! unidade do arquivo
    character*(*),intent(in) :: nome ! nome do arquivo

    open ( unit, file = trim(nome) )

    read ( unit, * ) titulo_can
    read ( unit, * ) nome_parede_can
    read ( unit, * ) modelo_can
    read ( unit, * ) w_lista_can
    read ( unit, * ) lista_caso_can

    read ( unit, * ) w_p_can
    read ( unit, * ) w_T_can
    read ( unit, * ) w_u_can
    read ( unit, * ) w_ro_can

    read ( unit, * ) w_grafico_can
    read ( unit, * ) g_p_can
    read ( unit, * ) g_T_can
    read ( unit, * ) g_u_can
    read ( unit, * ) g_ro_can

    read ( unit, * ) lista_rex_can

    close ( unit )

  end subroutine CANAL_GER_le_dados

!-------------------------------------------------

  subroutine CANAL_GER_le_inicio ( unit, nome )

    integer,      intent(in) :: unit ! unidade do arquivo
    character*(*),intent(in) :: nome ! nome do arquivo de dados de configuração do programa

    open ( unit, file = trim(nome) )

    read ( unit, * ) nome_canal_ger_can 
    read ( unit, * ) lista_canal_ger_can
    read ( unit, * ) le_canal_ger_can
    read ( unit, * ) copia_canal_ger_can

    read ( unit, * ) arquivo_nome_inicio_modulo_can  
    read ( unit, * ) exato_canal_nome_inicio_modulo_can 
    read ( unit, * ) plota_nome_inicio_modulo_can
    read ( unit, * ) num_ger_nome_inicio_modulo_can
    read ( unit, * ) num_cte_nome_inicio_modulo_can
    read ( unit, * ) num_var_nome_inicio_modulo_can

    close ( unit )

  end subroutine CANAL_GER_le_inicio

! -----------------------------------------------

  subroutine CANAL_GER_le_parede

    open ( unit_aux_can, file = trim(nome_parede_can), form = 'unformatted' )

    read ( unit_aux_can ) nx, n_canais

    ! *** ALOCAÇÃO DE MEMÓRIA ***
    allocate ( xp_can(nx),   bp_can(nx),   tp_can(nx),   ep_can(nx),   dp_can(nx),  sp_can(nx), sap_can(nx), sbp_can(nx) )
    allocate ( xe_can(nx-1), re_can(nx-1), le_can(nx-1), ee_can(nx-1), se_can(nx-1) )

    read ( unit_aux_can ) xe_can, xp_can, re_can, le_can, bp_can, tp_can, ee_can, ep_can, dp_can, se_can, sp_can, sap_can, sbp_can

    close ( unit_aux_can )

  end subroutine CANAL_GER_le_parede

! -----------------------------------------------

  subroutine CANAL_GER_saida_rex ( unit, dp, T_ex )

    integer,intent(in) :: unit   ! unidade do arquivo

    real*8,intent(in)  :: dp   ! queda de pressão do escoamento (Pa)
    real*8,intent(in)  :: T_ex ! temperatura do escoamento na saída dos canais (K)

    real*8 :: dx ! tamanho médio dos volumes de controle (m)
   
    open ( unit, file = trim(nome_caso_can)//'.canal.num' )

    dx = ( xe_can(nx-1) - xe_can(1) ) / ( nx - 2 )

    ! número total de variáveis = 2
    write(unit,1) dx, 2
    1 format(1pd25.15,' = dx',//, &
                   i5,' = número total de variáveis',/)

    ! parâmetro 1 = pressão do escoamento: saída - entrada (Pa)
    write(unit,11) dp
    11 format(3x,"'pressão do escoamento: saída - entrada (Pa)'",/, &
               1pd25.15,' = solução numérica',/)

    ! parâmetro 2 = temperatura do escoamento na saída dos canais (K)
    write(unit,12) T_ex
    12 format(3x,"'temperatura do escoamento na saída dos canais (K)'",/, &
               1pd25.15,' = solução numérica',/)
               
    ! tempo de processamento total
    write(unit,13) tcpu_mach, tcpu_can, tcpu_tot
    13 format(3x, "'tempo de processamento total (s)'", /, &
               1pe25.15,' = escoamento reativo', /, &
               1pe25.15,' = escoamento nos canais', /, &
               1pe25.15,' = tempo de processamento total',/)
 
     close(unit)

  end subroutine CANAL_GER_saida_rex

!-------------------------------------------------

end module CANAL_GERAL
