Ignore:
Timestamp:
Feb 10, 2020 8:32:41 PM (4 years ago)
Author:
suehring
Message:

Revision of the virtual-measurement module: data input from NetCDF file; removed binary output - instead parallel NetCDF output using the new data-output module; variable attributes added; further variables added that can be sampled, file connections added; Functions for coordinate transformation moved to basic_constants_and_equations; netcdf_data_input_mod: unused routines netcdf_data_input_att and netcdf_data_input_var removed; new routines to inquire fill values added; Preprocessing script (palm_cvd) to setup virtual-measurement input files provided; postprocessor combine_virtual_measurements deleted

File:
1 edited

Legend:

Unmodified
Added
Removed
  • palm/trunk/SOURCE/basic_constants_and_equations_mod.f90

    r4360 r4400  
    2525! -----------------
    2626! $Id$
     27! Move routine to transform coordinates from netcdf_interface_mod to
     28! basic_constants_and_equations_mod
     29!
     30! 4360 2020-01-07 11:25:50Z suehring
    2731! Corrected "Former revisions" section
    2832!
     
    113117            barometric_formula_1d
    114118
     119
     120    INTERFACE convert_utm_to_geographic
     121       MODULE PROCEDURE convert_utm_to_geographic
     122    END INTERFACE convert_utm_to_geographic
     123
    115124    INTERFACE magnus
    116125       MODULE PROCEDURE magnus_0d
     
    142151       MODULE PROCEDURE barometric_formula_1d
    143152    END INTERFACE barometric_formula
     153!
     154!-- Public routines
     155    PUBLIC convert_utm_to_geographic
    144156
    145157 CONTAINS
     158
     159
     160!------------------------------------------------------------------------------!
     161! Description:
     162! ------------
     163!> Convert UTM coordinates into geographic latitude and longitude. Conversion
     164!> is based on the work of KrÃŒger (1912) DOI: 10.2312/GFZ.b103-krueger28
     165!> and Karney (2013) DOI: 10.1007/s00190-012-0578-z
     166!> Based on a JavaScript of the geodesy function library written by chrisveness
     167!> https://github.com/chrisveness/geodesy
     168!------------------------------------------------------------------------------!
     169    SUBROUTINE convert_utm_to_geographic( crs, eutm, nutm, lon, lat )
     170
     171       INTEGER(iwp) ::  j   !< loop index
     172
     173       REAL(wp), INTENT(in)  ::  eutm !< easting (UTM)
     174       REAL(wp), INTENT(out) ::  lat  !< geographic latitude in degree
     175       REAL(wp), INTENT(out) ::  lon  !< geographic longitude in degree
     176       REAL(wp), INTENT(in)  ::  nutm !< northing (UTM)
     177
     178       REAL(wp) ::  a           !< 2*pi*a is the circumference of a meridian
     179       REAL(wp) ::  cos_eta_s   !< cos(eta_s)
     180       REAL(wp) ::  delta_i     !<
     181       REAL(wp) ::  delta_tau_i !<
     182       REAL(wp) ::  e           !< eccentricity
     183       REAL(wp) ::  eta         !<
     184       REAL(wp) ::  eta_s       !<
     185       REAL(wp) ::  n           !< 3rd flattening
     186       REAL(wp) ::  n2          !< n^2
     187       REAL(wp) ::  n3          !< n^3
     188       REAL(wp) ::  n4          !< n^4
     189       REAL(wp) ::  n5          !< n^5
     190       REAL(wp) ::  n6          !< n^6
     191       REAL(wp) ::  nu          !<
     192       REAL(wp) ::  nu_s        !<
     193       REAL(wp) ::  sin_eta_s   !< sin(eta_s)
     194       REAL(wp) ::  sinh_nu_s   !< sinush(nu_s)
     195       REAL(wp) ::  tau_i       !<
     196       REAL(wp) ::  tau_i_s     !<
     197       REAL(wp) ::  tau_s       !<
     198       REAL(wp) ::  x           !< adjusted easting
     199       REAL(wp) ::  y           !< adjusted northing
     200
     201       REAL(wp), DIMENSION(6) ::  beta !< 6th order KrÃŒger expressions
     202
     203       REAL(wp), DIMENSION(8), INTENT(in) ::  crs !< coordinate reference system, consists of
     204                                                  !< (/semi_major_axis,
     205                                                  !<   inverse_flattening,
     206                                                  !<   longitude_of_prime_meridian,
     207                                                  !<   longitude_of_central_meridian,
     208                                                  !<   scale_factor_at_central_meridian,
     209                                                  !<   latitude_of_projection_origin,
     210                                                  !<   false_easting,
     211                                                  !<   false_northing /)
     212
     213       x = eutm - crs(7)  ! remove false easting
     214       y = nutm - crs(8)  ! remove false northing
     215!
     216!--    from Karney 2011 Eq 15-22, 36:
     217       e = SQRT( 1.0_wp / crs(2) * ( 2.0_wp - 1.0_wp / crs(2) ) )
     218       n = 1.0_wp / crs(2) / ( 2.0_wp - 1.0_wp / crs(2) )
     219       n2 = n * n
     220       n3 = n * n2
     221       n4 = n * n3
     222       n5 = n * n4
     223       n6 = n * n5
     224
     225       a = crs(1) / ( 1.0_wp + n ) * ( 1.0_wp + 0.25_wp * n2       &
     226                                              + 0.015625_wp * n4   &
     227                                              + 3.90625E-3_wp * n6 )
     228
     229       nu  = x / ( crs(5) * a )
     230       eta = y / ( crs(5) * a )
     231
     232!--    According to KrÃŒger (1912), eq. 26*
     233       beta(1) =        0.5_wp                  * n  &
     234               -        2.0_wp /         3.0_wp * n2 &
     235               +       37.0_wp /        96.0_wp * n3 &
     236               -        1.0_wp /       360.0_wp * n4 &
     237               -       81.0_wp /       512.0_wp * n5 &
     238               +    96199.0_wp /    604800.0_wp * n6
     239
     240       beta(2) =        1.0_wp /        48.0_wp * n2 &
     241               +        1.0_wp /        15.0_wp * n3 &
     242               -      437.0_wp /      1440.0_wp * n4 &
     243               +       46.0_wp /       105.0_wp * n5 &
     244               -  1118711.0_wp /   3870720.0_wp * n6
     245
     246       beta(3) =       17.0_wp /       480.0_wp * n3 &
     247               -       37.0_wp /       840.0_wp * n4 &
     248               -      209.0_wp /      4480.0_wp * n5 &
     249               +     5569.0_wp /     90720.0_wp * n6
     250
     251       beta(4) =     4397.0_wp /    161280.0_wp * n4 &
     252               -       11.0_wp /       504.0_wp * n5 &
     253               -   830251.0_wp /   7257600.0_wp * n6
     254
     255       beta(5) =     4583.0_wp /    161280.0_wp * n5 &
     256               -   108847.0_wp /   3991680.0_wp * n6
     257
     258       beta(6) = 20648693.0_wp / 638668800.0_wp * n6
     259
     260       eta_s = eta
     261       nu_s  = nu
     262       DO  j = 1, 6
     263         eta_s = eta_s - beta(j) * SIN(2.0_wp * j * eta) * COSH(2.0_wp * j * nu)
     264         nu_s  = nu_s  - beta(j) * COS(2.0_wp * j * eta) * SINH(2.0_wp * j * nu)
     265       ENDDO
     266
     267       sinh_nu_s = SINH( nu_s )
     268       sin_eta_s = SIN( eta_s )
     269       cos_eta_s = COS( eta_s )
     270
     271       tau_s = sin_eta_s / SQRT( sinh_nu_s**2 + cos_eta_s**2 )
     272
     273       tau_i = tau_s
     274       delta_tau_i = 1.0_wp
     275
     276       DO WHILE ( ABS( delta_tau_i ) > 1.0E-12_wp )
     277
     278         delta_i = SINH( e * ATANH( e * tau_i / SQRT( 1.0_wp + tau_i**2 ) ) )
     279
     280         tau_i_s = tau_i   * SQRT( 1.0_wp + delta_i**2 )  &
     281                  - delta_i * SQRT( 1.0_wp + tau_i**2 )
     282
     283         delta_tau_i = ( tau_s - tau_i_s ) / SQRT( 1.0_wp + tau_i_s**2 )  &
     284                      * ( 1.0_wp + ( 1.0_wp - e**2 ) * tau_i**2 )          &
     285                      / ( ( 1.0_wp - e**2 ) * SQRT( 1.0_wp + tau_i**2 ) )
     286
     287         tau_i = tau_i + delta_tau_i
     288
     289       ENDDO
     290
     291       lat = ATAN( tau_i ) / pi * 180.0_wp
     292       lon = ATAN2( sinh_nu_s, cos_eta_s ) / pi * 180.0_wp + crs(4)
     293
     294    END SUBROUTINE convert_utm_to_geographic
    146295
    147296!------------------------------------------------------------------------------!
     
    161310!--    Saturation vapor pressure for a specific temperature:
    162311       magnus_0d =  611.2_wp * EXP( 17.62_wp * ( t - degc_to_k ) /             &
    163                                                    ( t - 29.65_wp  ) )
     312                                               ( t - 29.65_wp  ) )
    164313
    165314    END FUNCTION magnus_0d
Note: See TracChangeset for help on using the changeset viewer.