3 !------------------------------------------------------------------------------!
4 ! MM5 Map projection parameters needed to compute MM5 coordinates (xj, yi)
5 ! from latitude and longitude.
6 ! get_map_params: Read the parameters from an MM5 V2/V3 input/output file
7 ! set_map_param: Set the map parameters from the input read in MM5 file
9 ! F. VANDENBERGHE, March 2001
10 !------------------------------------------------------------------------------!
13 ! INTEGER :: IDD, IPROJ, IXC, JXC
14 ! REAL :: PHIC, XLONC, XN, TRUELAT1, TRUELAT2, POLE, &
15 ! DIS (10), XIM11 (10), XJM11 (10), &
16 ! PSI1, C2, XCNTR, YCNTR
20 !------------------------------------------------------------------------------!
23 SUBROUTINE get_map_params (iunit)
24 !------------------------------------------------------------------------------!
27 ! READ THE MAP PROJECTION PARAMETERS: IPROJ, IXC, JXC, PHIC, XLONC, XN,
28 ! TRUELAT1, TRUELAT2, POLE, DSC, DSM, XIM11, XJM11
29 ! FROM A MM5 V2/V3 INPUT/OUTPUT FILE.
32 ! iunit: Logical file unit (file must be preably opened
35 ! IXC: COARSE DOMAIN GRID DIMENSION IN I (N-S) DIRECTION
36 ! JXC: COARSE DOMAIN GRID DIMENSION IN J (E-W) DIRECTION
37 ! IPROJ: MAP PROJECTION (1 = LAMBER, 2 = POLAR, 3 = MERCATOR)
38 ! DSC: COARSE DOMAIN GRID DISTANCE IN KM
39 ! PHIC: COARSE DOMAIN CENTER LATITUDE
40 ! XLONC: COARSE DOMAIN CENTER LONGITUDE
42 ! TRUELAT1: TRUE LATITUDE 1 (DEGREE)
43 ! TRUELAT2: TRUE LATITUDE 2 (DEGREE)
44 ! POLE: POLE POSITION IN DEGREE LATIITUDE
45 ! DSM : DOMAIN GRID DISTANCE IN KM
46 ! XIM11: I LOCATION IN THE COARSE DOMAIN OF THE CURRENT DOMAIN POINT (1,1)
47 ! XJM11: J LOCATION IN THE COARSE DOMAIN OF THE CURRENT DOMAIN POINT (1,1)
49 !------------------------------------------------------------------------------!
52 INTEGER, INTENT (in) :: iunit
53 ! INTEGER, INTENT (out) :: iproj, ixc, jxc
54 ! REAL, INTENT (out) :: phic, pole, truelat1, xn, &
55 ! xlonc, truelat2, dsc, dsm, xim11, xjm11
58 CHARACTER (LEN= 8) :: message
60 INTEGER(kind=4) :: flag
61 integer(kind=4), dimension(50,20) :: bhi
62 real(kind=4), dimension(20,20) :: bhr
63 character(80), dimension(50,20) :: bhic
64 character(80), dimension(20,20) :: bhrc
66 !------------------------------------------------------------------------------!
73 ! 1.1 V3 very first record must be an integer
74 ! --------------------------------------
78 READ (iunit, IOSTAT = io_error) flag
80 ! 1.2 Then come headers
83 IF ((io_error .EQ. 0) .AND. (flag .EQ. 0)) THEN
85 READ (iunit, IOSTAT = io_error) bhi, bhr, bhic, bhrc
87 ! 1.3 Integer map parameters
88 ! ----------------------
104 NUMC (IDD) = bhi(14,1)
106 NESTIX(IDD) = bhi(16,1)
107 NESTJX(IDD) = bhi(17,1)
109 NESTI (IDD) = bhi(18,1)
110 NESTJ (IDD) = bhi(19,1)
112 ! 1.4 Real map parameters
113 ! -------------------
120 DIS (1) = bhr (1, 1) * 0.001
121 DIS (IDD) = bhr (9, 1) * 0.001
125 ! 1.4 Real map parameters
126 ! -------------------
129 DIS (IDD) = bhr (9, 1)
134 TRUELAT1 = bhr (5, 1)
135 TRUELAT2 = bhr (6, 1)
137 XIM11 (IDD) = bhr (10, 1)
138 XJM11 (IDD) = bhr (11, 1)
143 write(unit=*, fmt='(a,i4)') &
144 'Error reading big header of unit:', iunit
150 ! 3. OTHER FILE FORMATS ARE UNKNOWN
151 ! ==================================
153 IF (io_error .NE. 0) THEN
154 WRITE (message,'(I3)') iunit
155 CALL error_handler ('get_mm5_params.F90',&
156 ' Cannot read file unit ', TRIM (message), .TRUE.)
163 WRITE (0,'(4(A,A,F7.2,/))',ADVANCE='no') &
164 "Map parameters: "," Phic = ",PHIC, &
165 " "," Xlonc= ",XLONC, &
166 " "," True1= ",TRUELAT1,&
167 " "," True2= ",TRUELAT2
169 WRITE (0,'(A,A,I4)',ADVANCE='no') &
173 CASE (1); WRITE (0,'(A)') " (LAMBERT CONFORMAL)"
174 CASE (2); WRITE (0,'(A)') " (POLAR STEREO.)"
175 CASE (3); WRITE (0,'(A)') " (MERCATOR)"
176 CASE DEFAULT ; WRITE (0,'(A)') " (UNKNOWN)"
179 END SUBROUTINE GET_MAP_PARAMS
181 ! SUBROUTINE SET_MAP_PARAMS (iproj, ixc, jxc, &
182 ! phic, xlonc, xn, truelat1, truelat2, pole,&
183 ! dsc, dsm, xim11, xjm11, &
184 ! c2, psi1, xcntr, ycntr)
185 SUBROUTINE SET_MAP_PARAMS
186 !------------------------------------------------------------------------------!
189 ! Set the map projection parameters: c2, psi1, xcntr, ycntr
193 ! iproj: Map projection (1 = lamber, 2 = polar, 3 = mercator)
194 ! phic: Coarse domain center latitude (in degree)
195 ! pole: Pole position latitude (in degree)
196 ! truelat1: True latitude for domain 1 (in degree)
205 !------------------------------------------------------------------------------!
208 ! INTEGER, INTENT (in) :: iproj, ixc, jxc
209 ! REAL, INTENT (in) :: phic, pole, truelat1, xn, &
210 ! xlonc, truelat2, dsc, dsm, xim11, xjm11
211 ! REAL, INTENT (out) :: c2, psi1, xcntr, ycntr
213 REAL :: psx, cell, cell2, r, phictr
215 ! Pi and earth radius in km
217 ! REAL, PARAMETER :: PI = 3.1415926535897932346
218 ! REAL, PARAMETER :: CONV = 180. / PI
219 ! REAL, PARAMETER :: A = 6378.15
221 INCLUDE 'constants.inc'
222 !------------------------------------------------------------------------------C
224 ! WRITE (0,'(A)') ' SET MAP PARAMETERS'
228 IF (IPROJ .EQ. 1 .OR. IPROJ.EQ.2) THEN
245 ! --------CALCULATE R
247 IF (IPROJ .NE. 3) THEN
249 PSX = (POLE-PHIC)/CONV
253 CELL = A*SIN (PSI1)/XN
254 CELL2 = (TAN (PSX/2.))/(TAN (PSI1/2.))
255 WRITE (0,*) ' CELL = ' ,A,PSI1,XN,CELL
261 CELL = A*SIN (PSX)/XN
262 CELL2 = (1. + COS (PSI1))/(1. + COS (PSX))
270 WRITE (0,*) ' YCNTR = ' ,CELL,CELL2,XN
274 ! -----FOR MERCATOR PROJECTION, THE PROJECTION IS TRUE AT LAT AT PHI1
276 IF (IPROJ .EQ. 3) THEN
281 CELL = COS (PHICTR)/(1.0+SIN (PHICTR))
282 YCNTR = - C2*ALOG (CELL)
286 WRITE (0,'(3(A,A,F7.2,/))',ADVANCE='no') &
288 " "," Psi1 = ",Psi1, &
290 WRITE (0,'(1(A,A,F9.2))') &
297 END SUBROUTINE SET_MAP_PARAMS
299 SUBROUTINE LLXY (XLATI,XLONI,X,Y)
300 !------------------------------------------------------------------------------!
306 ! PURPOSE: CALCULATES THE (X,Y) LOCATION (DOT) IN THE MESOSCALE GRIDS
307 ! ------- FROM LATITUDES AND LONGITUDES
317 ! X: THE COORDINATE IN X (J)-DIRECTION.
318 ! Y: THE COORDINATE IN Y (I)-DIRECTION.
320 !------------------------------------------------------------------------------!
324 REAL, INTENT(IN) :: XLATI, XLONI
325 ! REAL, INTENT(IN) :: ID
326 REAL, INTENT(OUT) :: X, Y
329 REAL :: XX, YY, XC, YC
330 REAL :: CELL, PSI0, PSX, R, FLP
331 REAL :: CENTRI, CENTRJ
336 INCLUDE 'constants.inc'
338 !------------------------------------------------------------------------------!
343 XLAT = MAX (XLAT, -89.95)
344 XLAT = MIN (XLAT, +89.95)
347 IF (DXLON.GT. 180) DXLON = DXLON - 360.
348 IF (DXLON.LT.-180) DXLON = DXLON + 360.
355 ! For Mercator projection, high latitude has no definition:
356 IF (abs(XLAT) .gt.89.95) THEN
357 PRINT '(A,F8.3,A,F8.3)', &
358 "**WARNING** MERCATOR PROJECTION, BUT abs(XLAT)= |", &
359 XLAT,"| > 89.95 ?? XLON=",xlon
365 CELL = COS(XLAT/CONV)/(1.0+SIN(XLAT/CONV))
371 PSI0 = ( POLE - PHIC )/CONV
374 !------ CALCULATE X,Y COORDS. RELATIVE TO POLE
378 PSX = ( POLE - XLAT )/CONV
381 bb = 2.0*(COS(PSI1/2.0)**2)
382 YC = -A*bb*TAN(PSI0/2.0)
383 R = -A*bb*TAN(PSX/2.0)
386 YC = bb*(TAN(PSI0/2.0)/TAN(PSI1/2.0))**XN
387 R = bb*(TAN(PSX /2.0)/TAN(PSI1/2.0))**XN
390 IF (PHIC .LT. 0.0) THEN
400 ! TRANSFORM (1,1) TO THE ORIGIN
402 CENTRI = FLOAT (IXC + 1)/2.0 ! the location of the center in the coarse
403 CENTRJ = FLOAT (JXC + 1)/2.0 ! domain
405 X = ( XX - XC )/DIS (1) + CENTRJ ! the (X,Y) coordinates in the coarse
406 Y = ( YY - YC )/DIS (1) + CENTRI ! domain
408 NRATIO = NINT(DIS (1) / DIS (IDD))
410 X = (X - XJM11 (IDD))*NRATIO + 1.0
411 Y = (Y - XIM11 (IDD))*NRATIO + 1.0
415 SUBROUTINE XYLL (XX,YY,XLAT,XLON)
416 !--------------------------------------------------------------------------CCC
422 ! PURPOSE: CALCULATES THE LATITUDES AND LONGITUDES FROM THE
423 ! ------- (X,Y) LOCATION (DOT) IN THE MESOSCALE GRIDS.
427 ! X: THE COORDINATE IN X (J)-DIRECTION.
428 ! Y: THE COORDINATE IN Y (I)-DIRECTION.
435 !----------------------------------------------------------------------------CC
441 REAL, INTENT(IN) :: XX, YY
442 REAL, INTENT(OUT) :: XLAT,XLON
443 ! INTEGER, INTENT(IN) :: ID
449 REAL :: FLP, FLPP, R, RXN, CELL, CEL1, CEL2, PSX
451 INCLUDE 'constants.inc'
452 !------------------------------------------------------------------------------C
454 CNTRI = float(IXC+1)/2.
455 CNTRJ = float(JXC+1)/2.
457 !-----CALCULATE X AND Y POSITIONS OF GRID AT DOT POINT
459 X = XCNTR+(XX-1.0)*DIS(IDD)+(XJM11(IDD)-CNTRJ)*DIS(1)
460 Y = YCNTR+(YY-1.0)*DIS(IDD)+(XIM11(IDD)-CNTRI)*DIS(1)
462 !-----NOW CALCULATE LAT AND LON OF THIS POINT
468 IF (X.GE.0.0) FLP = 90.0/CONV
469 IF (X.LT.0.0) FLP = -90.0/CONV
481 FLPP = (FLP/XN)*CONV+XLONC
483 IF (FLPP.LT.-180.) FLPP = FLPP + 360
484 IF (FLPP.GT.180.) FLPP = FLPP - 360.
488 !--------NOW SOLVE FOR LATITUDE
492 IF (PHIC.LT.0.0) R = -R
495 CELL = (R*XN)/(A*SIN(PSI1))
497 CEL1 = TAN(PSI1/2.)*(CELL)**RXN
502 CEL1 = CELL/(1.0+COS(PSI1))
511 !-----CALCULATIONS FOR MERCATOR LAT,LON
515 XLON = XLONC + ((X-XCNTR)/C2)*CONV
517 IF (XLON.LT.-180.) XLON = XLON + 360
518 IF (XLON.GT.180.) XLON = XLON - 360.
521 XLAT = 2.*(CONV*ATAN(CELL))-90.0
526 !==============================================================================!
527 END MODULE MODULE_MAP