! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ! Copyright (c) 2009, Centre National de la Recherche Scientifique ! All rights reserved. ! Redistribution and use in source and binary forms, with or without modification, are ! permitted provided that the following conditions are met: ! 1. Redistributions of source code must retain the above copyright notice, this list of ! conditions and the following disclaimer. ! 2. Redistributions in binary form must reproduce the above copyright notice, this list ! of conditions and the following disclaimer in the documentation and/or other ! materials provided with the distribution. ! 3. Neither the name of the copyright holder nor the names of its contributors may be ! used to endorse or promote products derived from this software without specific prior ! written permission. ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY ! EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ! MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ! THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT ! OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! History ! December 2008, S. Bony, H. Chepfer and J-L. Dufresne : ! - optimization for vectorization ! Version 2.0 (October 2008) ! Version 2.1 (December 2008) ! May 2015 - D. Swales - Modified for COSPv2.0 ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% module mod_parasol USE COSP_KINDS, ONLY: wp USE COSP_MATH_CONSTANTS, ONLY: pi use mod_cosp_config, ONLY: R_UNDEF,PARASOL_NREFL,PARASOL_NTAU,PARASOL_TAU,PARASOL_SZA,rlumA,rlumB implicit none contains SUBROUTINE parasol_subcolumn(npoints,nrefl,tautot_S_liq,tautot_S_ice,refl) ! ########################################################################## ! Purpose: To compute Parasol reflectance signal from model-simulated profiles ! of cloud water and cloud fraction in each sub-column of each model ! gridbox. ! December 2008, S. Bony, H. Chepfer and J-L. Dufresne : ! - optimization for vectorization ! Version 2.0 (October 2008) ! Version 2.1 (December 2008) ! ########################################################################## ! INPUTS INTEGER,intent(in) :: & npoints, & ! Number of horizontal gridpoints nrefl ! Number of angles for which the reflectance is computed REAL(WP),intent(inout),dimension(npoints) :: & tautot_S_liq, & ! Liquid water optical thickness, from TOA to SFC tautot_S_ice ! Ice water optical thickness, from TOA to SFC ! OUTPUTS REAL(WP),intent(inout),dimension(npoints,nrefl) :: & refl ! Parasol reflectances ! LOCAL VARIABLES REAL(WP),dimension(npoints) :: & tautot_S, & ! Cloud optical thickness, from TOA to surface frac_taucol_liq, & ! frac_taucol_ice ! ! Look up table variables: INTEGER :: ny,it REAL(WP),dimension(PARASOL_NREFL) :: r_norm REAL(WP),dimension(PARASOL_NREFL,PARASOL_NTAU-1) :: aa,ab,ba,bb REAL(WP),dimension(npoints,5) :: rlumA_mod,rlumB_mod !-------------------------------------------------------------------------------- ! Lum_norm=f(PARASOL_SZA,tau_cloud) derived from adding-doubling calculations ! valid ONLY ABOVE OCEAN (albedo_sfce=5%) ! valid only in one viewing direction (theta_v=30�, phi_s-phi_v=320�) ! based on adding-doubling radiative transfer computation ! for PARASOL_TAU values (0 to 100) and for PARASOL_SZA values (0 to 80) ! for 2 scattering phase functions: liquid spherical, ice non spherical ! Initialize rlumA_mod(1:npoints,1:5) = 0._wp rlumB_mod(1:npoints,1:5) = 0._wp r_norm(1:PARASOL_NREFL)=1._wp/ cos(pi/180._wp*PARASOL_SZA(1:PARASOL_NREFL)) tautot_S_liq(1:npoints) = max(tautot_S_liq(1:npoints),PARASOL_TAU(1)) tautot_S_ice(1:npoints) = max(tautot_S_ice(1:npoints),PARASOL_TAU(1)) tautot_S(1:npoints) = tautot_S_ice(1:npoints) + tautot_S_liq(1:npoints) ! Relative fraction of the opt. thick due to liquid or ice clouds WHERE (tautot_S(1:npoints) .gt. 0.) frac_taucol_liq(1:npoints) = tautot_S_liq(1:npoints) / tautot_S(1:npoints) frac_taucol_ice(1:npoints) = tautot_S_ice(1:npoints) / tautot_S(1:npoints) ELSEWHERE frac_taucol_liq(1:npoints) = 1._wp frac_taucol_ice(1:npoints) = 0._wp END WHERE tautot_S(1:npoints)=MIN(tautot_S(1:npoints),PARASOL_TAU(PARASOL_NTAU)) ! Linear interpolation DO ny=1,PARASOL_NTAU-1 ! Microphysics A (liquid clouds) aA(1:PARASOL_NREFL,ny) = (rlumA(1:PARASOL_NREFL,ny+1)-rlumA(1:PARASOL_NREFL,ny))/(PARASOL_TAU(ny+1)-PARASOL_TAU(ny)) bA(1:PARASOL_NREFL,ny) = rlumA(1:PARASOL_NREFL,ny) - aA(1:PARASOL_NREFL,ny)*PARASOL_TAU(ny) ! Microphysics B (ice clouds) aB(1:PARASOL_NREFL,ny) = (rlumB(1:PARASOL_NREFL,ny+1)-rlumB(1:PARASOL_NREFL,ny))/(PARASOL_TAU(ny+1)-PARASOL_TAU(ny)) bB(1:PARASOL_NREFL,ny) = rlumB(1:PARASOL_NREFL,ny) - aB(1:PARASOL_NREFL,ny)*PARASOL_TAU(ny) ENDDO DO it=1,PARASOL_NREFL DO ny=1,PARASOL_NTAU-1 WHERE (tautot_S(1:npoints) .ge. PARASOL_TAU(ny).and. & tautot_S(1:npoints) .le. PARASOL_TAU(ny+1)) rlumA_mod(1:npoints,it) = aA(it,ny)*tautot_S(1:npoints) + bA(it,ny) rlumB_mod(1:npoints,it) = aB(it,ny)*tautot_S(1:npoints) + bB(it,ny) END WHERE END DO END DO DO it=1,PARASOL_NREFL refl(1:npoints,it) = frac_taucol_liq(1:npoints) * rlumA_mod(1:npoints,it) & + frac_taucol_ice(1:npoints) * rlumB_mod(1:npoints,it) ! Normalized radiance -> reflectance: refl(1:npoints,it) = refl(1:npoints,it) * r_norm(it) ENDDO RETURN END SUBROUTINE parasol_subcolumn ! ###################################################################################### ! SUBROUTINE parasol_gridbox ! ###################################################################################### subroutine parasol_column(npoints,nrefl,ncol,land,refl,parasolrefl) ! Inputs integer,intent(in) :: & npoints, & ! Number of horizontal grid points ncol, & ! Number of subcolumns nrefl ! Number of solar zenith angles for parasol reflectances real(wp),intent(in),dimension(npoints) :: & land ! Landmask [0 - Ocean, 1 - Land] real(wp),intent(in),dimension(npoints,ncol,nrefl) :: & refl ! Subgrid parasol reflectance ! parasol ! Outputs real(wp),intent(out),dimension(npoints,nrefl) :: & parasolrefl ! Grid-averaged parasol reflectance ! Local variables integer :: k,ic ! Compute grid-box averaged Parasol reflectances parasolrefl(:,:) = 0._wp do k = 1, nrefl do ic = 1, ncol parasolrefl(:,k) = parasolrefl(:,k) + refl(:,ic,k) enddo enddo do k = 1, nrefl parasolrefl(:,k) = parasolrefl(:,k) / float(ncol) ! if land=1 -> parasolrefl=R_UNDEF ! if land=0 -> parasolrefl=parasolrefl parasolrefl(:,k) = parasolrefl(:,k) * MAX(1._wp-land(:),0.0) & + (1._wp - MAX(1._wp-land(:),0.0))*R_UNDEF enddo end subroutine parasol_column end module mod_parasol