!#########################################################################
!		
!    Copyright (C) 2003-2012 Department of Physics and Astronomy,
!                            University of Rochester,
!                            Rochester, NY
!
!    io_curve.f90 is part of AstroBEAR.
!
!    AstroBEAR is free software: you can redistribute it and/or modify	  
!    it under the terms of the GNU General Public License as published by 
!    the Free Software Foundation, either version 3 of the License, or    
!    (at your option) any later version.
!
!    AstroBEAR is distributed in the hope that it will be useful, 
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
!
!    You should have received a copy of the GNU General Public License
!    along with AstroBEAR.  If not, see <http://www.gnu.org/licenses/>.
!
!#########################################################################
!> @file io_curve.f90
!! @brief Main file for module IOCURVE

!> @defgroup IOCURVE IO CURVE
!! @brief Writes CURVE files for viewing data in visit (or gnuplot)
!! @ingroup IO

!> Writes CURVE files for viewing data in visit (or gnuplot)
!! @ingroup IOCURVE
MODULE IOCURVE
   USE GlobalDeclarations
   USE TreeDeclarations
   USE ProcessingDeclarations
   IMPLICIT NONE
CONTAINS



   SUBROUTINE WriteCurveData(name, lower, upper, tnow, data, varname)
      USE GlobalDeclarations
      CHARACTER(LEN=*) :: name
      CHARACTER(LEN=MAXFIELDSLENGTH), DIMENSION(:) :: varname
      CHARACTER(LEN=100) :: Filename
      REAL(KIND=qPREC) :: lower, upper, tnow, dx
      REAL(KIND=qPREC), DIMENSION(:,:) :: data
      INTEGER :: mx, i, j
      write(FileName,'(A4,A,A6)') 'out/',TRIM(name),".curve"
      OPEN(UNIT=CURVE_DATA_HANDLE, FILE=TRIM(FileName), status="replace")
      mx=size(data,1)
      dx=(upper-lower)/real(mx)
      DO j=1,size(data,2)
         write(CURVE_DATA_HANDLE, '(A2,A)') "# ", varname(j)
         DO i=1,mx
            write(CURVE_DATA_HANDLE, '(2E25.16)') lower+(real(i, qPREC)-half)*dx, data(i,j)
         END DO
         write(CURVE_DATA_HANDLE,*)
         write(CURVE_DATA_HANDLE,*)
      END DO
      CLOSE(CURVE_DATA_HANDLE)
   END SUBROUTINE WriteCurveData
   
   SUBROUTINE WriteCurveFile(nFrame)
      REAL(KIND=qPREC), DIMENSION(:,:), ALLOCATABLE :: data, totaldata
      REAL(KIND=qPREC), DIMENSION(:), ALLOCATABLE :: x
      INTEGER :: i,j, iErr, nFrame
      CHARACTER(LEN=21) :: filename
      TYPE(NodeDefList), POINTER :: nodelist
      TYPE(InfoDef), POINTER :: info
      TYPE(DiagnosticListDef), POINTER :: Diagnostic
      ALLOCATE(data(levels(0)%mX(1),NrVars+NrDiagnosticVars))
      ALLOCATE(totaldata(levels(0)%mX(1),NrVars+NrDiagnosticVars))
      data=0d0
      nodelist=>Nodes(0)%p
      DO WHILE (ASSOCIATED(nodelist))
         info=>nodelist%self%info
         data(Info%mBounds(1,1):Info%mBounds(1,2), 1:NrVars)=Info%q(1:Info%mX(1),1,1,1:NrVars)
         IF (NrDiagnosticVars > 0) THEN
            data(Info%mBounds(1,1):Info%mBounds(1,2), NrVars+1:NrVars+NrDiagnosticVars)=Info%diagnostics(1:Info%mX(1),1,1,1:NrDiagnosticVars)
            DEALLOCATE(Info%diagnostics)
         END IF
         nodelist=>nodelist%next
      END DO
#if defined _MPI
      CALL MPI_REDUCE(data, totaldata, size(data), MPI_REAL8, MPI_SUM, 0, MPI_COMM_WORLD, iErr)
#else
      totaldata=data
#endif
      IF (MPI_ID == 0) THEN
         write(filename, '(A10,I5.5,A6)') 'out/frame_', nFrame, '.curve'
         OPEN(UNIT=CURVE_DATA_HANDLE, FILE=filename, STATUS='UNKNOWN')
         ALLOCATE(x(levels(0)%mX(1)))
         x=GxBounds(1,1)+(REAL((/(i,i=1,levels(0)%mX(1))/),8)-half)*levels(0)%dx
         DO i=1, NrVars+NrDiagnosticVars
            IF (i <= NrCons) THEN
               write(CURVE_DATA_HANDLE, '(A2,A)')  '# ', trim(FieldName(i))
            ELSEIF (i <= NrCons+NrTracerVars) THEN
               write(CURVE_DATA_HANDLE, '(A2,A)')  '# ', trim(TracerName(i-NrCons))
            ELSEIF (i <= NrCons+NrTracerVars+NrEllipticVars) THEN
               write(CURVE_DATA_HANDLE, '(A2,A)')  '# ', trim(EllipticName(i-NrCons-NrTracerVars))       
            ELSE
               Diagnostic=>FirstDiagnostic
               j=NrCons+NrTracerVars+NrEllipticVars+1
               DO WHILE (ASSOCIATED(Diagnostic))
                  IF (j == i) write(CURVE_DATA_HANDLE, '(A2,A)')  '# ', trim(Diagnostic%Field%Name)
                  j=j+1
                  Diagnostic=>Diagnostic%next
               END DO
            END IF
            DO j=1,levels(0)%mX(1)
               write(CURVE_DATA_HANDLE, '(2E26.16)') x(j), totaldata(j,i)
            END DO
            write(CURVE_DATA_HANDLE, *)
            write(CURVE_DATA_HANDLE, *)
         END DO
         CLOSE(CURVE_DATA_HANDLE)
         DEALLOCATE(x,totaldata)
      END IF
      DEALLOCATE(data)
   END SUBROUTINE WriteCurveFile



END MODULE IOCURVE


