module dados

! Objetivos: definir as variáveis globais do código, 
!            ler e escrever os dados principais do código,
!            alocar memória para as variáveis globais,
!            obter a data e a hora do sistema.

! Versão atual: 2 Ago 09

! Relação das sub-rotinas em ordem de apresentação:
!   1) le_dados
!   2) mostra_dados
!   3) aloca_memoria
!   4) data_hora

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

use portlib

implicit none

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

! *** variáveis da malha ***

integer :: nx     ! número total de volumes na direção X (com 2 fictícios)
integer :: ny     ! número total de volumes na direção Y (com 2 fictícios)
integer :: nxy    ! nx * ny: número total de volumes da malha

integer :: i      ! número do volume na direção X
integer :: j      ! número do volume na direção Y
integer :: np     ! número do volume nas direções X e Y combinados

integer :: coord  ! sistema de coordenadas: 0=plano; 1=axissimétrico
integer :: grid   ! tipo de malha: 1=uniforme por linha;

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

! *** variáveis do processo iterativo ***

integer :: itmax  ! número máximo de iterações externas
integer :: it     ! número da iteração externa
integer :: nitm   ! número máximo de iterações internas no MSI
real*8  :: toli   ! tolerância do MSI
real*8  :: tole   ! tolerância sobre as iterações externas (norma L1)
real*8  :: norma  ! norma L1 de todos os sistemas lineares na iteração it
real*8  :: norma1 ! norma L1 de todos os sistemas lineares na iteração it=1
integer :: ci     ! tipo da condição inicial: 0=nula

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

! *** dados físicos ***

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

! *** resultados físicos ***

real*8 :: Tmin2D ! temperatura mínima da parede do modelo 2D
real*8 :: Tmax2D ! temperatura máxima da parede do modelo 2D

real*8 :: q1D    ! taxa de transferência de calor do modelo 1D
real*8 :: q2D    ! taxa de transferência de calor do modelo 2D

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

! *** variáveis com dimensão = nx ***

real*8,dimension(:),allocatable :: Twc1D ! T parede fria 1D
real*8,dimension(:),allocatable :: Twh1D ! T parede quente 1D

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

! *** variáveis com dimensão = ny ***

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

! *** variáveis com dimensão = nxy ***

real*8,dimension(:),allocatable :: x    ! coordenada X da malha no canto ne
real*8,dimension(:),allocatable :: y    ! coordenada Y da malha no canto ne
real*8,dimension(:),allocatable :: raio ! raio da malha no canto ne

real*8,dimension(:),allocatable :: xp   ! coordenada X da malha no centro do volume
real*8,dimension(:),allocatable :: yp   ! coordenada Y da malha no centro do volume
real*8,dimension(:),allocatable :: rp   ! raio da malha no centro do volume
real*8,dimension(:),allocatable :: Jp   ! Jacobiano no centro do volume

real*8,dimension(:),allocatable :: re    ! raio da malha no centro da face leste
real*8,dimension(:),allocatable :: xe    ! métrica xe da malha no centro da face leste
real*8,dimension(:),allocatable :: xke   ! métrica xk da malha no centro da face leste
real*8,dimension(:),allocatable :: ye    ! métrica ye da malha no centro da face leste
real*8,dimension(:),allocatable :: yke   ! métrica yk da malha no centro da face leste
real*8,dimension(:),allocatable :: Je    ! Jacobiano no centro da face leste
real*8,dimension(:),allocatable :: Alfae ! Alfa do tensor métrico no centro da face leste
real*8,dimension(:),allocatable :: Betae ! Beta do tensor métrico no centro da face leste

real*8,dimension(:),allocatable :: rn    ! raio da malha no centro da face norte
real*8,dimension(:),allocatable :: xk    ! métrica xk da malha no centro da face norte
real*8,dimension(:),allocatable :: xen   ! métrica xe da malha no centro da face norte
real*8,dimension(:),allocatable :: yk    ! métrica yk da malha no centro da face norte
real*8,dimension(:),allocatable :: yen   ! métrica ye da malha no centro da face norte
real*8,dimension(:),allocatable :: Jn    ! Jacobiano no centro da face norte
real*8,dimension(:),allocatable :: Gaman ! Gama do tensor métrico no centro da face norte
real*8,dimension(:),allocatable :: Betan ! Beta do tensor métrico no centro da face norte

real*8,dimension(:),allocatable :: T    ! temperatura no centro do volume

real*8,dimension(:),allocatable :: kp   ! condutividade térmica (k) no centro do volume
real*8,dimension(:),allocatable :: ke   ! k na face leste do volume
real*8,dimension(:),allocatable :: kn   ! k na face norte do volume

real*8,dimension(:),allocatable :: b    ! termo fonte de T

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

! *** variáveis com dimensão = nxy,9 ***

! primeiro índice = variável np
! segundo  índice = identificação do coeficiente:
!                   1=SW, 2=S, 3=SE, 4=W, 5=P, 6=E, 7=NW, 8=N, 9=NE

real*8,dimension(:,:),allocatable :: a ! coeficientes de T

! a(NP,1)*T(NPSW) + a(NP,2)*T(NPS) + a(NP,3)*T(NPSE) + a(NP,4)*T(NPW) +
! a(NP,5)*T(NP)   + a(NP,6)*T(NPE) + a(NP,7)*T(NPNW) + a(NP,8)*T(NPN) +
! a(NP,9)*T(NPNE) = b(NP)

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

! *** variáveis com dimensão = nxy,5 ***

real*8,dimension(:,:),allocatable :: dl9 ! coeficientes de a low no MSI
                                         ! de 9 diagonais

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

! *** variáveis com dimensão = nxy,4 ***

real*8,dimension(:,:),allocatable :: du9 ! coeficientes de a up no MSI
                                         ! de 9 diagonais

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

! *** variáveis auxiliares ***

integer       :: w_cam   ! =1, escreve campos;   =0, não
integer       :: w_r     ! freqüência de escrita dos resíduos e globais
integer       :: w_g     ! freqüência de escrita nos gráficos
integer       :: sem_a   ! 1=não abre arquivos; 0=abre
integer       :: sem_g   ! 1=não abre gráficos; 0=abre
integer       :: dos     ! acessa prompt dos
character*100 :: caso    ! nome do experimento numérico
character*100 :: arqd    ! nome do arquivo de dados
character*100 :: title   ! título do gráfico
character*100 :: hard    ! hardware
character*112 :: head    ! título do gráfico + dia
character*12  :: dia     ! data da simulação
character*8   :: hora    ! horário da simulação
character*120 :: nome    ! auxiliar
real*8        :: tcpu1   ! tempo de CPU inicial
real*8        :: tcpu2   ! tempo de CPU final
real*8        :: tcpu    ! tempo de CPU total acumulado
real*8        :: tcpuo   ! tempo de CPU de reinício
integer       :: ito     ! número da iteração inicial no tempo de reinício
real*8        :: pi      ! constante matemática pi
integer       :: k       ! auxiliar
real*8        :: hmedio  ! h médio em X (m)
!-------------------------------------------------

contains

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

  subroutine le_dados

    ! define se os arquivos de dados serão abertos
    open(7,file='Parede2D_1p1.in')
    read(7,*) sem_a
    close(7)

    ! lista arquivo com nome do arquivo de dados
    if ( sem_a == 0 ) dos = system('notepad Parede2D_1p1.ent')

    ! lê o nome genérico do arquivo de dados
    open(7,file='Parede2D_1p1.ent')
    read(7,*) arqd
    close(7)

    ! lista arquivo com os dados a usar
    if ( sem_a == 0 ) dos = system('notepad ' //trim(adjustl(arqd)) )

    ! lê os dados a usar
  	open(7,file=trim(adjustl(arqd)))

    read(7,*) caso
    read(7,*) coord
    read(7,*) nx
    read(7,*) ny
    read(7,*) grid
    read(7,*) ci
    read(7,*) tole
    read(7,*) itmax
    read(7,*) toli
    read(7,*) nitm
    read(7,*) w_cam
    read(7,*) w_r
    read(7,*) w_g
    read(7,*) sem_a
    read(7,*) sem_g
    read(7,*) hard
    read(7,*) title

    close(7)

    ! cálculo de dados secundários

    pi  = dacos(-1.0d0)

    nx  = nx + 2

    ny  = ny + 2

    nxy = nx * ny

    ito = 1

    tcpuo = 0.0d0

  end subroutine le_dados

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

  subroutine mostra_dados

    write(10,1) title, caso, coord, nx-2,  ny-2,  (nx-2)*(ny-2), &
                grid,  ci,   tole,  itmax, toli,  nitm,          &
                w_cam, w_r,  w_g,   sem_a, sem_g, hard

    1 format(/,'título = ',a,//, &
                  5x,'DADOS',//,  &
               'caso: nome do experimento numérico = ', a, //, &
              i8,12x,'   = coord: sistema de coordenadas: 0=plano; 1=axissimetrico',//, &
              i8,12x,'   = nx:    número de volumes reais na direção X',/, &
              i8,12x,'   = ny:    número de volumes reais na direção Y',/, &
              i8,12x,'   = nxy:   número total de volumes reais',//, &
              i8,12x,'   = grid:  tipo de malha: 1=uniforme por linha',/, &
              i8,12x,'   = ci:    tipo da condição inicial: 0=nula',/, &
             1pe22.9,' = tole: tolerância sobre as iterações externas (norma L1 adim.)',/, &
              i8,12x,'   = itmax: número máximo de iterações externas',/, &
             1pe22.9,' = toli: tolerância no MSI',/, &
              i8,12x,'   = nitm: número máximo de iterações internas no MSI',/, &
              i8,12x,'   = w_cam: =1, escreve campos;   =0, não',/, &
              i8,12x,'   = w_r:   freqüência de escrita dos resíduos e globais',/, &
              i8,12x,'   = w_g:   freqüência de escrita nos gráficos',/, &
              i8,12x,'   = sem_a: 1=não abre arquivos; 0=abre',/, &
              i8,12x,'   = sem_g: 1=não abre gráficos; 0=abre',//, &
              'hard: hardware = ', a )

  end subroutine mostra_dados

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

  subroutine aloca_memoria

    allocate ( x(nxy),   xp(nxy),    y(nxy),     yp(nxy)    )

    allocate ( rp(nxy),  re(nxy),    rn(nxy),    raio(nxy)  )

    allocate ( xe(nxy),  ye(nxy),    xk(nxy),    yk(nxy),   Jp(nxy) )

    allocate ( xke(nxy), yke(nxy),   xen(nxy),   yen(nxy)   )

    allocate ( Je(nxy),  Alfae(nxy), Betae(nxy)  )

    allocate ( Jn(nxy),  Gaman(nxy), Betan(nxy)  )

    allocate ( T(nxy) )

    allocate ( kp(nxy),  ke(nxy),    kn(nxy)     )

    allocate ( b(nxy) )

    allocate ( a(nxy,9), dl9(nxy,5), du9(nxy,4) )

    allocate ( Twc1D(nx), Twh1D(nx) )

  end subroutine aloca_memoria

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

  subroutine data_hora

    integer*4    :: var(8) ! data e hora
    character*20 :: vardate,vartime,varzone ! data e hora
    character*2  :: aux1,aux2
    character*4  :: aux3
    character*50 :: aux

    call date_and_time(vardate,vartime,varzone,var)

    write(aux,*) var(3)
    aux1 = trim(adjustl(aux))
    write(aux,*) var(2)
    aux2 = trim(adjustl(aux))
    write(aux,*) var(1)
    aux3 = trim(adjustl(aux))
    dia = '('//trim(aux1)//'/'//trim(aux2)//'/'//aux3//')'

    write(aux,*) var(5)
    aux1 = trim(adjustl(aux))
    write(aux,*) var(6)
    aux2 = trim(adjustl(aux))
    write(aux,*) var(7)
    aux3 = trim(adjustl(aux))
    hora = trim(aux1)//':'//trim(aux2)//':'//aux3

    write(10,18) dia, hora
    18 format(/,5x,'Dia = ',a12,5x,'Hora = ',a8)

    head = trim(title)//" "//trim(dia)//"'"

  end subroutine data_hora

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

end module dados
