module NUMERICO_GERAL

! sigla = NUM_GER_

! objetivo: gerenciar o cálculo da solução numérica do modelo matemático

! versão original 1.0 (16 Dez 99)

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

! versão atual    1.0 (16 Dez 99)

! última alteração =   27 Fev 06

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

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

  ! NUM_GER_abre_iteracoes
  ! NUM_GER_abre_outros
  ! NUM_GER_executa
  ! NUM_GER_le_dados
  ! NUM_GER_le_inicio

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

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

  ! NUM_GER_le_dados
  ! NUM_GER_le_inicio

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

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

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

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

use NUMERICO_CONSTANTE   ! versão 1.1 (11 Abr 00)

use NUMERICO_VARIAVEL    ! versão 1.0 ( 3 Mai 00)

use NUMERICO_CONGELADO   ! versão 1.0 (26 Jan 06)

use NUMERICO_EQUILIBRIO  ! versão 1.0 ( 9 Fev 06)

use NUMERICO_TAXA_FINITA ! versão 1.0 (24 Fev 06)

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

implicit none

integer,private :: beta          ! 0=UDS; 1=CDS
integer,private :: nitm          ! número máximo de iterações no tempo
integer,private :: w_it          ! freqüência de escrita de parâmetros ao longo das iterações
integer,private :: lista_itera   ! lista solução iterativa
integer,private :: w_aux         ! freqüência de escrita de campos auxiliares
integer,private :: lista_aux     ! lista arquivo com os campos auxiliares (1); 0=não
integer,private :: tipo_ci       ! tipo de condição inicial: 1=analítica; 2=reinício

real*8, private :: dt            ! intervalo de tempo (s)

integer,private :: lista ! lista conteúdo do arquivo de dados do módulo NUMERICO_GERAL
integer,private :: le    ! lê conteúdo do arquivo de dados do módulo NUMERICO_GERAL
integer,private :: copia ! gera back up do arquivo de dados do módulo NUMERICO_GERAL

character*50,private  :: nome_ci      ! nome do arquivo de dados de reinício

character*50,private  :: nome_num_ger ! nome do arquivo de dados do módulo NUMERICO_GERAL

character*220,private :: comando      ! linha de comando

logical,private       :: dos          ! acessa prompt dos

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

contains

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

  subroutine NUM_GER_abre_iteracoes

    character*(150) :: trabalho ! nome do diretório para saídas
    character*(50)  :: caso     ! nome do caso

    if ( lista_itera == 0 ) return

    call ARQUIVO_passa_diretorio_trabalho ( trabalho )
    call ARQUIVO_passa_caso ( caso )
    comando = 'notepad '// trim(trabalho) // &
              trim(caso) // '.mach1d.itn'
    dos = systemqq ( comando )

  end subroutine NUM_GER_abre_iteracoes

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

  subroutine NUM_GER_abre_outros

    character*(150) :: trabalho ! nome do diretório para saídas
    character*(50)  :: caso     ! nome do caso

    if ( lista_aux == 0 ) return

    call ARQUIVO_passa_diretorio_trabalho ( trabalho )
    call ARQUIVO_passa_caso ( caso )
    comando = 'notepad '// trim(trabalho) // &
              trim(caso) // '.mach1d.outros.txt'
    dos = systemqq ( comando )

  end subroutine NUM_GER_abre_outros

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

  subroutine NUM_GER_executa ( unit, n,    modelo, fm_exato, F_exato, nome_inicio, rc,  &
                               Sg,   xe,   xp,     rp,       se,      sp,          sn,  &
                               fm,   F_ex, r_qwh,  q_sai,    u,       p,           T,   &
                               ro,   M,    p_tot,  T_tot,    itg,     itgmax       )

    integer,intent(in) :: unit    ! unidade de leitura do arquivo de dados
    integer,intent(in) :: n       ! número de volumes de controle com dois fictícios
    integer,intent(in) :: modelo  ! 2=numérico c/props.constantes; 3=numérico c/props.variáveis 

    real*8,intent(in) :: fm_exato ! fluxo de massa exato (kg/s)
    real*8,intent(in) :: F_exato  ! empuxo na saída da tubeira exato (N)   
    real*8,intent(in) :: rc       ! raio de curvatura na garganta da tubeira (m)
    real*8,intent(in) :: Sg       ! área da garganta (m2)

    character*(*),intent(in) :: nome_inicio ! nome do arquivo de dados de inicialização

    real*8,dimension(:),intent(in) :: xe ! coordenada espacial na face leste do volume de controle
    real*8,dimension(:),intent(in) :: xp ! coordenada espacial no centro do volume de controle
    real*8,dimension(:),intent(in) :: rp ! raio no centro do volume de controle
    real*8,dimension(:),intent(in) :: se ! área na face leste do volume de controle
    real*8,dimension(:),intent(in) :: sp ! área no centro do volume de controle
    real*8,dimension(:),intent(in) :: sn ! área da parede da tubeira

    real*8,intent(out) :: fm    ! fluxo de massa numérico (kg/s)
    real*8,intent(out) :: F_ex  ! empuxo na saída da tubeira numérico (N)
    real*8,intent(out) :: r_qwh ! razão q_wall / q_sai
    real*8,intent(out) :: q_sai ! taxa de transferência de calor advectivo na saída da tubeira (W)

    real*8,dimension(:),intent(inout) :: u     ! velocidade (m/s)
    real*8,dimension(:),intent(inout) :: p     ! pressão (Pa)
    real*8,dimension(:),intent(inout) :: T     ! temperatura (K)
    real*8,dimension(:),intent(inout) :: ro    ! massa específica (kg/m3)
    real*8,dimension(:),intent(inout) :: M     ! número de Mach (adimensional)
    real*8,dimension(:),intent(inout) :: p_tot ! pressão de estagnação (Pa)
    real*8,dimension(:),intent(inout) :: T_tot ! temperatura de estagnação (K)

    integer,intent(inout) :: itg    ! número da iteração global corrente entre MACH1D e CANAL
    integer,intent(inout) :: itgmax ! número da iteração global máxima entre MACH1D e CANAL a realizar

    select case ( modelo )

       case ( 2 )
          call NUM_CTE_le_inicio ( unit, nome_inicio )
          call NUM_CTE_executa ( n,     w_it, beta, nitm, dt, fm_exato, F_exato, &
                                 xe,    xp,   rp,   se,   sp, sn,       fm,      &
                                 F_ex,  u,    p,    T,    ro, r_qwh,    q_sai,   &
                                 w_aux, lista_aux   )

       case ( 3 )
          call NUM_VAR_le_inicio ( unit, nome_inicio )
          call NUM_VAR_executa ( n,         w_it,  beta,     nitm,    tipo_ci, nome_ci, w_aux, &
                                 lista_aux, dt,    fm_exato, F_exato, rc,      Sg,      xe,    &
                                 xp,        rp,    se,       sp,      sn,      fm,      F_ex,  &
                                 r_qwh,     q_sai, u,        p,       T,       ro,      M,     &
                                 p_tot,     T_tot, itg,      itgmax   )

       case ( 4 )
          call NUM_CONG_le_inicio ( unit, nome_inicio )
          call NUM_CONG_executa ( n,         w_it,  beta,     nitm,    tipo_ci, nome_ci, w_aux, &
                                  lista_aux, dt,    fm_exato, F_exato, rc,      Sg,      xe,    &
                                  xp,        rp,    se,       sp,      sn,      fm,      F_ex,  &
                                  r_qwh,     q_sai, u,        p,       T,       ro,      M,     &
                                  p_tot,     T_tot, itg,      itgmax   )

       case ( 5 )
          call NUM_EQ_le_inicio ( unit, nome_inicio )
          call NUM_EQ_executa ( n,         w_it,  beta,     nitm,    tipo_ci, nome_ci, w_aux, &
                                lista_aux, dt,    fm_exato, F_exato, rc,      Sg,      xe,    &
                                xp,        rp,    se,       sp,      sn,      fm,      F_ex,  &
                                r_qwh,     q_sai, u,        p,       T,       ro,      M,     &
                                p_tot,     T_tot, itg,      itgmax   )

       case ( 6 )
          call NUM_TF_le_inicio ( unit, nome_inicio )
          call NUM_TF_executa ( n,         w_it,  beta,     nitm,    tipo_ci, nome_ci, w_aux, &
                                lista_aux, dt,    fm_exato, F_exato, rc,      Sg,      xe,    &
                                xp,        rp,    se,       sp,      sn,      fm,      F_ex,  &
                                r_qwh,     q_sai, u,        p,       T,       ro,      M,     &
                                p_tot,     T_tot, itg,      itgmax   )

    end select

    if ( itg == itgmax ) then
       call NUM_GER_abre_iteracoes
       call NUM_GER_abre_outros
    end if

  end subroutine NUM_GER_executa 

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

  subroutine NUM_GER_le_dados ( unit )

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

    open ( unit, file = trim(nome_num_ger) )

    read ( unit, * ) beta
    read ( unit, * ) dt
    read ( unit, * ) nitm
    read ( unit, * ) tipo_ci
    read ( unit, * ) nome_ci
    read ( unit, * ) w_it
    read ( unit, * ) lista_itera
    read ( unit, * ) w_aux
    read ( unit, * ) lista_aux

    close ( unit )

  end subroutine NUM_GER_le_dados 

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

  subroutine NUM_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 módulo

    open ( unit, file = trim(nome) )

    read ( unit, * ) nome_num_ger 
    read ( unit, * ) lista
    read ( unit, * ) le
    read ( unit, * ) copia

    close ( unit )

    if ( lista == 1 ) call ARQUIVO_notepad_abre_dado ( nome_num_ger )

    if ( le    == 1 ) call NUM_GER_le_dados ( unit )

    if ( copia == 1 ) call ARQUIVO_copia_arquivo ( nome_num_ger )

  end subroutine NUM_GER_le_inicio

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

end module NUMERICO_GERAL