!--------------------- BEGIN globchem_integrate.f90 BEGIN --------------------
! @file globchem_integrate.f90                                                
! @author jlinford                                                            
! @date 2014-09-23 10:48:06.388139                                            
! @brief Interface to time stepping integrator                                
!                                                                             
! Definitions of interface functions for the Kppa-generated                   
! time stepping integrator.  These are the Kppa "entry point" routines.       
!                                                                             
! This file was generated by Kppa: http://www.paratools.com/Kppa              
!-----------------------------------------------------------------------------


MODULE globchem_integrate

  USE globchem_parameters
  USE globchem_rosenbrock

  IMPLICIT NONE




  CONTAINS

!------------------------------- GridIntegrate -------------------------------
! Applies the Kppa-generated integrator to the grid                           
!                                                                             
! @param[in]     ncells Number of grid cells                                  
! @param[in,out] conc   Species concentrations                                
! @param[in]     tstart Integration start time                                
! @param[in]     tend   Integration end time                                  
! @param[in]     abstol Absolute integration tolerances for variable species  
! @param[in]     reltol Relative integration tolerances for variable species  
! @param[in,out] idata  Integer integration in/out parameters                 
! @param[in,out] rdata  Real value integration in/out parameters              
! @param[out]    lastH  Last timestep in each grid cell                       
!-----------------------------------------------------------------------------
  INTEGER FUNCTION GridIntegrate(ncells, conc, tstart, tend, abstol, reltol, &
      idata, rdata, lastH)
    IMPLICIT NONE

    INTEGER, INTENT(IN) :: ncells
    REAL(8), INTENT(INOUT) :: conc(NSPEC*ncells)
    REAL(8), INTENT(IN) :: tstart
    REAL(8), INTENT(IN) :: tend
    REAL(8), INTENT(IN) :: abstol(NVAR)
    REAL(8), INTENT(IN) :: reltol(NVAR)
    INTEGER, INTENT(INOUT) :: idata(20)
    REAL(8), INTENT(INOUT) :: rdata(20)
    REAL(8), INTENT(OUT) :: lastH(ncells)

    INTEGER :: tid, nthreads
    INTEGER :: omp_get_thread_num, omp_get_num_threads

    ! Return value 
    INTEGER :: retval
    
        INTEGER :: i
        INTEGER :: var
        INTEGER :: fix

102 FORMAT(I2,": Kppa(",I6,"): Stp=",I12,", Acc=",I12,", Rej=",I12,", Sng=",I12, &
               ", Fun=",I12,", Jac=",I12,", Dec=",I12,", Sol=",I12)

        retval = 0

!$OMP  PARALLEL &
!$OMP& DEFAULT(SHARED) &
!$OMP& PRIVATE(i,var,fix,tid,nthreads)
    
    tid = omp_get_thread_num()
    nthreads = omp_get_num_threads()

!$OMP  DO & 
!$OMP& FIRSTPRIVATE(idata, rdata) &
!$OMP& REDUCTION(IOR:retval)
        DO i = 1, ncells
            var = (i-1)*NSPEC + 1
            fix = var + NVAR

            ! Invoke the integrator
            CALL Integrate(conc(var), conc(fix), i, tstart, tend, &
                           abstol, reltol, idata, rdata)
    
            ! Save the last timestep for future use
            lastH(i) = rdata(12)

            !if (tid == 0) then
            !  WRITE(*,102) tid,i,idata(13),idata(14),idata(15),idata(18), &
            !               idata(11),idata(12),idata(16),idata(17)
            !end if
            ! Process integrator return code
            IF (idata(20) < 0) THEN
                WRITE(*,*) "Kppa: CELL",i,"-- INTEGRATION FAILED"
                WRITE(*,*) "Kppa: CELL",i,"idata=",idata
                WRITE(*,*) "Kppa: CELL",i,"rdata=",rdata
                retval = MIN(idata(20), retval)
            ELSE IF (idata(20) > 0) THEN
                WRITE(*,*) "Kppa: CELL",i,"-- INTEGRATION COMPLETED WITH WARNING"
                IF (retval >= 0 .AND. idata(20) > retval) THEN
                    retval = idata(20)
                END IF
            END IF
        END DO
!$OMP END DO

        !write (*,*) tid,": GridIntegrate=================================="
        !write (*,*) idata,rdata

!$OMP END PARALLEL

    GridIntegrate = retval
    RETURN
  END FUNCTION GridIntegrate


END MODULE globchem_integrate
!----------------------- END globchem_integrate.f90 END ----------------------
