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 =   29 Mar 00

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

! 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 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 NUMERICO_GERAL ! versão 1.0 (11 Abr 00)

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

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

implicit none

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

contains

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

  subroutine CANAL_GER_escreve_texto

    call ARQUIVO_escreve_campo_1D ( unit_main,       & ! unidade de arquivo para escrever
                            w_p,                     & ! 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
                            n,                       & ! número de dados a escrever
                            xp,                      & ! coordenada espacial
                            p                        ) ! variável a escrever


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


    call ARQUIVO_escreve_campo_1D ( unit_main,       & ! unidade de arquivo para escrever
                            w_u,                     & ! 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
                            n,                       & ! número de dados a escrever
                            xp,                      & ! coordenada espacial
                            u                        ) ! variável a escrever


    call ARQUIVO_escreve_campo_1D ( unit_main,       & ! unidade de arquivo para escrever
                            w_ro,                    & ! 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
                            n,                       & ! número de dados a escrever
                            xp,                      & ! coordenada espacial
                            ro                       ) ! 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, inicio )

    ! dados do módulo ARQUIVO
    call ARQUIVO_le_inicio ( unit_aux, arquivo_nome_inicio_modulo )
    call ARQUIVO_passa_caso ( nome_caso )

    ! dados do módulo CANAL_GERAL
    if ( lista_canal_ger == 1 ) call ARQUIVO_notepad_abre_dado ( nome_canal_ger )
    if ( le_canal_ger    == 1 ) call CANAL_GER_le_dados ( unit_aux, nome_canal_ger )
    if ( copia_canal_ger == 1 ) call ARQUIVO_copia_arquivo ( nome_canal_ger )

    ! dados do programa PAREDE
    call CANAL_GER_le_parede

    ! dados do módulo EXATO_CANAL
    call EXATO_CANAL_le_inicio ( unit_aux, exato_canal_nome_inicio_modulo )

    ! *** ALOCAÇÃO DE MEMÓRIA ***
    allocate ( p(n), T(n), u(n), ro(n) )

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

    call EXATO_CANAL_inicio_1 ( n, m, fm, sp, u, p, T, ro )

    ! solução numérica com propriedades constantes

    if ( modelo /= 1 ) call NUM_GER_le_inicio ( unit_aux, num_ger_nome_inicio_modulo )

    if ( modelo == 2 ) &
       call NUM_GER_executa ( unit_aux, n,     m,     modelo, num_cte_nome_inicio_modulo, xe,  &
                              xp,       se,    sp,    dp,     le,                         sbp, &
                              sap,      tp,    re,    ep,     ee,                         bp,  &
                              fm,       r_qwc, q_sai, u,      p,                          T,   &
                              ro,       itg,   itgmax )

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

    if ( modelo == 3 ) &
       call NUM_GER_executa ( unit_aux, n,     m,     modelo, num_var_nome_inicio_modulo, xe,  &
                              xp,       se,    sp,    dp,     le,                         sbp, &
                              sap,      tp,    re,    ep,     ee,                         bp,  &
                              fm,       r_qwc, q_sai, u,      p,                          T,   &
                              ro,       itg,   itgmax )

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

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

    if ( w_lista == 1 .and. itg == itgmax ) then
   
       call ARQUIVO_cria_arquivo ( unit_main, trim(nome_caso)//'.canal.txt' )

       write ( unit_main, 1 ) titulo
       1 format ( /, t5, a100, // )

       call ARQUIVO_escreve_data_hora ( unit_main )

       write(unit_main,2) p(1)-p(n), T(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,3) q_sai, r_qwc
       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 )

       if ( lista_caso == 1 ) &
          call ARQUIVO_notepad_abre_saida ( unit_aux, trim(nome_caso)//'.canal.txt' )

    end if

    if ( itg == itgmax ) then

       if ( modelo /= 3 ) call CANAL_GER_saida_rex ( unit_aux, p(1)-p(n), T(1) )

       if ( lista_rex == 1 ) &
          call ARQUIVO_notepad_abre_dado ( trim(nome_caso)//'.canal.num' )

       if ( w_grafico /= 0 ) call CANAL_GER_graficos

    end if

  end subroutine CANAL_GER_executa

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

  subroutine CANAL_GER_graficos

    call PLOTA_copia_Wgnuplot

    ! dados do módulo PLOTA: nomes dos casos a plotar (sem as extensões)
    call PLOTA_le_inicio ( unit_aux, plota_nome_inicio_modulo )

    ! gráfico da pressão

    if ( g_p == 1 ) then
       call ARQUIVO_grava_campo_1D ( unit_aux,             & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.pressao.dat', & ! nome do arquivo
                             w_p,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial
                             n,                            & ! número de dados a escrever
                             xp,                           & ! dados da coluna 1
                             p                             ) ! dados da coluna 2
    end if

    if ( g_p == 2 ) then
       call ARQUIVO_grava_campo_e_tubeira ( unit_aux,      & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.pressao.dat', & ! nome do arquivo a gravar
                             w_p,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial do campo
                             n,                            & ! número do ponto final do campo
                             xp,                           & ! dados da coluna 1
                             p,                            & ! dados da coluna 2
                             xe,                           & ! coordenada espacial da face da tubeira
                             re                            ) ! raio da face da tubeira
    end if

    if ( g_p == 1 .or. g_p == 2 ) then
       call PLOTA_gera_nomes ( unit_aux, '.pressao.dat' )
       call PLOTA_le_dados_gnu (  unit_aux, 'canal.pressao.grafico.ent' )
       call PLOTA_gera_gnu ( unit_aux, trim(nome_caso)//'.pressao.grafico.gnu' )
       call PLOTA_executa_Wgnuplot ( unit_aux, trim(nome_caso)//'.pressao.grafico.gnu' )
    end if

    ! gráfico da temperatura

    if ( g_T == 1 ) then
       call ARQUIVO_grava_campo_1D ( unit_aux,             & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.temperatura.dat', & ! nome do arquivo
                             w_T,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial
                             n,                            & ! número de dados a escrever
                             xp,                           & ! dados da coluna 1
                             T                             ) ! dados da coluna 2
    end if

    if ( g_T == 2 ) then
       call ARQUIVO_grava_campo_e_tubeira ( unit_aux,      & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.temperatura.dat', & ! nome do arquivo a gravar
                             w_T,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial do campo
                             n,                            & ! número do ponto final do campo
                             xp,                           & ! dados da coluna 1
                             T,                            & ! dados da coluna 2
                             xe,                           & ! coordenada espacial da face da tubeira
                             re                            ) ! raio da face da tubeira
    end if

    if ( g_T == 1 .or. g_T == 2 ) then
       call PLOTA_gera_nomes ( unit_aux, '.temperatura.dat' )
       call PLOTA_le_dados_gnu (  unit_aux, 'canal.temperatura.grafico.ent' )
       call PLOTA_gera_gnu ( unit_aux, trim(nome_caso)//'.temperatura.grafico.gnu' )
       call PLOTA_executa_Wgnuplot ( unit_aux, trim(nome_caso)//'.temperatura.grafico.gnu' )
    end if

    ! gráfico da velocidade

    if ( g_u == 1 ) then
       call ARQUIVO_grava_campo_1D ( unit_aux,             & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.velocidade.dat', & ! nome do arquivo
                             w_u,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial
                             n,                            & ! número de dados a escrever
                             xp,                           & ! dados da coluna 1
                             u                             ) ! dados da coluna 2
    end if

    if ( g_u == 2 ) then
       call ARQUIVO_grava_campo_e_tubeira ( unit_aux,      & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.velocidade.dat', & ! nome do arquivo a gravar
                             w_u,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial do campo
                             n,                            & ! número do ponto final do campo
                             xp,                           & ! dados da coluna 1
                             u,                            & ! dados da coluna 2
                             xe,                           & ! coordenada espacial da face da tubeira
                             re                            ) ! raio da face da tubeira
    end if

    if ( g_u == 1 .or. g_u == 2 ) then
       call PLOTA_gera_nomes ( unit_aux, '.velocidade.dat' )
       call PLOTA_le_dados_gnu (  unit_aux, 'canal.velocidade.grafico.ent' )
       call PLOTA_gera_gnu ( unit_aux, trim(nome_caso)//'.velocidade.grafico.gnu' )
       call PLOTA_executa_Wgnuplot ( unit_aux, trim(nome_caso)//'.velocidade.grafico.gnu' )
    end if

    ! gráfico da massa_especifica

    if ( g_ro == 1 ) then
       call ARQUIVO_grava_campo_1D ( unit_aux,             & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.massa_especifica.dat', & ! nome do arquivo
                             w_ro,                          & ! freqüência de escrita
                             1,                            & ! número do ponto inicial
                             n,                            & ! número de dados a escrever
                             xp,                           & ! dados da coluna 1
                             ro                             ) ! dados da coluna 2
    end if

    if ( g_ro == 2 ) then
       call ARQUIVO_grava_campo_e_tubeira ( unit_aux,      & ! unidade de arquivo para escrever
                             trim(nome_caso)//'.massa_especifica.dat', & ! nome do arquivo a gravar
                             w_ro,                         & ! freqüência de escrita
                             1,                            & ! número do ponto inicial do campo
                             n,                            & ! número do ponto final do campo
                             xp,                           & ! dados da coluna 1
                             ro,                           & ! dados da coluna 2
                             xe,                           & ! coordenada espacial da face da tubeira
                             re                            ) ! raio da face da tubeira
    end if

    if ( g_ro == 1 .or. g_ro == 2 ) then
       call PLOTA_gera_nomes ( unit_aux, '.massa_especifica.dat' )
       call PLOTA_le_dados_gnu (  unit_aux, 'canal.massa_especifica.grafico.ent' )
       call PLOTA_gera_gnu ( unit_aux, trim(nome_caso)//'.massa_especifica.grafico.gnu' )
       call PLOTA_executa_Wgnuplot ( unit_aux, trim(nome_caso)//'.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
    read ( unit, * ) nome_parede
    read ( unit, * ) modelo
    read ( unit, * ) w_lista
    read ( unit, * ) lista_caso

    read ( unit, * ) w_p
    read ( unit, * ) w_T
    read ( unit, * ) w_u
    read ( unit, * ) w_ro

    read ( unit, * ) w_grafico
    read ( unit, * ) g_p
    read ( unit, * ) g_T
    read ( unit, * ) g_u
    read ( unit, * ) g_ro

    read ( unit, * ) lista_rex

    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 
    read ( unit, * ) lista_canal_ger
    read ( unit, * ) le_canal_ger
    read ( unit, * ) copia_canal_ger

    read ( unit, * ) arquivo_nome_inicio_modulo  
    read ( unit, * ) exato_canal_nome_inicio_modulo 
    read ( unit, * ) plota_nome_inicio_modulo
    read ( unit, * ) num_ger_nome_inicio_modulo
    read ( unit, * ) num_cte_nome_inicio_modulo
    read ( unit, * ) num_var_nome_inicio_modulo

    close ( unit )

  end subroutine CANAL_GER_le_inicio

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

  subroutine CANAL_GER_le_parede

    open ( unit_aux, file = trim(nome_parede), form = 'unformatted' )

    read ( unit_aux ) n, m

    ! *** ALOCAÇÃO DE MEMÓRIA ***
    allocate ( xp(n),   bp(n),   tp(n),   ep(n),   dp(n),  sp(n), sap(n), sbp(n) )
    allocate ( xe(n-1), re(n-1), le(n-1), ee(n-1), se(n-1) )

    read ( unit_aux ) xe, xp, re, le, bp, tp, ee, ep, dp, se, sp, sap, sbp

    close ( unit_aux )

  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)//'.canal.num' )

    dx = ( xe(n-1) - xe(1) ) / ( n - 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',/)

    close(unit)

  end subroutine CANAL_GER_saida_rex

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

end module CANAL_GERAL
