Newer
Older
!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
!MNH_LIC for details. version 1.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
!-----------------------------------------------------------------
!--------------- special set of characters for RCS information
!-----------------------------------------------------------------
! $Source$ $Revision$
!-----------------------------------------------------------------
!###################
MODULE MODI_SPAWN_ZS
!###################
!
INTERFACE
!
SUBROUTINE SPAWN_ZS (KXOR,KXEND,KYOR,KYEND,KDXRATIO,KDYRATIO,HLBCX,HLBCY,&
HLUOUT,PZS1,PZS2,HFIELD,PZS2_LS )
!
INTEGER, INTENT(IN) :: KXOR,KXEND ! horizontal position (i,j) of the ORigin and END
INTEGER, INTENT(IN) :: KYOR,KYEND ! of the model 2 domain, relative to model 1
INTEGER, INTENT(IN) :: KDXRATIO ! x and y-direction Resolution ratio
INTEGER, INTENT(IN) :: KDYRATIO ! between model 2 and model 1
CHARACTER(LEN=4),DIMENSION(2),INTENT(IN):: HLBCX, HLBCY ! X- and Y-direc LBC
CHARACTER(LEN=*), INTENT(IN) :: HLUOUT ! output-listing file
REAL, DIMENSION(:,:), INTENT(IN) :: PZS1 ! model 1 orography
REAL, DIMENSION(:,:), INTENT(OUT) :: PZS2 ! interpolated orography with iterative correction
CHARACTER(LEN=6), INTENT(IN) :: HFIELD ! name of the field to nest
REAL, DIMENSION(:,:), INTENT(OUT),OPTIONAL :: PZS2_LS ! interpolated orography
!
END SUBROUTINE SPAWN_ZS
!
END INTERFACE
!
END MODULE MODI_SPAWN_ZS
!
!
! #########################################################################
SUBROUTINE SPAWN_ZS (KXOR,KXEND,KYOR,KYEND,KDXRATIO,KDYRATIO,HLBCX,HLBCY,&
HLUOUT,PZS1,PZS2,HFIELD,PZS2_LS )
! #########################################################################
!
!!**** *SPAWN_ZS * - subroutine to spawn zs field
!!
!! PURPOSE
!! -------
!!
!! This routine defines the information necessary to generate the model 2
!! grid, consistently with the spawning model 1.
!! The longitude and latitude of the model 2 origine are computed from
!! the model 1. Then the grid in the conformal projection and terrain
!! following coordinates (XHAT,YHAT and ZHAT) and orography, are interpolated
!! from the model 1 grid and orography knowledge.
!!
!!** METHOD
!! ------
!!
!! The model 2 variables are transmitted by argument (P or K prefixes),
!! while the ones of model 1 are declared through calls to MODD_...
!! (X or N prefixes)
!!
!! For the case where the resolution ratio between models is 1,
!! the horizontal interpolation becomes a simple equality.
!! For the general case where resolution ratio is not egal to one,
!! grid and orography are interpolated as follows:
!! - linear interpolation for XHAT and YHAT
!! - identity for ZHAT (no vertical spawning)
!! 2 types of interpolations can be used:
!! 1. Clark and Farley (JAS 1984) on 9 points
!! 2. Bikhardt on 16 points
!!
!! EXTERNAL
!! --------
!!
!! FMLOOK : to recover a logical unit number
!! Routine BIKHARDT2 : to perform horizontal interpolations
!!
!!
!! IMPLICIT ARGUMENTS
!! ------------------
!!
!! Module MODD_PARAMETERS : contains parameters
!! Module MODD_CONF : contains models configuration
!! Module MODD_LUNIT2 : contains unit numbers of model 2 files
!!
!! REFERENCE
!! ---------
!!
!! Book1 of the documentation
!! PROGRAM SPAWN_ZS (Book2 of the documentation)
!!
!! AUTHOR
!! ------
!!
!! V. Masson * METEO-FRANCE *
!!
!! MODIFICATIONS
!! -------------
!!
!! Original 12/01/05
!! Modification 20/05/06 Remove Clark and Farley interpolation
!! J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
!-------------------------------------------------------------------------------
!
!* 0. DECLARATIONS
! ------------
!
USE MODD_PARAMETERS, ONLY : JPHEXT ! Declarative modules
USE MODD_CONF, ONLY : NVERB
!
USE MODD_BIKHARDT_n
!
USE MODI_BIKHARDT
USE MODI_ZS_BOUNDARY
!
USE MODE_MODELN_HANDLER
!
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
IMPLICIT NONE
!
!* 0.1 Declarations of dummy arguments :
!
INTEGER, INTENT(IN) :: KXOR,KXEND ! horizontal position (i,j) of the ORigin and END
INTEGER, INTENT(IN) :: KYOR,KYEND ! of the model 2 domain, relative to model 1
INTEGER, INTENT(IN) :: KDXRATIO ! x and y-direction Resolution ratio
INTEGER, INTENT(IN) :: KDYRATIO ! between model 2 and model 1
CHARACTER(LEN=4),DIMENSION(2),INTENT(IN):: HLBCX, HLBCY ! X- and Y-direc LBC
CHARACTER(LEN=*), INTENT(IN) :: HLUOUT ! output-listing file
REAL, DIMENSION(:,:), INTENT(IN) :: PZS1 ! model 1 orography
REAL, DIMENSION(:,:), INTENT(OUT) :: PZS2 ! interpolated orography with iterative correction
CHARACTER(LEN=6), INTENT(IN) :: HFIELD ! name of the field to nest
REAL, DIMENSION(:,:), INTENT(OUT),OPTIONAL :: PZS2_LS ! interpolated orography
!
!* 0.2 Declarations of local variables for print on FM file
!
INTEGER :: ILUOUT ! Logical unit number for the output listing
INTEGER :: IRESP ! Return codes in FM routines
!
REAL, DIMENSION(:,:), ALLOCATABLE :: ZZS2_LS ! interpolated orography
REAL, DIMENSION(:,:), ALLOCATABLE :: ZZS1 ! zs of model 1 at iteration n or n+1
REAL, DIMENSION(:,:), ALLOCATABLE :: ZZS2 ! averaged zs of model 2 at iteration n
REAL, DIMENSION(:,:), ALLOCATABLE :: ZDZS ! difference between PZS1 and ZZS2
!
INTEGER :: IXMIN, IXMAX ! indices to interpolate the
! modified orography on model 2
! domain to model 1 grid
INTEGER :: JI,JEPSX ! Loop index in x direction
INTEGER :: JJ,JEPSY ! Loop index in y direction
INTEGER :: JCOUNTER ! counter for iterative method
REAL :: ZRELAX ! relaxation factor
INTEGER :: JMAXITER = 2000 ! maximum number of iterations
!
INTEGER, DIMENSION(2) :: IZSMAX
INTEGER :: IMI ! current model index
!
INTEGER :: IXSIZE,IYSIZE
INTEGER :: INFO_ll ! error return code
!-------------------------------------------------------------------------------
!
!* 1. PROLOGUE:
! ---------
!
IMI = GET_CURRENT_MODEL_INDEX()
CALL GOTO_MODEL(2)
CALL GO_TOMODEL_ll(2,INFO_ll)
!
!
!* 1.2 recovers logical unit number of output listing
!
CALL FMLOOK_ll(HLUOUT,HLUOUT,ILUOUT,IRESP)
!
!-------------------------------------------------------------------------------
!
!* 2. COMPUTATION:
! ---------
!
!* 2.1 Purely interpolated zs:
! -----------------------
!
ALLOCATE(ZZS2_LS(SIZE(PZS2,1),SIZE(PZS2,2)))
!
CALL BIKHARDT (XBMX1,XBMX2,XBMX3,XBMX4,XBMY1,XBMY2,XBMY3,XBMY4, &
XBFX1,XBFX2,XBFX3,XBFX4,XBFY1,XBFY2,XBFY3,XBFY4, &
KXOR,KYOR,KXEND,KYEND,KDXRATIO,KDYRATIO,1, &
HLBCX,HLBCY,PZS1,ZZS2_LS)
CALL MPPDB_CHECK2D(ZZS2_LS,"SPAWN_ZS::ZZS2_LS",PRECISION)
!
!* 4.2 New zs:
! -------
!
!* we use an iterative method to insure the equality between large-scale
! orography and the average of fine orography, and to be sure not to have
! spurious cliffs near the coast (multiplication by xland during the
! iterative process).
!
IF (KDXRATIO/=1 .OR. KDYRATIO/=1) THEN
!
!* allocations
!
IXSIZE = KXEND-KXOR - 2*JPHEXT + 1
IYSIZE = KYEND-KYOR - 2*JPHEXT + 1
ALLOCATE(ZZS2(IXSIZE,IYSIZE))
ALLOCATE(ZDZS(IXSIZE,IYSIZE))
ALLOCATE(ZZS1(SIZE(PZS1,1),SIZE(PZS1,2)))
!
!* constants
!
ZRELAX=16./13. ! best relaxation for infinite aspect ratio.
! for dx=2, one should take 32./27. !!!
!
!* initializations of initial state
!
JCOUNTER=0
ZZS1(:,:)=PZS1(:,:)
!
!* iterative loop
!
DO
!
!* interpolation
!
CALL BIKHARDT (XBMX1,XBMX2,XBMX3,XBMX4,XBMY1,XBMY2,XBMY3,XBMY4, &
XBFX1,XBFX2,XBFX3,XBFX4,XBFY1,XBFY2,XBFY3,XBFY4, &
KXOR,KYOR,KXEND,KYEND,KDXRATIO,KDYRATIO,1, &
HLBCX,HLBCY,ZZS1,PZS2)
CALL MPPDB_CHECK2D(PZS2,"SPAWN_ZS::PZS2",PRECISION)
JCOUNTER=JCOUNTER+1
!
!* if orography is positive, it stays positive
!
DO JI=1,IXSIZE
DO JJ=1,IYSIZE
IF (PZS1(JI+KXOR,JJ+KYOR)>-1.E-15) &
PZS2((JI-1)*KDXRATIO+1+JPHEXT:JI*KDXRATIO+JPHEXT, &
(JJ-1)*KDYRATIO+1+JPHEXT:JJ*KDYRATIO+JPHEXT) = &
MAX( PZS2((JI-1)*KDXRATIO+1+JPHEXT:JI*KDXRATIO+JPHEXT, &
(JJ-1)*KDYRATIO+1+JPHEXT:JJ*KDYRATIO+JPHEXT), 0.)
END DO
END DO
CALL MPPDB_CHECK2D(PZS2,"SPAWN_ZS::PZS2",PRECISION)
!
!* computation of new averaged orography
!
ZZS2(:,:) = 0.
DO JI=1,IXSIZE
DO JJ=1,IYSIZE
DO JEPSX = (JI-1)*KDXRATIO+1+JPHEXT, JI*KDXRATIO+JPHEXT
DO JEPSY = (JJ-1)*KDYRATIO+1+JPHEXT, JJ*KDYRATIO+JPHEXT
ZZS2(JI,JJ) = ZZS2(JI,JJ) + PZS2(JEPSX,JEPSY)
END DO
END DO
END DO
END DO
ZZS2(:,:) = ZZS2(:,:) / (KDXRATIO*KDYRATIO)
!
ZDZS(:,:)=PZS1(KXOR+JPHEXT:KXEND-JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT)-ZZS2(:,:)
!
!* test to end the iterative process
!
IF (MAXVAL(ABS(ZDZS(:,:)))<1.E-3) EXIT
!
IF (JCOUNTER>=JMAXITER) THEN
WRITE(ILUOUT,FMT=*) 'SPAWN_ZS: convergence of ',TRIM(HFIELD), &
' NOT obtained after',JCOUNTER,' iterations'
WRITE(ILUOUT,FMT=*) TRIM(HFIELD), &
' is modified to insure egality of large scale and averaged fine field'
DO JI=1,IXSIZE
DO JJ=1,IYSIZE
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
DO JEPSX = (JI-1)*KDXRATIO+1+JPHEXT, JI*KDXRATIO+JPHEXT
DO JEPSY = (JJ-1)*KDYRATIO+1+JPHEXT, JJ*KDYRATIO+JPHEXT
PZS2(JEPSX,JEPSY) = PZS2(JEPSX,JEPSY) + ZDZS(JI,JJ)
END DO
END DO
END DO
END DO
!
EXIT
END IF
!
!* prints
!
IF (NVERB >=7) THEN
IZSMAX=MAXLOC(ABS(ZDZS(:,:)))
IF (MOD(JCOUNTER,500)==1) &
WRITE(ILUOUT,FMT='(A4,1X,A4,1X,A2,1X,A2,1X,A12,1X,A12,1X,A12)') &
'n IT','nDIV','I1','J1',' ZS1',' ZS2',' DZS'
WRITE(ILUOUT,FMT='(I4,1X,I4,1X,I2,1X,I2,1X,F12.7,1X,F12.7,1X,F12.7)')&
JCOUNTER,COUNT(ABS(ZDZS(:,:))>=1.E-3), &
IZSMAX(1)+KXOR,IZSMAX(2)+KYOR, &
PZS1(KXOR+IZSMAX(1),KYOR+IZSMAX(2)), &
ZZS2(IZSMAX(1),IZSMAX(2)), &
ZDZS(IZSMAX(1),IZSMAX(2))
END IF
!
!* correction of coarse orography
!
ZZS1(KXOR+JPHEXT:KXEND-JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT) = &
ZZS1(KXOR+JPHEXT:KXEND-JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT) + ZRELAX * ZDZS(:,:)
!
! extrapolations (X direction)
!
IF(KXOR==1 .AND. KXEND==SIZE(PZS1,1) .AND. HLBCX(1)=='CYCL' ) THEN
ZZS1(KXOR,KYOR+JPHEXT:KYEND-JPHEXT) = ZZS1(KXEND-JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT)
ZZS1(KXEND,KYOR+JPHEXT:KYEND-JPHEXT) = ZZS1(KXOR+JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT)
ZZS1(KXOR+JPHEXT-1,KYOR+JPHEXT:KYEND-JPHEXT) = &
2. * ZZS1(KXOR+JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT) - ZZS1(KXOR+JPHEXT+1,KYOR+JPHEXT:KYEND-JPHEXT)
ZZS1(KXOR+JPHEXT-2,KYOR+JPHEXT:KYEND-JPHEXT) = &
2. * ZZS1(KXOR+JPHEXT-1,KYOR+JPHEXT:KYEND-JPHEXT) - ZZS1(KXOR+JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT)
ZZS1(KXEND-JPHEXT+1,KYOR+JPHEXT:KYEND-JPHEXT) = &
2. * ZZS1(KXEND-JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT) - ZZS1(KXEND-JPHEXT-1,KYOR+JPHEXT:KYEND-JPHEXT)
ZZS1(KXEND-JPHEXT+2,KYOR+JPHEXT:KYEND-JPHEXT) = &
2. * ZZS1(KXEND-JPHEXT+1,KYOR+JPHEXT:KYEND-JPHEXT) - ZZS1(KXEND-JPHEXT,KYOR+JPHEXT:KYEND-JPHEXT)
END IF
!
! extrapolations (Y direction)
!
IXMIN=MAX(KXOR-1,1)
IXMAX=MIN(KXEND+1,SIZE(PZS1,1))
IF(KYOR==1 .AND. KYEND==SIZE(PZS1,2) .AND. HLBCY(1)=='CYCL' ) THEN
ZZS1(IXMIN:IXMAX,KYOR) = ZZS1(IXMIN:IXMAX,KYEND-JPHEXT)
ZZS1(IXMIN:IXMAX,KYEND) = ZZS1(IXMIN:IXMAX,KYOR+JPHEXT)
ZZS1(IXMIN:IXMAX,KYOR+JPHEXT-1) = &
2. * ZZS1(IXMIN:IXMAX,KYOR+JPHEXT) - ZZS1(IXMIN:IXMAX,KYOR+JPHEXT+1)
ZZS1(IXMIN:IXMAX,KYOR+JPHEXT-2) = &
2. * ZZS1(IXMIN:IXMAX,KYOR+JPHEXT-1) - ZZS1(IXMIN:IXMAX,KYOR+JPHEXT)
ZZS1(IXMIN:IXMAX,KYEND-JPHEXT+1) = &
2. * ZZS1(IXMIN:IXMAX,KYEND-JPHEXT) - ZZS1(IXMIN:IXMAX,KYEND-JPHEXT-1)
ZZS1(IXMIN:IXMAX,KYEND-JPHEXT+2) = &
2. * ZZS1(IXMIN:IXMAX,KYEND-JPHEXT+1) - ZZS1(IXMIN:IXMAX,KYEND-JPHEXT)
END IF
!
!* next iteration
!
END DO
!
CALL ZS_BOUNDARY(PZS2,ZZS2_LS)
!
WRITE(ILUOUT,FMT=*) 'convergence of ',TRIM(HFIELD),' obtained after ', &
JCOUNTER,' iterations'
!
DEALLOCATE(ZZS2)
DEALLOCATE(ZDZS)
DEALLOCATE(ZZS1)
END IF
!
IF (PRESENT(PZS2_LS)) PZS2_LS(:,:)=ZZS2_LS(:,:)
DEALLOCATE(ZZS2_LS)
!
CALL GOTO_MODEL(IMI)
CALL GO_TOMODEL_ll(IMI,INFO_ll)
!-------------------------------------------------------------------------------
END SUBROUTINE SPAWN_ZS
!