prismtrs_line_integral.F90

Go to the documentation of this file.
00001 !------------------------------------------------------------------------
00002 ! Copyright 2006-2010, CERFACS, Toulouse, France.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 !
00008 ! !ROUTINE: PRISMTrs_line_integral
00009 !
00010 ! !INTERFACE!
00011       subroutine prismtrs_line_integral(lcl_weights, & 
00012                              in_phi1, in_phi2, theta1, theta2, &
00013                              grid1_lon, grid2_lon, num_wts)
00014 
00015 !-----------------------------------------------------------------------
00016 !
00017 !     intent(in):
00018 !
00019 !-----------------------------------------------------------------------
00020       USE PRISMDrv, dummy_INTERFACE => PRISMTrs_line_integral
00021       IMPLICIT NONE
00022 
00023       DOUBLE PRECISION, intent(in) ::  
00024            in_phi1, in_phi2,      ! longitude endpoints for the segment
00025            theta1, theta2,           ! latitude  endpoints for the segment
00026            grid1_lon,  ! reference coordinates for each
00027            grid2_lon  ! grid (to ensure correct 0,2pi interv.
00028       INTEGER, intent(in) :: num_wts ! Number of weights for 2D conservative remapping
00029 
00030 !-----------------------------------------------------------------------
00031 !
00032 !     intent(out):
00033 !
00034 !-----------------------------------------------------------------------
00035 
00036       DOUBLE PRECISION, dimension(2*num_wts), intent(out) :: 
00037            lcl_weights   ! line integral contribution to lcl_weights
00038 
00039 ! !DESCRIPTION
00040 !
00041 ! SUBROUTINE PRISMTrs_line_integral computes the line integral 
00042 !     of the flux function that results in the interpolation lcl_weights.  
00043 !     the line is defined by the input lat/lon of the endpoints.
00044 !     This routine comes from the SCRIP 1.4 library available 
00045 !     from Los Alamos National Laboratory.
00046 !
00047 ! !REVISED HISTORY
00048 !   Date      Programmer   Description
00049 ! ----------  ----------   -----------
00050 ! 20/03/2007  S. Valcke    Duplicated from the SCRIP library
00051 !
00052 ! EOP
00053 !----------------------------------------------------------------------
00054 ! $Id: prismtrs_line_integral.F90 2082 2009-10-21 13:31:19Z hanke $
00055 ! $Author: hanke $
00056 !----------------------------------------------------------------------
00057 !
00058 !-----------------------------------------------------------------------
00059 !
00060 !     local variables
00061 !
00062 !-----------------------------------------------------------------------
00063   CHARACTER(LEN=len_cvs_string), SAVE  :: mycvs = 
00064      '$Id: prismtrs_line_integral.F90 2082 2009-10-21 13:31:19Z hanke $'
00065       DOUBLE PRECISION :: dphi, sinth1, sinth2, costh1, costh2, fac, 
00066                               phi1, phi2, phidiff1, phidiff2
00067       DOUBLE PRECISION :: f1, f2, fint
00068 
00069 #ifdef DEBUGX
00070   PRINT *, '| | | | | | | Enter PRISMTrs_line_integral'
00071   call psmile_flushstd
00072 #endif
00073 !-----------------------------------------------------------------------
00074 !
00075 !     lcl_weights for the general case based on a trapezoidal approx to
00076 !     the integrals.
00077 !
00078 !-----------------------------------------------------------------------
00079 
00080       sinth1 = SIN(theta1)
00081       sinth2 = SIN(theta2)
00082       costh1 = COS(theta1)
00083       costh2 = COS(theta2)
00084 
00085       dphi = in_phi1 - in_phi2
00086       if (dphi >  dble_pi) then
00087         dphi = dphi - dble_pi2
00088       else if (dphi < -dble_pi) then
00089         dphi = dphi + dble_pi2
00090       endif
00091       dphi = half*dphi
00092 
00093 !-----------------------------------------------------------------------
00094 !
00095 !     the first weight is the area overlap integral. the second and
00096 !     fourth are second-order latitude gradient lcl_weights.
00097 !
00098 !-----------------------------------------------------------------------
00099       lcl_weights(:) = zero
00100       lcl_weights(        1) = dphi*(sinth1 + sinth2)
00101       lcl_weights(num_wts+1) = dphi*(sinth1 + sinth2)
00102       lcl_weights(        2) = dphi*(costh1 + costh2 + (theta1*sinth1 + &
00103                                                     theta2*sinth2))
00104       lcl_weights(num_wts+2) = dphi*(costh1 + costh2 + (theta1*sinth1 + &
00105                                                     theta2*sinth2))
00106 
00107 !-----------------------------------------------------------------------
00108 !
00109 !     the third and fifth lcl_weights are for the second-order phi gradient
00110 !     component.  must be careful of longitude range.
00111 !
00112 !-----------------------------------------------------------------------
00113       f1 = half*(costh1*sinth1 + theta1)
00114       f2 = half*(costh2*sinth2 + theta2)
00115 
00116       phi1 = in_phi1 - grid1_lon
00117       if (phi1 >  dble_pi) then
00118         phi1 = phi1 - dble_pi2
00119       else if (phi1 < -dble_pi) then
00120         phi1 = phi1 + dble_pi2
00121       endif
00122 
00123       phi2 = in_phi2 - grid1_lon
00124       if (phi2 >  dble_pi) then
00125         phi2 = phi2 - dble_pi2
00126       else if (phi2 < -dble_pi) then
00127         phi2 = phi2 + dble_pi2
00128       endif
00129 
00130       if ((phi2-phi1) <  dble_pi .and. (phi2-phi1) > -dble_pi) then
00131         lcl_weights(3) = dphi*(phi1*f1 + phi2*f2)
00132       else
00133         if (phi1 > zero) then
00134           fac = dble_pi
00135         else
00136           fac = -dble_pi
00137         endif
00138         fint = f1 + (f2-f1)*(fac-phi1)/abs(dphi)
00139         lcl_weights(3) = half*phi1*(phi1-fac)*f1 - &
00140                      half*phi2*(phi2+fac)*f2 + &
00141                      half*fac*(phi1+phi2)*fint
00142       endif
00143 
00144       phi1 = in_phi1 - grid2_lon
00145       if (phi1 >  dble_pi) then
00146         phi1 = phi1 - dble_pi2
00147       else if (phi1 < -dble_pi) then
00148         phi1 = phi1 + dble_pi2
00149       endif
00150 
00151       phi2 = in_phi2 - grid2_lon
00152       if (phi2 >  dble_pi) then
00153         phi2 = phi2 - dble_pi2
00154       else if (phi2 < -dble_pi) then
00155         phi2 = phi2 + dble_pi2
00156       endif
00157 
00158       if ((phi2-phi1) <  dble_pi .and. (phi2-phi1) > -dble_pi) then
00159         lcl_weights(num_wts+3) = dphi*(phi1*f1 + phi2*f2)
00160       else
00161         if (phi1 > zero) then
00162           fac = dble_pi
00163         else
00164           fac = -dble_pi
00165         endif
00166         fint = f1 + (f2-f1)*(fac-phi1)/abs(dphi)
00167         lcl_weights(num_wts+3) = half*phi1*(phi1-fac)*f1 - &
00168                              half*phi2*(phi2+fac)*f2 + &
00169                              half*fac*(phi1+phi2)*fint
00170       endif
00171 
00172 #ifdef DEBUGX
00173   PRINT *, '| | | | | | | Quit PRISMTrs_line_integral'
00174   call psmile_flushstd
00175 #endif
00176 
00177 !-----------------------------------------------------------------------
00178 
00179       end subroutine prismtrs_line_integral
00180 

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1