# 1 "../sat_vapor_pres/sat_vapor_pres_k.F90" !*********************************************************************** !* GNU Lesser General Public License !* !* This file is part of the GFDL Flexible Modeling System (FMS). !* !* FMS is free software: you can redistribute it and/or modify it under !* the terms of the GNU Lesser General Public License as published by !* the Free Software Foundation, either version 3 of the License, or (at !* your option) any later version. !* !* FMS 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 Lesser General Public !* License along with FMS. If not, see . !*********************************************************************** module sat_vapor_pres_k_mod ! This module is what I (pjp) think a kernel should be. ! There have been many proposals as to what a kernel should look like. ! If fact, so many different ideas have been expressed that the lack ! of agreement has greatly hampered progress. ! The only way to move forward is to limit the requirments for a kernel ! to only what is widely agreeded upon. ! I believe that there are only two things widely agreeded upon. ! 1) A kernel should be independent of the rest of FMS so that it can ! easily be ported into another programming system. ! This requires that a kernel does not access anything by use association. ! The one exception is this kernel, because it is not practical for physics ! modules to avoid using a module that computes the saturation vapor ! pressure of water vapor. ! 2) For the sake of thread safety, module globals should be written only at initialization. ! In this case, the module globals are the tables and a handful of scalars. ! 3) A kernel should not read from an external file. ! One of the things that was not widely agreeded upon is that a kernel should ! not be a fortran module. This complicates things greatly for questionable ! benefit and could be done as a second step anyway, if necessary. implicit none private ! Include variable "version" to be written to log file. # 1 "../include/file_version.h" 1 ! -*-f90-*- !*********************************************************************** !* GNU Lesser General Public License !* !* This file is part of the GFDL Flexible Modeling System (FMS). !* !* FMS is free software: you can redistribute it and/or modify it under !* the terms of the GNU Lesser General Public License as published by !* the Free Software Foundation, either version 3 of the License, or (at !* your option) any later version. !* !* FMS 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 Lesser General Public !* License along with FMS. If not, see . !*********************************************************************** # 23 character(len=*), parameter :: version = 'unknown' # 51 "../sat_vapor_pres/sat_vapor_pres_k.F90" 2 public :: sat_vapor_pres_init_k public :: lookup_es_k public :: lookup_des_k public :: lookup_es_des_k public :: lookup_es2_k public :: lookup_des2_k public :: lookup_es2_des2_k public :: lookup_es3_k public :: lookup_des3_k public :: lookup_es3_des3_k public :: compute_qs_k public :: compute_mrs_k interface lookup_es_k module procedure lookup_es_k_0d module procedure lookup_es_k_1d module procedure lookup_es_k_2d module procedure lookup_es_k_3d end interface interface lookup_des_k module procedure lookup_des_k_0d module procedure lookup_des_k_1d module procedure lookup_des_k_2d module procedure lookup_des_k_3d end interface interface lookup_es_des_k module procedure lookup_es_des_k_0d module procedure lookup_es_des_k_1d module procedure lookup_es_des_k_2d module procedure lookup_es_des_k_3d end interface interface lookup_es2_k module procedure lookup_es2_k_0d module procedure lookup_es2_k_1d module procedure lookup_es2_k_2d module procedure lookup_es2_k_3d end interface interface lookup_des2_k module procedure lookup_des2_k_0d module procedure lookup_des2_k_1d module procedure lookup_des2_k_2d module procedure lookup_des2_k_3d end interface interface lookup_es2_des2_k module procedure lookup_es2_des2_k_0d module procedure lookup_es2_des2_k_1d module procedure lookup_es2_des2_k_2d module procedure lookup_es2_des2_k_3d end interface interface lookup_es3_k module procedure lookup_es3_k_0d module procedure lookup_es3_k_1d module procedure lookup_es3_k_2d module procedure lookup_es3_k_3d end interface interface lookup_des3_k module procedure lookup_des3_k_0d module procedure lookup_des3_k_1d module procedure lookup_des3_k_2d module procedure lookup_des3_k_3d end interface interface lookup_es3_des3_k module procedure lookup_es3_des3_k_0d module procedure lookup_es3_des3_k_1d module procedure lookup_es3_des3_k_2d module procedure lookup_es3_des3_k_3d end interface interface compute_qs_k module procedure compute_qs_k_0d module procedure compute_qs_k_1d module procedure compute_qs_k_2d module procedure compute_qs_k_3d end interface interface compute_mrs_k module procedure compute_mrs_k_0d module procedure compute_mrs_k_1d module procedure compute_mrs_k_2d module procedure compute_mrs_k_3d end interface real :: dtres, tepsl, tminl, dtinvl integer :: table_siz real, dimension(:), allocatable :: TABLE ! sat vapor pres (es) real, dimension(:), allocatable :: DTABLE ! first derivative of es real, dimension(:), allocatable :: D2TABLE ! second derivative of es real, dimension(:), allocatable :: TABLE2 ! sat vapor pres (es) real, dimension(:), allocatable :: DTABLE2 ! first derivative of es real, dimension(:), allocatable :: D2TABLE2 ! second derivative of es real, dimension(:), allocatable :: TABLE3 ! sat vapor pres (es) real, dimension(:), allocatable :: DTABLE3 ! first derivative of es real, dimension(:), allocatable :: D2TABLE3 ! second derivative of es logical :: use_exact_qs logical :: module_is_initialized = .false. contains subroutine sat_vapor_pres_init_k(table_size, tcmin, tcmax, TFREEZE, HLV, RVGAS, ES0, err_msg, & use_exact_qs_input, do_simple, & construct_table_wrt_liq, & construct_table_wrt_liq_and_ice, & teps, tmin, dtinv) ! This routine has been generalized to return tables for any temperature range and resolution integer, intent(in) :: table_size real, intent(in) :: tcmin ! TABLE(1) = sat vapor pressure at temperature tcmin (deg C) real, intent(in) :: tcmax ! TABLE(table_size) = sat vapor pressure at temperature tcmax (deg C) real, intent(in) :: TFREEZE, HLV, RVGAS, ES0 logical, intent(in) :: use_exact_qs_input, do_simple logical, intent(in) :: construct_table_wrt_liq logical, intent(in) :: construct_table_wrt_liq_and_ice character(len=*), intent(out) :: err_msg real, intent(out), optional :: teps, tmin, dtinv ! increment used to generate derivative table real, dimension(3) :: tem(3), es(3) real :: hdtinv, tinrc, tfact integer :: i err_msg = '' if (module_is_initialized) return if(allocated(TABLE) .or. allocated(DTABLE) .or. allocated(D2TABLE)) then err_msg = 'Attempt to allocate sat vapor pressure tables when already allocated' return else allocate(TABLE(table_size), DTABLE(table_size), D2TABLE(table_size)) endif if (construct_table_wrt_liq) then if(allocated(TABLE2) .or. allocated(DTABLE2) .or. allocated(D2TABLE2)) then err_msg = 'Attempt to allocate sat vapor pressure table2s when already allocated' return else allocate(TABLE2(table_size), DTABLE2(table_size), D2TABLE2(table_size)) endif endif if (construct_table_wrt_liq_and_ice) then if(allocated(TABLE3) .or. allocated(DTABLE3) .or. allocated(D2TABLE3)) then err_msg = 'Attempt to allocate sat vapor pressure table2s when already allocated' return else allocate(TABLE3(table_size), DTABLE3(table_size), D2TABLE3(table_size)) endif endif table_siz = table_size dtres = (tcmax - tcmin)/real(table_size-1) tminl = real(tcmin)+TFREEZE ! minimum valid temp in table dtinvl = 1./dtres tepsl = .5*dtres tinrc = .1*dtres if(present(teps )) teps =tepsl if(present(tmin )) tmin =tminl if(present(dtinv)) dtinv=dtinvl ! To be able to compute tables for any temperature range and resolution, ! and at the same time exactly reproduce answers from memphis revision, ! it is necessary to compute ftact differently than it is in memphis. tfact = 5.0*dtinvl hdtinv = dtinvl*0.5 ! compute es tables from tcmin to tcmax ! estimate es derivative with small +/- difference if (do_simple) then do i = 1, table_size tem(1) = tminl + dtres*real(i-1) TABLE(i) = ES0*610.78*exp(-hlv/rvgas*(1./tem(1) - 1./tfreeze)) DTABLE(i) = hlv*TABLE(i)/rvgas/tem(1)**2. enddo else do i = 1, table_size tem(1) = tminl + dtres*real(i-1) tem(2) = tem(1)-tinrc tem(3) = tem(1)+tinrc es = compute_es_k (tem, TFREEZE) TABLE(i) = es(1) DTABLE(i) = (es(3)-es(2))*tfact enddo endif !if (do_simple) ! compute one-half second derivative using centered differences ! differencing des values in the table do i = 2, table_size-1 D2TABLE(i) = 0.25*dtinvl*(DTABLE(i+1)-DTABLE(i-1)) enddo ! one-sided derivatives at boundaries D2TABLE(1) = 0.50*dtinvl*(DTABLE(2)-DTABLE(1)) D2TABLE(table_size) = 0.50*dtinvl*& (DTABLE(table_size)-DTABLE(table_size-1)) if (construct_table_wrt_liq) then ! compute es tables from tcmin to tcmax ! estimate es derivative with small +/- difference do i = 1, table_size tem(1) = tminl + dtres*real(i-1) tem(2) = tem(1)-tinrc tem(3) = tem(1)+tinrc ! pass in flag to force all values to be wrt liquid es = compute_es_liq_k (tem, TFREEZE) TABLE2(i) = es(1) DTABLE2(i) = (es(3)-es(2))*tfact enddo ! compute one-half second derivative using centered differences ! differencing des values in the table do i = 2, table_size-1 D2TABLE2(i) = 0.25*dtinvl*(DTABLE2(i+1)-DTABLE2(i-1)) enddo ! one-sided derivatives at boundaries D2TABLE2(1) = 0.50*dtinvl*(DTABLE2(2)-DTABLE2(1)) D2TABLE2(table_size) = 0.50*dtinvl*& (DTABLE2(table_size)-DTABLE2(table_size-1)) endif if (construct_table_wrt_liq_and_ice) then ! compute es tables from tcmin to tcmax ! estimate es derivative with small +/- difference do i = 1, table_size tem(1) = tminl + dtres*real(i-1) tem(2) = tem(1)-tinrc tem(3) = tem(1)+tinrc ! pass in flag to force all values to be wrt liquid es = compute_es_liq_ice_k (tem, TFREEZE) TABLE3(i) = es(1) DTABLE3(i) = (es(3)-es(2))*tfact enddo ! compute one-half second derivative using centered differences ! differencing des values in the table do i = 2, table_size-1 D2TABLE3(i) = 0.25*dtinvl*(DTABLE3(i+1)-DTABLE3(i-1)) enddo ! one-sided derivatives at boundaries D2TABLE3(1) = 0.50*dtinvl*(DTABLE3(2)-DTABLE3(1)) D2TABLE3(table_size) = 0.50*dtinvl*& (DTABLE3(table_size)-DTABLE3(table_size-1)) endif use_exact_qs = use_exact_qs_input module_is_initialized = .true. end subroutine sat_vapor_pres_init_k !####################################################################### function compute_es_k(tem, TFREEZE) result (es) real, intent(in) :: tem(:), TFREEZE real :: es(size(tem,1)) real :: x, esice, esh2o, TBASW, TBASI integer :: i real, parameter :: ESBASW = 101324.60 real, parameter :: ESBASI = 610.71 TBASW = TFREEZE+100. TBASI = TFREEZE do i = 1, size(tem) ! compute es over ice if (tem(i) < TBASI) then x = -9.09718*(TBASI/tem(i)-1.0) - 3.56654*log10(TBASI/tem(i)) & +0.876793*(1.0-tem(i)/TBASI) + log10(ESBASI) esice =10.**(x) else esice = 0. endif ! compute es over water greater than -20 c. ! values over 100 c may not be valid ! see smithsonian meteorological tables page 350. if (tem(i) > -20.+TBASI) then x = -7.90298*(TBASW/tem(i)-1.0) + 5.02808*log10(TBASW/tem(i)) & -1.3816e-07*(10.0**((1.0-tem(i)/TBASW)*11.344)-1.0) & +8.1328e-03*(10.0**((TBASW/tem(i)-1.0)*(-3.49149))-1.0) & +log10(ESBASW) esh2o = 10.**(x) else esh2o = 0. endif ! derive blended es over ice and supercooled water between -20c and 0c if (tem(i) <= -20.+TBASI) then es(i) = esice else if (tem(i) >= TBASI) then es(i) = esh2o else es(i) = 0.05*((TBASI-tem(i))*esice + (tem(i)-TBASI+20.)*esh2o) endif enddo end function compute_es_k !####################################################################### function compute_es_liq_k(tem, TFREEZE) result (es) real, intent(in) :: tem(:), TFREEZE real :: es(size(tem,1)) real :: x, esh2o, TBASW integer :: i real, parameter :: ESBASW = 101324.60 TBASW = TFREEZE+100. do i = 1, size(tem) ! compute es over water for all temps. ! values over 100 c may not be valid ! see smithsonian meteorological tables page 350. x = -7.90298*(TBASW/tem(i)-1.0) + 5.02808*log10(TBASW/tem(i)) & -1.3816e-07*(10.0**((1.0-tem(i)/TBASW)*11.344)-1.0) & +8.1328e-03*(10.0**((TBASW/tem(i)-1.0)*(-3.49149))-1.0) & +log10(ESBASW) esh2o = 10.**(x) es(i) = esh2o enddo end function compute_es_liq_k !####################################################################### function compute_es_liq_ice_k(tem, TFREEZE) result (es) real, intent(in) :: tem(:), TFREEZE real :: es(size(tem,1)) real :: x, TBASW, TBASI integer :: i real, parameter :: ESBASW = 101324.60 real, parameter :: ESBASI = 610.71 TBASW = TFREEZE+100. TBASI = TFREEZE do i = 1, size(tem) if (tem(i) < TBASI) then ! compute es over ice x = -9.09718*(TBASI/tem(i)-1.0) - 3.56654*log10(TBASI/tem(i)) & +0.876793*(1.0-tem(i)/TBASI) + log10(ESBASI) es(i) =10.**(x) else ! compute es over water ! values over 100 c may not be valid ! see smithsonian meteorological tables page 350. x = -7.90298*(TBASW/tem(i)-1.0) + 5.02808*log10(TBASW/tem(i)) & -1.3816e-07*(10.0**((1.0-tem(i)/TBASW)*11.344)-1.0) & +8.1328e-03*(10.0**((TBASW/tem(i)-1.0)*(-3.49149))-1.0) & +log10(ESBASW) es(i) = 10.**(x) endif enddo end function compute_es_liq_ice_k !####################################################################### subroutine compute_qs_k_3d (temp, press, eps, zvir, qs, nbad, q, hc, & dqsdT, esat, es_over_liq, es_over_liq_and_ice) real, intent(in), dimension(:,:,:) :: temp, press real, intent(in) :: eps, zvir real, intent(out), dimension(:,:,:) :: qs integer, intent(out) :: nbad real, intent(in), dimension(:,:,:), optional :: q real, intent(in), optional :: hc real, intent(out), dimension(:,:,:), optional :: dqsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real, dimension(size(temp,1), size(temp,2), size(temp,3)) :: & esloc, desat, denom integer :: i, j, k real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present(es_over_liq)) then if (present (dqsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dqsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dqsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (q) .and. use_exact_qs) then qs = (1.0 + zvir*q)*eps*esloc/press if (present (dqsdT)) then dqsdT = (1.0 + zvir*q)*eps*desat/press endif else ! (present(q)) denom = press - (1.0 - eps)*esloc do k=1,size(qs,3) do j=1,size(qs,2) do i=1,size(qs,1) if (denom(i,j,k) > 0.0) then qs(i,j,k) = eps*esloc(i,j,k)/denom(i,j,k) else qs(i,j,k) = eps endif end do end do end do if (present (dqsdT)) then dqsdT = eps*press*desat/denom**2 endif endif ! (present(q)) else ! (nbad = 0) qs = -999. if (present (dqsdT)) then dqsdT = -999. endif if (present (esat)) then esat = -999. endif endif ! (nbad = 0) end subroutine compute_qs_k_3d !####################################################################### subroutine compute_qs_k_2d (temp, press, eps, zvir, qs, nbad, q, hc, & dqsdT, esat, es_over_liq, es_over_liq_and_ice) real, intent(in), dimension(:,:) :: temp, press real, intent(in) :: eps, zvir real, intent(out), dimension(:,:) :: qs integer, intent(out) :: nbad real, intent(in), dimension(:,:), optional :: q real, intent(in), optional :: hc real, intent(out), dimension(:,:), optional :: dqsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real, dimension(size(temp,1), size(temp,2)) :: esloc, desat, denom integer :: i, j real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present(es_over_liq)) then if (present (dqsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dqsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dqsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (q) .and. use_exact_qs) then qs = (1.0 + zvir*q)*eps*esloc/press if (present (dqsdT)) then dqsdT = (1.0 + zvir*q)*eps*desat/press endif else ! (present(q)) denom = press - (1.0 - eps)*esloc do j=1,size(qs,2) do i=1,size(qs,1) if (denom(i,j) > 0.0) then qs(i,j) = eps*esloc(i,j)/denom(i,j) else qs(i,j) = eps endif end do end do if (present (dqsdT)) then dqsdT = eps*press*desat/denom**2 endif endif ! (present(q)) else ! (nbad = 0) qs = -999. if (present (dqsdT)) then dqsdT = -999. endif if (present (esat)) then esat = -999. endif endif ! (nbad = 0) end subroutine compute_qs_k_2d !####################################################################### subroutine compute_qs_k_1d (temp, press, eps, zvir, qs, nbad, q, hc, & dqsdT, esat, es_over_liq, es_over_liq_and_ice) real, intent(in), dimension(:) :: temp, press real, intent(in) :: eps, zvir real, intent(out), dimension(:) :: qs integer, intent(out) :: nbad real, intent(in), dimension(:), optional :: q real, intent(in), optional :: hc real, intent(out), dimension(:), optional :: dqsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real, dimension(size(temp,1)) :: esloc, desat, denom integer :: i real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present(es_over_liq)) then if (present (dqsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dqsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dqsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (q) .and. use_exact_qs) then qs = (1.0 + zvir*q)*eps*esloc/press if (present (dqsdT)) then dqsdT = (1.0 + zvir*q)*eps*desat/press endif else ! (present(q)) denom = press - (1.0 - eps)*esloc do i=1,size(qs,1) if (denom(i) > 0.0) then qs(i) = eps*esloc(i)/denom(i) else qs(i) = eps endif end do if (present (dqsdT)) then dqsdT = eps*press*desat/denom**2 endif endif ! (present(q)) else ! (nbad = 0) qs = -999. if (present (dqsdT)) then dqsdT = -999. endif if (present (esat)) then esat = -999. endif endif ! (nbad = 0) end subroutine compute_qs_k_1d !####################################################################### subroutine compute_qs_k_0d (temp, press, eps, zvir, qs, nbad, q, hc, & dqsdT, esat, es_over_liq, es_over_liq_and_ice) real, intent(in) :: temp, press real, intent(in) :: eps, zvir real, intent(out) :: qs integer, intent(out) :: nbad real, intent(in), optional :: q real, intent(in), optional :: hc real, intent(out), optional :: dqsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real :: esloc, desat, denom real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present(es_over_liq)) then if (present (dqsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dqsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dqsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (q) .and. use_exact_qs) then qs = (1.0 + zvir*q)*eps*esloc/press if (present (dqsdT)) then dqsdT = (1.0 + zvir*q)*eps*desat/press endif else ! (present(q)) denom = press - (1.0 - eps)*esloc if (denom > 0.0) then qs = eps*esloc/denom else qs = eps endif if (present (dqsdT)) then dqsdT = eps*press*desat/denom**2 endif endif ! (present(q)) else ! (nbad = 0) qs = -999. if (present (dqsdT)) then dqsdT = -999. endif if (present (esat)) then esat = -999. endif endif ! (nbad = 0) end subroutine compute_qs_k_0d !####################################################################### !####################################################################### subroutine compute_mrs_k_3d (temp, press, eps, zvir, mrs, nbad, & mr, hc, dmrsdT, esat,es_over_liq, es_over_liq_and_ice) real, intent(in), dimension(:,:,:) :: temp, press real, intent(in) :: eps, zvir real, intent(out), dimension(:,:,:) :: mrs integer, intent(out) :: nbad real, intent(in), dimension(:,:,:), optional :: mr real, intent(in), optional :: hc real, intent(out), dimension(:,:,:), optional :: dmrsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real, dimension(size(temp,1), size(temp,2), size(temp,3)) :: & esloc, desat, denom integer :: i, j, k real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present (es_over_liq)) then if (present (dmrsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dmrsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dmrsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (mr) .and. use_exact_qs) then mrs = (eps + mr)*esloc/press if (present (dmrsdT)) then dmrsdT = (eps + mr)*desat/press endif else ! (present (mr)) denom = press - esloc do k=1,size(mrs,3) do j=1,size(mrs,2) do i=1,size(mrs,1) if (denom(i,j,k) > 0.0) then mrs(i,j,k) = eps*esloc(i,j,k)/denom(i,j,k) else mrs(i,j,k) = eps endif end do end do end do if (present (dmrsdT)) then dmrsdT = eps*press*desat/denom**2 endif endif !(present (mr)) else mrs = -999. if (present (dmrsdT)) then dmrsdT = -999. endif if (present (esat)) then esat = -999. endif endif end subroutine compute_mrs_k_3d !####################################################################### subroutine compute_mrs_k_2d (temp, press, eps, zvir, mrs, nbad, & mr, hc, dmrsdT, esat,es_over_liq, es_over_liq_and_ice) real, intent(in), dimension(:,:) :: temp, press real, intent(in) :: eps, zvir real, intent(out), dimension(:,:) :: mrs integer, intent(out) :: nbad real, intent(in), dimension(:,:), optional :: mr real, intent(in), optional :: hc real, intent(out), dimension(:,:), optional :: dmrsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real, dimension(size(temp,1), size(temp,2)) :: esloc, desat, denom integer :: i, j real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present (es_over_liq)) then if (present (dmrsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dmrsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dmrsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (mr) .and. use_exact_qs) then mrs = (eps + mr)*esloc/press if (present (dmrsdT)) then dmrsdT = (eps + mr)*desat/press endif else ! (present (mr)) denom = press - esloc do j=1,size(mrs,2) do i=1,size(mrs,1) if (denom(i,j) > 0.0) then mrs(i,j) = eps*esloc(i,j)/denom(i,j) else mrs(i,j) = eps endif end do end do if (present (dmrsdT)) then dmrsdT = eps*press*desat/denom**2 endif endif !(present (mr)) else mrs = -999. if (present (dmrsdT)) then dmrsdT = -999. endif if (present (esat)) then esat = -999. endif endif end subroutine compute_mrs_k_2d !####################################################################### subroutine compute_mrs_k_1d (temp, press, eps, zvir, mrs, nbad, & mr, hc, dmrsdT, esat,es_over_liq, es_over_liq_and_ice) real, intent(in), dimension(:) :: temp, press real, intent(in) :: eps, zvir real, intent(out), dimension(:) :: mrs integer, intent(out) :: nbad real, intent(in), dimension(:), optional :: mr real, intent(in), optional :: hc real, intent(out), dimension(:), optional :: dmrsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real, dimension(size(temp,1)) :: esloc, desat, denom integer :: i real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present (es_over_liq)) then if (present (dmrsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dmrsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dmrsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (mr) .and. use_exact_qs) then mrs = (eps + mr)*esloc/press if (present (dmrsdT)) then dmrsdT = (eps + mr)*desat/press endif else ! (present (mr)) denom = press - esloc do i=1,size(mrs,1) if (denom(i) > 0.0) then mrs(i) = eps*esloc(i)/denom(i) else mrs(i) = eps endif end do if (present (dmrsdT)) then dmrsdT = eps*press*desat/denom**2 endif endif !(present (mr)) else mrs = -999. if (present (dmrsdT)) then dmrsdT = -999. endif if (present (esat)) then esat = -999. endif endif end subroutine compute_mrs_k_1d !####################################################################### subroutine compute_mrs_k_0d (temp, press, eps, zvir, mrs, nbad, & mr, hc, dmrsdT, esat,es_over_liq, es_over_liq_and_ice) real, intent(in) :: temp, press real, intent(in) :: eps, zvir real, intent(out) :: mrs integer, intent(out) :: nbad real, intent(in), optional :: mr real, intent(in), optional :: hc real, intent(out), optional :: dmrsdT, esat logical,intent(in), optional :: es_over_liq logical,intent(in), optional :: es_over_liq_and_ice real :: esloc, desat, denom real :: hc_loc if (present(hc)) then hc_loc = hc else hc_loc = 1.0 endif if (present (es_over_liq)) then if (present (dmrsdT)) then call lookup_es2_des2_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es2_k (temp, esloc, nbad) endif else if (present(es_over_liq_and_ice)) then if (present (dmrsdT)) then call lookup_es3_des3_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es3_k (temp, esloc, nbad) endif else if (present (dmrsdT)) then call lookup_es_des_k (temp, esloc, desat, nbad) desat = desat*hc_loc else call lookup_es_k (temp, esloc, nbad) endif endif esloc = esloc*hc_loc if (present (esat)) then esat = esloc endif if (nbad == 0) then if (present (mr) .and. use_exact_qs) then mrs = (eps + mr)*esloc/press if (present (dmrsdT)) then dmrsdT = (eps + mr)*desat/press endif else ! (present (mr)) denom = press - esloc if (denom > 0.0) then mrs = eps*esloc/denom else mrs = eps endif if (present (dmrsdT)) then dmrsdT = eps*press*desat/denom**2 endif endif !(present (mr)) else mrs = -999. if (present (dmrsdT)) then dmrsdT = -999. endif if (present (esat)) then esat = -999. endif endif end subroutine compute_mrs_k_0d !####################################################################### subroutine lookup_es_des_k_3d (temp, esat, desat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j,k) = TABLE(ind+1) + & del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) desat(i,j,k) = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif enddo enddo enddo end subroutine lookup_es_des_k_3d !####################################################################### subroutine lookup_es_des_k_2d (temp, esat, desat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j) = TABLE(ind+1) + & del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) desat(i,j) = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif enddo enddo end subroutine lookup_es_des_k_2d !####################################################################### subroutine lookup_es_des_k_1d (temp, esat, desat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i) = TABLE(ind+1) + & del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) desat(i) = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif enddo end subroutine lookup_es_des_k_1d !####################################################################### subroutine lookup_es_des_k_0d (temp, esat, desat, nbad) real, intent(in) :: temp real, intent(out) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat = TABLE(ind+1) + & del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) desat = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif end subroutine lookup_es_des_k_0d !####################################################################### subroutine lookup_es_k_3d(temp, esat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j,k) = TABLE(ind+1) + & del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) endif enddo enddo enddo end subroutine lookup_es_k_3d !####################################################################### subroutine lookup_des_k_3d(temp, desat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i,j,k) = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif enddo enddo enddo end subroutine lookup_des_k_3d !####################################################################### subroutine lookup_des_k_2d(temp, desat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i,j) = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif enddo enddo end subroutine lookup_des_k_2d !####################################################################### subroutine lookup_es_k_2d(temp, esat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j) = TABLE(ind+1) + del*(DTABLE(ind+1) + & del*D2TABLE(ind+1)) endif enddo enddo end subroutine lookup_es_k_2d !####################################################################### subroutine lookup_des_k_1d(temp, desat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i) = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif enddo end subroutine lookup_des_k_1d !####################################################################### subroutine lookup_es_k_1d(temp, esat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i) = TABLE(ind+1) + del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) endif enddo end subroutine lookup_es_k_1d !####################################################################### subroutine lookup_des_k_0d(temp, desat, nbad) real, intent(in) :: temp real, intent(out) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat = DTABLE(ind+1) + 2.*del*D2TABLE(ind+1) endif end subroutine lookup_des_k_0d !####################################################################### subroutine lookup_es_k_0d(temp, esat, nbad) real, intent(in) :: temp real, intent(out) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat = TABLE(ind+1) + del*(DTABLE(ind+1) + del*D2TABLE(ind+1)) endif end subroutine lookup_es_k_0d !####################################################################### subroutine lookup_es2_des2_k_3d (temp, esat, desat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j,k) = TABLE2(ind+1) + & del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) desat(i,j,k) = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif enddo enddo enddo end subroutine lookup_es2_des2_k_3d !####################################################################### subroutine lookup_es2_des2_k_2d (temp, esat, desat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j) = TABLE2(ind+1) + & del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) desat(i,j) = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif enddo enddo end subroutine lookup_es2_des2_k_2d !####################################################################### subroutine lookup_es2_des2_k_1d (temp, esat, desat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i) = TABLE2(ind+1) + & del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) desat(i) = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif enddo end subroutine lookup_es2_des2_k_1d !####################################################################### subroutine lookup_es2_des2_k_0d (temp, esat, desat, nbad) real, intent(in) :: temp real, intent(out) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat = TABLE2(ind+1) + & del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) desat = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif end subroutine lookup_es2_des2_k_0d !####################################################################### subroutine lookup_es2_k_3d(temp, esat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j,k) = TABLE2(ind+1) + & del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) endif enddo enddo enddo end subroutine lookup_es2_k_3d !####################################################################### subroutine lookup_des2_k_3d(temp, desat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i,j,k) = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif enddo enddo enddo end subroutine lookup_des2_k_3d !####################################################################### subroutine lookup_des2_k_2d(temp, desat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i,j) = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif enddo enddo end subroutine lookup_des2_k_2d !####################################################################### subroutine lookup_es2_k_2d(temp, esat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j) = TABLE2(ind+1) + del*(DTABLE2(ind+1) + & del*D2TABLE2(ind+1)) endif enddo enddo end subroutine lookup_es2_k_2d !####################################################################### subroutine lookup_des2_k_1d(temp, desat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i) = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif enddo end subroutine lookup_des2_k_1d !####################################################################### subroutine lookup_es2_k_1d(temp, esat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i) = TABLE2(ind+1) + del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) endif enddo end subroutine lookup_es2_k_1d !####################################################################### subroutine lookup_des2_k_0d(temp, desat, nbad) real, intent(in) :: temp real, intent(out) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat = DTABLE2(ind+1) + 2.*del*D2TABLE2(ind+1) endif end subroutine lookup_des2_k_0d !####################################################################### subroutine lookup_es2_k_0d(temp, esat, nbad) real, intent(in) :: temp real, intent(out) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat = TABLE2(ind+1) + del*(DTABLE2(ind+1) + del*D2TABLE2(ind+1)) endif end subroutine lookup_es2_k_0d !####################################################################### !####################################################################### subroutine lookup_es3_des3_k_3d (temp, esat, desat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j,k) = TABLE3(ind+1) + & del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) desat(i,j,k) = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif enddo enddo enddo end subroutine lookup_es3_des3_k_3d !####################################################################### subroutine lookup_es3_des3_k_2d (temp, esat, desat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j) = TABLE3(ind+1) + & del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) desat(i,j) = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif enddo enddo end subroutine lookup_es3_des3_k_2d !####################################################################### subroutine lookup_es3_des3_k_1d (temp, esat, desat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i) = TABLE3(ind+1) + & del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) desat(i) = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif enddo end subroutine lookup_es3_des3_k_1d !####################################################################### subroutine lookup_es3_des3_k_0d (temp, esat, desat, nbad) real, intent(in) :: temp real, intent(out) :: esat, desat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat = TABLE3(ind+1) + & del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) desat = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif end subroutine lookup_es3_des3_k_0d !####################################################################### subroutine lookup_es3_k_3d(temp, esat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j,k) = TABLE3(ind+1) + & del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) endif enddo enddo enddo end subroutine lookup_es3_k_3d !####################################################################### subroutine lookup_des3_k_3d(temp, desat, nbad) real, intent(in), dimension(:,:,:) :: temp real, intent(out), dimension(:,:,:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j, k nbad = 0 do k = 1, size(temp,3) do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j,k)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i,j,k) = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif enddo enddo enddo end subroutine lookup_des3_k_3d !####################################################################### subroutine lookup_des3_k_2d(temp, desat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i,j) = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif enddo enddo end subroutine lookup_des3_k_2d !####################################################################### subroutine lookup_es3_k_2d(temp, esat, nbad) real, intent(in), dimension(:,:) :: temp real, intent(out), dimension(:,:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i, j nbad = 0 do j = 1, size(temp,2) do i = 1, size(temp,1) tmp = temp(i,j)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i,j) = TABLE3(ind+1) + del*(DTABLE3(ind+1) + & del*D2TABLE3(ind+1)) endif enddo enddo end subroutine lookup_es3_k_2d !####################################################################### subroutine lookup_des3_k_1d(temp, desat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat(i) = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif enddo end subroutine lookup_des3_k_1d !####################################################################### subroutine lookup_es3_k_1d(temp, esat, nbad) real, intent(in), dimension(:) :: temp real, intent(out), dimension(:) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind, i nbad = 0 do i = 1, size(temp,1) tmp = temp(i)-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat(i) = TABLE3(ind+1) + del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) endif enddo end subroutine lookup_es3_k_1d !####################################################################### subroutine lookup_des3_k_0d(temp, desat, nbad) real, intent(in) :: temp real, intent(out) :: desat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) desat = DTABLE3(ind+1) + 2.*del*D2TABLE3(ind+1) endif end subroutine lookup_des3_k_0d !####################################################################### subroutine lookup_es3_k_0d(temp, esat, nbad) real, intent(in) :: temp real, intent(out) :: esat integer, intent(out) :: nbad real :: tmp, del integer :: ind nbad = 0 tmp = temp-tminl ind = int(dtinvl*(tmp+tepsl)) if (ind < 0 .or. ind >= table_siz) then nbad = nbad+1 else del = tmp-dtres*real(ind) esat = TABLE3(ind+1) + del*(DTABLE3(ind+1) + del*D2TABLE3(ind+1)) endif end subroutine lookup_es3_k_0d !####################################################################### end module sat_vapor_pres_k_mod