source: LMDZ6/branches/Amaury_dev/libf/dyn3dmem/friction_loc.f90 @ 5136

Last change on this file since 5136 was 5136, checked in by abarral, 3 months ago

Put comgeom.h, comgeom2.h into modules

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 5.3 KB
Line 
1! $Id: friction_p.F 1299 2010-01-20 14:27:21Z fairhead $
2
3!=======================================================================
4SUBROUTINE friction_loc(ucov, vcov, pdt)
5  USE parallel_lmdz
6  USE control_mod
7  USE IOIPSL
8  USE comconst_mod, ONLY: pi
9  USE lmdz_iniprint, ONLY: lunout, prt_level
10  USE lmdz_academic, ONLY: tetarappel, knewt_t, kfrict, knewt_g, clat4
11  USE lmdz_comgeom2
12
13  IMPLICIT NONE
14
15  !=======================================================================
16
17  !   Friction for the Newtonian case:
18  !   --------------------------------
19  !    2 possibilities (depending on flag 'friction_type'
20  ! friction_type=0 : A friction that is only applied to the lowermost
21  !                   atmospheric layer
22  ! friction_type=1 : Friction applied on all atmospheric layer (but
23  !   (default)       with stronger magnitude near the surface; see
24  !                   iniacademic.F)
25  !=======================================================================
26
27  INCLUDE "dimensions.h"
28  INCLUDE "paramet.h"
29
30  ! arguments:
31  REAL, INTENT(INOUT) :: ucov(iip1, jjb_u:jje_u, llm)
32  REAL, INTENT(INOUT) :: vcov(iip1, jjb_v:jje_v, llm)
33  REAL, INTENT(IN) :: pdt ! time step
34
35  ! local variables:
36
37  REAL :: modv(iip1, jjb_u:jje_u), zco, zsi
38  REAL :: vpn, vps, upoln, upols, vpols, vpoln
39  REAL :: u2(iip1, jjb_u:jje_u), v2(iip1, jjb_v:jje_v)
40  INTEGER :: i, j, l
41  REAL, PARAMETER :: cfric = 1.e-5
42  LOGICAL, SAVE :: firstcall = .TRUE.
43  INTEGER, SAVE :: friction_type = 1
44  CHARACTER(len = 20) :: modname = "friction_p"
45  CHARACTER(len = 80) :: abort_message
46  !$OMP THREADPRIVATE(firstcall,friction_type)
47  INTEGER :: jjb, jje
48
49  !$OMP SINGLE
50  IF (firstcall) THEN
51    ! set friction type
52    CALL getin("friction_type", friction_type)
53    IF ((friction_type<0).OR.(friction_type>1)) THEN
54      abort_message = "wrong friction type"
55      WRITE(lunout, *)'Friction: wrong friction type', friction_type
56      CALL abort_gcm(modname, abort_message, 42)
57    endif
58    firstcall = .FALSE.
59  ENDIF
60  !$OMP END SINGLE COPYPRIVATE(friction_type,firstcall)
61
62  IF (friction_type==0) then ! friction on first layer only
63    !$OMP SINGLE
64    !   calcul des composantes au carre du vent naturel
65    jjb = jj_begin
66    jje = jj_end + 1
67    IF (pole_sud) jje = jj_end
68
69    do j = jjb, jje
70      do i = 1, iip1
71        u2(i, j) = ucov(i, j, 1) * ucov(i, j, 1) * unscu2(i, j)
72      enddo
73    enddo
74
75    jjb = jj_begin - 1
76    jje = jj_end + 1
77    IF (pole_nord) jjb = jj_begin
78    IF (pole_sud) jje = jj_end - 1
79
80    do j = jjb, jje
81      do i = 1, iip1
82        v2(i, j) = vcov(i, j, 1) * vcov(i, j, 1) * unscv2(i, j)
83      enddo
84    enddo
85
86    !   calcul du module de V en dehors des poles
87    jjb = jj_begin
88    jje = jj_end + 1
89    IF (pole_nord) jjb = jj_begin + 1
90    IF (pole_sud) jje = jj_end - 1
91
92    do j = jjb, jje
93      do i = 2, iip1
94        modv(i, j) = sqrt(0.5 * (u2(i - 1, j) + u2(i, j) + v2(i, j - 1) + v2(i, j)))
95      enddo
96      modv(1, j) = modv(iip1, j)
97    enddo
98
99    !   les deux composantes du vent au pole sont obtenues comme
100    !   premiers modes de fourier de v pres du pole
101    IF (pole_nord) THEN
102      upoln = 0.
103      vpoln = 0.
104
105      do i = 2, iip1
106        zco = cos(rlonv(i)) * (rlonu(i) - rlonu(i - 1))
107        zsi = sin(rlonv(i)) * (rlonu(i) - rlonu(i - 1))
108        vpn = vcov(i, 1, 1) / cv(i, 1)
109        upoln = upoln + zco * vpn
110        vpoln = vpoln + zsi * vpn
111      enddo
112      vpn = sqrt(upoln * upoln + vpoln * vpoln) / pi
113      do i = 1, iip1
114        ! modv(i,1)=vpn
115        modv(i, 1) = modv(i, 2)
116      enddo
117
118    ENDIF
119
120    IF (pole_sud) THEN
121      upols = 0.
122      vpols = 0.
123      do i = 2, iip1
124        zco = cos(rlonv(i)) * (rlonu(i) - rlonu(i - 1))
125        zsi = sin(rlonv(i)) * (rlonu(i) - rlonu(i - 1))
126        vps = vcov(i, jjm, 1) / cv(i, jjm)
127        upols = upols + zco * vps
128        vpols = vpols + zsi * vps
129      enddo
130      vps = sqrt(upols * upols + vpols * vpols) / pi
131      do i = 1, iip1
132        ! modv(i,jjp1)=vps
133        modv(i, jjp1) = modv(i, jjm)
134      enddo
135
136    ENDIF
137
138    !   calcul du frottement au sol.
139
140    jjb = jj_begin
141    jje = jj_end
142    IF (pole_nord) jjb = jj_begin + 1
143    IF (pole_sud) jje = jj_end - 1
144
145    do j = jjb, jje
146      do i = 1, iim
147        ucov(i, j, 1) = ucov(i, j, 1) &
148                - cfric * pdt * 0.5 * (modv(i + 1, j) + modv(i, j)) * ucov(i, j, 1)
149      enddo
150      ucov(iip1, j, 1) = ucov(1, j, 1)
151    enddo
152
153    jjb = jj_begin
154    jje = jj_end
155    IF (pole_sud) jje = jj_end - 1
156
157    do j = jjb, jje
158      do i = 1, iip1
159        vcov(i, j, 1) = vcov(i, j, 1) &
160                - cfric * pdt * 0.5 * (modv(i, j + 1) + modv(i, j)) * vcov(i, j, 1)
161      enddo
162      vcov(iip1, j, 1) = vcov(1, j, 1)
163    enddo
164    !$OMP END SINGLE
165  ENDIF ! of if (friction_type.EQ.0)
166
167  IF (friction_type==1) THEN
168    ! for ucov()
169    jjb = jj_begin
170    jje = jj_end
171    IF (pole_nord) jjb = jj_begin + 1
172    IF (pole_sud) jje = jj_end - 1
173
174    !$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
175    do l = 1, llm
176      ucov(1:iip1, jjb:jje, l) = ucov(1:iip1, jjb:jje, l) * &
177              (1. - pdt * kfrict(l))
178    enddo
179    !$OMP END DO NOWAIT
180
181    ! for vcoc()
182    jjb = jj_begin
183    jje = jj_end
184    IF (pole_sud) jje = jj_end - 1
185
186    !$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
187    do l = 1, llm
188      vcov(1:iip1, jjb:jje, l) = vcov(1:iip1, jjb:jje, l) * &
189              (1. - pdt * kfrict(l))
190    enddo
191    !$OMP END DO
192  ENDIF ! of if (friction_type.EQ.1)
193
194END SUBROUTINE friction_loc
195
Note: See TracBrowser for help on using the repository browser.