!#########################################################################
!		
!    Copyright (C) 2003-2012 Department of Physics and Astronomy,
!                            University of Rochester,
!                            Rochester, NY
!
!    cooling.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/>.
!
!#########################################################################
!> @dir source
!! @brief directory containing modules for handling source terms

!> @file cooling.f90
!! @brief Cooling source terms ingroup

!! @file Source

!> Module for handling cooling source terms
MODULE CoolingSrc

   USE DataDeclarations
   USE PhysicsDeclarations
   USE EOS
   USE AnalyticCooling
   USE IICooling
   USE DMCooling
   USE ZCooling
   USE AlCooling

   IMPLICIT NONE
   PRIVATE
   PUBLIC Cooling, GetCoolingStrength, CoolingInit


CONTAINS



   ! ==================================================================
   ! =                Main Cooling Section                            =
   ! ==================================================================


   !> Main cooling subroutine, loops over linked list and calls specific cooling source(s)
   !! @params q variable vector q
   !! @params dqdt update to variable vector q
   !! @params x location of current cell center
   !! @params dx size of current cell
   SUBROUTINE Cooling(q,dqdt,ne,Temp)
      ! Interface declarations
      REAL(KIND=qPrec) :: q(:), dqdt(:), Temp, ne

      IF (Temp > FloorTemp) THEN      
         SELECT CASE(iCooling)
         CASE(NoCool)
            ! do nothing
         CASE(AnalyticCool)
            CALL Analytic_Cooling(q,dqdt,Temp)
         CASE(DMCool)
            CALL DM_Cooling(q,dqdt,ne,Temp)
         CASE(IICool)
            CALL II_Cooling(q,dqdt,Temp)
         CASE(ZCool)
            CALL Z_Cooling(q,dqdt,ne,Temp)
         CASE(AlCool)
            CALL Al_Cooling(q,dqdt,Temp)
         CASE DEFAULT
         END SELECT
      END IF
   END SUBROUTINE Cooling

   FUNCTION GetCoolingStrength(q)
      REAL(KIND=qPrec) :: q(:)
      REAL(KIND=qPrec) :: x(3),dx,GetCoolingStrength,Temp, ne
      ! Internal declarations
      GetCoolingStrength=0d0
      Temp=SourceTemperature(q)
      IF (Temp > FloorTemp) THEN
         SELECT CASE(iCooling)
         CASE(NoCool)
            ! do nothing
         CASE(AnalyticCool)
            GetCoolingStrength = AnalyticCoolingStrength(q,Temp)
         CASE(DMCool)
            ne=get_ne(q)    
            GetCoolingStrength = DMCoolingStrength(q,ne,Temp)
         CASE(IICool)
            GetCoolingStrength = IICoolingStrength(q,Temp)
         CASE(ZCool)
            ne=get_ne(q)    
            GetCoolingStrength = ZCoolingStrength(q,ne,Temp)
         CASE(AlCool)
            GetCoolingStrength = AlCoolingStrength(q,Temp)
         CASE DEFAULT
         END SELECT
      END IF
   END FUNCTION GetCoolingStrength


   !> Finalize initialization of cooling sources, including
   !!  allocating relevant tables
   SUBROUTINE CoolingInit
      SELECT CASE(iCooling)
      CASE(NoCool)
      CASE(AnalyticCool)
         CALL InitAnalyticCool
      CASE(DMCool)
         CALL InitDMCool
      CASE(IICool)
         CALL InitIICool
      CASE(ZCool)
         CALL InitZCool
      CASE(AlCool)
         CALL InitAlCool
      END SELECT
   END SUBROUTINE CoolingInit

END MODULE CoolingSrc
