!----------------------- BEGIN globchem_main.f90 BEGIN -----------------------
! @file globchem_main.f90                                                     
! @author jlinford                                                            
! @date 2014-09-23 12:57:50.223647                                            
! @brief Fortran90 driver with plplot                                         
!                                                                             
! Fortran90 driver with plplot                                                
!                                                                             
! This file was generated by Kppa: http://www.paratools.com/Kppa              
!-----------------------------------------------------------------------------



PROGRAM main

    USE globchem_parameters
    USE globchem_integrate
    USE globchem_initialize
    USE globchem_driver_parameters
    USE globchem_monitor
    USE globchem_gcdata

    IMPLICIT NONE

    !---------------------------------------------------------------------------
    ! Lookat data                                                               
    !---------------------------------------------------------------------------
    
    INTEGER, PARAMETER :: lookatFile = 100
    CHARACTER(80), PARAMETER :: fname = "globchem.dat"
    

    !---------------------------------------------------------------------------
    ! Program data                                                               
    !---------------------------------------------------------------------------
    
    ! Integration status code 
    INTEGER :: retval
    ! Integration status code per timestep iteration 
    INTEGER :: tsretval
    ! Integration time 
    REAL(8) :: time

    ! Absolute integration tolerances for variable species 
    REAL(8) :: abstol(174)
    ! Relative integration tolerances for variable species 
    REAL(8) :: reltol(174)

    ! Integer integration in/out parameters 
    INTEGER :: idata(20)
    ! Real value integration in/out parameters 
    REAL(8) :: rdata(20)

    ! Species concentrations for all grid cells
    REAL(8), ALLOCATABLE :: conc(:,:)

    ! Last stepsize in each grid cell
    REAL(8), ALLOCATABLE :: lastH(:)
    
    ! Integrator statistics
    !INTEGER :: nFun = 0       ! Number of function evaluations
    !INTEGER :: nJac = 0       ! Number of Jacobian evaluations
    !INTEGER :: nStp = 0       ! Number of solver steps
    !INTEGER :: nAcc = 0       ! Number of accepted steps
    !INTEGER :: nRej = 0       ! Number of rejected steps
    !INTEGER :: nDec = 0       ! Number of matrix decompositions
    !INTEGER :: nSol = 0       ! Number of Ax=b solves
    !INTEGER :: nSng = 0       ! Number of singular decomposition results
    
    ! Iterator
    INTEGER :: i

    REAL(8) :: start, elapsed
    REAL(8) :: omp_get_wtime

    !---------------------------------------------------------------------------
    ! Program text                                                               
    !---------------------------------------------------------------------------

    call load_gc_data
    NCELLS = GC_NTT
    TSTART = 0.d0
    TEND = GC_DT

    WRITE(*,101) NCELLS,TSTART,TEND
101 FORMAT("Kppa: Integrating ",I8," grid cells, time interval [",E8.2,",",E8.2,"]")

    ! Initialize example grid data
    ALLOCATE(conc(NSPEC,NCELLS))
    DO i=1,ncells
        CALL Initialize(i, conc(1:NVAR,i), conc(NVAR+1:NSPEC,i))
    END DO
    
    ! Allocate storage for last step size (useful in reentrant solvers)
    ALLOCATE(lastH(ncells))

    ! Set time interval
    time = TSTART

    ! Initialize vector tolerances
    abstol = ATOLS
    reltol = RTOLS

    ! Initialize integration parameters to 0 = use defaults
    idata = 0
    rdata = 0

    ! Rosenbrock default parameters
    idata(1) = 1       ! Autonomous
    idata(2) = 0       ! Use vector tolerances
    idata(4) = 4       ! Rodas3 Rosenbrock method

    ! Initialize LookAt file
    OPEN(unit=lookatFile,file=fname)

    start = omp_get_wtime()

    ! Perform time integration
    retval = 0
    !DO WHILE (time < TEND)
        tsretval = GridIntegrate(NCELLS, conc, TSTART, TEND, &
                                 abstol, reltol, idata, rdata, lastH)

        ! Accumulate statistics
        !nStp = nStp + idata(13)
        !nAcc = nAcc + idata(14)
        !nRej = nRej + idata(15)
        !nSng = nSng + idata(18) 
        !nFun = nFun + idata(11)
        !nJac = nJac + idata(12)
        !nDec = nDec + idata(16)
        !nSol = nSol + idata(17)

        ! Update time
        !write (*,*) "Time=",time
        time = rdata(11)

        ! Write species concentrations to file
        !CALL LookAt(rdata(12), rdata(13))

        
        ! Process return code
        IF (tsretval < 0) THEN
            ! Error occured: save code and abort
            retval = MIN(retval, tsretval)
            !EXIT
        ELSE IF (tsretval > 0) THEN
            ! Warning occured: save code and continue
            IF (retval >= 0 .AND. retval < tsretval) THEN
                retval = tsretval;
            END IF
        END IF

        ! Use last integration step size as the starting step size
        rdata(3) = rdata(12)
    !END DO

    elapsed = omp_get_wtime() - start
    write (*,*) "Integration complete in",elapsed,"seconds"

    ! Report statistics                       
!    WRITE(*,102) nStp,nAcc,nRej,nSng,nFun,nJac,nDec,nSol
!102 FORMAT("Kppa: Stp=",I12,", Acc=",I12,", Rej=",I12,", Sng=",I12, &
!               ", Fun=",I12,", Jac=",I12,", Dec=",I12,", Sol=",I12)

    write (*,*) "Saving to output.dat"
    open(UNIT=100,FILE="output.dat")
    write (100,*) NCELLS,NVAR,NFIX
    do i=1,NCELLS
      write(100,*) conc(1:NSPEC,i)
    end do
    close(100)

    ! Clean up and exit
    !CLOSE(lookatFile)
    DEALLOCATE(conc)
    DEALLOCATE(lastH)
    !STOP




  CONTAINS

!----------------------------------- LookAt ----------------------------------
! Writes species concentrations to file                                       
!                                                                             
! @param[in]     step Last accepted integrator time step (H)                  
! @param[in]     err  Error in solution vector                                
!-----------------------------------------------------------------------------
  SUBROUTINE LookAt(step, err)
    IMPLICIT NONE

    REAL(8), INTENT(IN) :: step
    REAL(8), INTENT(IN) :: err

    REAL(8) :: data(3 + NLOOKAT)

    data(1) = time
    data(2) = step
    data(3) = err
    data(4) = conc(1, 1) / CFACTOR
    data(5) = conc(2, 1) / CFACTOR
    data(6) = conc(3, 1) / CFACTOR
    data(7) = conc(4, 1) / CFACTOR
    data(8) = conc(5, 1) / CFACTOR
    data(9) = conc(6, 1) / CFACTOR
    data(10) = conc(7, 1) / CFACTOR
    data(11) = conc(8, 1) / CFACTOR
    data(12) = conc(9, 1) / CFACTOR
    data(13) = conc(10, 1) / CFACTOR
    data(14) = conc(11, 1) / CFACTOR
    data(15) = conc(12, 1) / CFACTOR
    data(16) = conc(13, 1) / CFACTOR
    data(17) = conc(14, 1) / CFACTOR
    data(18) = conc(15, 1) / CFACTOR
    data(19) = conc(16, 1) / CFACTOR
    data(20) = conc(17, 1) / CFACTOR
    data(21) = conc(18, 1) / CFACTOR
    data(22) = conc(19, 1) / CFACTOR
    data(23) = conc(20, 1) / CFACTOR
    data(24) = conc(21, 1) / CFACTOR
    data(25) = conc(22, 1) / CFACTOR
    data(26) = conc(23, 1) / CFACTOR
    data(27) = conc(24, 1) / CFACTOR
    data(28) = conc(25, 1) / CFACTOR
    data(29) = conc(26, 1) / CFACTOR
    data(30) = conc(27, 1) / CFACTOR
    data(31) = conc(28, 1) / CFACTOR
    data(32) = conc(29, 1) / CFACTOR
    data(33) = conc(30, 1) / CFACTOR
    data(34) = conc(31, 1) / CFACTOR
    data(35) = conc(32, 1) / CFACTOR
    data(36) = conc(33, 1) / CFACTOR
    data(37) = conc(34, 1) / CFACTOR
    data(38) = conc(35, 1) / CFACTOR
    data(39) = conc(36, 1) / CFACTOR
    data(40) = conc(37, 1) / CFACTOR
    data(41) = conc(38, 1) / CFACTOR
    data(42) = conc(39, 1) / CFACTOR
    data(43) = conc(40, 1) / CFACTOR
    data(44) = conc(41, 1) / CFACTOR
    data(45) = conc(42, 1) / CFACTOR
    data(46) = conc(43, 1) / CFACTOR
    data(47) = conc(44, 1) / CFACTOR
    data(48) = conc(45, 1) / CFACTOR
    data(49) = conc(46, 1) / CFACTOR
    data(50) = conc(47, 1) / CFACTOR
    data(51) = conc(48, 1) / CFACTOR
    data(52) = conc(49, 1) / CFACTOR
    data(53) = conc(50, 1) / CFACTOR
    data(54) = conc(51, 1) / CFACTOR
    data(55) = conc(52, 1) / CFACTOR
    data(56) = conc(53, 1) / CFACTOR
    data(57) = conc(54, 1) / CFACTOR
    data(58) = conc(55, 1) / CFACTOR
    data(59) = conc(56, 1) / CFACTOR
    data(60) = conc(57, 1) / CFACTOR
    data(61) = conc(58, 1) / CFACTOR
    data(62) = conc(59, 1) / CFACTOR
    data(63) = conc(60, 1) / CFACTOR
    data(64) = conc(61, 1) / CFACTOR
    data(65) = conc(62, 1) / CFACTOR
    data(66) = conc(63, 1) / CFACTOR
    data(67) = conc(64, 1) / CFACTOR
    data(68) = conc(65, 1) / CFACTOR
    data(69) = conc(66, 1) / CFACTOR
    data(70) = conc(67, 1) / CFACTOR
    data(71) = conc(68, 1) / CFACTOR
    data(72) = conc(69, 1) / CFACTOR
    data(73) = conc(70, 1) / CFACTOR
    data(74) = conc(71, 1) / CFACTOR
    data(75) = conc(72, 1) / CFACTOR
    data(76) = conc(73, 1) / CFACTOR
    data(77) = conc(74, 1) / CFACTOR
    data(78) = conc(75, 1) / CFACTOR
    data(79) = conc(76, 1) / CFACTOR
    data(80) = conc(77, 1) / CFACTOR
    data(81) = conc(78, 1) / CFACTOR
    data(82) = conc(79, 1) / CFACTOR
    data(83) = conc(80, 1) / CFACTOR
    data(84) = conc(81, 1) / CFACTOR
    data(85) = conc(82, 1) / CFACTOR
    data(86) = conc(83, 1) / CFACTOR
    data(87) = conc(84, 1) / CFACTOR
    data(88) = conc(85, 1) / CFACTOR
    data(89) = conc(86, 1) / CFACTOR
    data(90) = conc(87, 1) / CFACTOR
    data(91) = conc(88, 1) / CFACTOR
    data(92) = conc(89, 1) / CFACTOR
    data(93) = conc(90, 1) / CFACTOR
    data(94) = conc(91, 1) / CFACTOR
    data(95) = conc(92, 1) / CFACTOR
    data(96) = conc(93, 1) / CFACTOR
    data(97) = conc(94, 1) / CFACTOR
    data(98) = conc(95, 1) / CFACTOR
    data(99) = conc(96, 1) / CFACTOR
    data(100) = conc(97, 1) / CFACTOR
    data(101) = conc(98, 1) / CFACTOR
    data(102) = conc(99, 1) / CFACTOR
    data(103) = conc(100, 1) / CFACTOR
    data(104) = conc(101, 1) / CFACTOR
    data(105) = conc(102, 1) / CFACTOR
    data(106) = conc(103, 1) / CFACTOR
    data(107) = conc(104, 1) / CFACTOR
    data(108) = conc(105, 1) / CFACTOR
    data(109) = conc(106, 1) / CFACTOR
    data(110) = conc(107, 1) / CFACTOR
    data(111) = conc(108, 1) / CFACTOR
    data(112) = conc(109, 1) / CFACTOR
    data(113) = conc(110, 1) / CFACTOR
    data(114) = conc(111, 1) / CFACTOR
    data(115) = conc(112, 1) / CFACTOR
    data(116) = conc(113, 1) / CFACTOR
    data(117) = conc(114, 1) / CFACTOR
    data(118) = conc(115, 1) / CFACTOR
    data(119) = conc(116, 1) / CFACTOR
    data(120) = conc(117, 1) / CFACTOR
    data(121) = conc(118, 1) / CFACTOR
    data(122) = conc(119, 1) / CFACTOR
    data(123) = conc(120, 1) / CFACTOR
    data(124) = conc(121, 1) / CFACTOR
    data(125) = conc(122, 1) / CFACTOR
    data(126) = conc(123, 1) / CFACTOR
    data(127) = conc(124, 1) / CFACTOR
    data(128) = conc(125, 1) / CFACTOR
    data(129) = conc(126, 1) / CFACTOR
    data(130) = conc(127, 1) / CFACTOR
    data(131) = conc(128, 1) / CFACTOR
    data(132) = conc(129, 1) / CFACTOR
    data(133) = conc(130, 1) / CFACTOR
    data(134) = conc(131, 1) / CFACTOR
    data(135) = conc(132, 1) / CFACTOR
    data(136) = conc(133, 1) / CFACTOR
    data(137) = conc(134, 1) / CFACTOR
    data(138) = conc(135, 1) / CFACTOR
    data(139) = conc(136, 1) / CFACTOR
    data(140) = conc(137, 1) / CFACTOR
    data(141) = conc(138, 1) / CFACTOR
    data(142) = conc(139, 1) / CFACTOR
    data(143) = conc(140, 1) / CFACTOR
    data(144) = conc(141, 1) / CFACTOR
    data(145) = conc(142, 1) / CFACTOR
    data(146) = conc(143, 1) / CFACTOR
    data(147) = conc(144, 1) / CFACTOR
    data(148) = conc(145, 1) / CFACTOR
    data(149) = conc(146, 1) / CFACTOR
    data(150) = conc(147, 1) / CFACTOR
    data(151) = conc(148, 1) / CFACTOR
    data(152) = conc(149, 1) / CFACTOR
    data(153) = conc(150, 1) / CFACTOR
    data(154) = conc(151, 1) / CFACTOR
    data(155) = conc(152, 1) / CFACTOR
    data(156) = conc(153, 1) / CFACTOR
    data(157) = conc(154, 1) / CFACTOR
    data(158) = conc(155, 1) / CFACTOR
    data(159) = conc(156, 1) / CFACTOR
    data(160) = conc(157, 1) / CFACTOR
    data(161) = conc(158, 1) / CFACTOR
    data(162) = conc(159, 1) / CFACTOR
    data(163) = conc(160, 1) / CFACTOR
    data(164) = conc(161, 1) / CFACTOR
    data(165) = conc(162, 1) / CFACTOR
    data(166) = conc(163, 1) / CFACTOR
    data(167) = conc(164, 1) / CFACTOR
    data(168) = conc(165, 1) / CFACTOR
    data(169) = conc(166, 1) / CFACTOR
    data(170) = conc(167, 1) / CFACTOR
    data(171) = conc(168, 1) / CFACTOR
    data(172) = conc(169, 1) / CFACTOR
    data(173) = conc(170, 1) / CFACTOR
    data(174) = conc(171, 1) / CFACTOR
    data(175) = conc(172, 1) / CFACTOR
    data(176) = conc(173, 1) / CFACTOR
    data(177) = conc(174, 1) / CFACTOR
    data(178) = conc(175, 1) / CFACTOR
    data(179) = conc(176, 1) / CFACTOR
    data(180) = conc(177, 1) / CFACTOR
    data(181) = conc(178, 1) / CFACTOR
    data(182) = conc(179, 1) / CFACTOR
    data(183) = conc(180, 1) / CFACTOR
    data(184) = conc(181, 1) / CFACTOR
    data(185) = conc(182, 1) / CFACTOR
    data(186) = conc(183, 1) / CFACTOR
    data(187) = conc(184, 1) / CFACTOR
    WRITE(lookatFile,*) data
  END SUBROUTINE LookAt



END PROGRAM main


!------------------------- END globchem_main.f90 END -------------------------
