source: LMDZ6/trunk/libf/dyn3dmem/top_bound_loc.f90 @ 5281

Last change on this file since 5281 was 5281, checked in by abarral, 10 hours ago

Turn 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: 7.0 KB
RevLine 
[1793]1!
2! $Id: $
3!
[5246]4SUBROUTINE top_bound_loc(vcov,ucov,teta,masse,dt)
[5281]5  USE comgeom2_mod_h
[5280]6  USE comdissipn_mod_h
[5246]7  USE parallel_lmdz
8  USE comconst_mod, ONLY: iflag_top_bound, mode_top_bound, &
9        tau_top_bound
10  USE comvert_mod, ONLY: presnivs, preff, scaleheight
[2600]11
[5271]12  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5272]13USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
14          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
[5271]15IMPLICIT NONE
[5246]16  !
[5271]17
[5272]18
[1632]19
20
[5246]21  ! ..  DISSIPATION LINEAIRE A HAUT NIVEAU, RUN MESO,
22  ! F. LOTT DEC. 2006
23  !                             (  10/12/06  )
[1632]24
[5246]25  !=======================================================================
26  !
27  !   Auteur:  F. LOTT
28  !   -------
29  !
30  !   Objet:
31  !   ------
32  !
[5271]33  !   Dissipation lin�aire (ex top_bound de la physique)
[5246]34  !
35  !=======================================================================
[1632]36
[5246]37  ! top_bound sponge layer model:
38  ! Quenching is modeled as: A(t)=Am+A0*exp(-lambda*t)
39  ! where Am is the zonal average of the field (or zero), and lambda the inverse
40  ! of the characteristic quenching/relaxation time scale
41  ! Thus, assuming Am to be time-independent, field at time t+dt is given by:
42  ! A(t+dt)=A(t)-(A(t)-Am)*(1-exp(-lambda*t))
43  ! Moreover lambda can be a function of model level (see below), and relaxation
44  ! can be toward the average zonal field or just zero (see below).
[1793]45
[5246]46  ! NB: top_bound sponge is only called from leapfrog if ok_strato=.true.
[1793]47
[5246]48  ! sponge parameters: (loaded/set in conf_gcm.F ; stored in comconst_mod)
49  !    iflag_top_bound=0 for no sponge
50  !    iflag_top_bound=1 for sponge over 4 topmost layers
51  !    iflag_top_bound=2 for sponge from top to ~1% of top layer pressure
52  !    mode_top_bound=0: no relaxation
53  !    mode_top_bound=1: u and v relax towards 0
54  !    mode_top_bound=2: u and v relax towards their zonal mean
55  !    mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean
56  !    tau_top_bound : inverse of charactericstic relaxation time scale at
57  !                   the topmost layer (Hz)
[1793]58
59
[5246]60  INCLUDE "iniprint.h"
[1632]61
[5246]62  !   Arguments:
63  !   ----------
[1632]64
[5246]65  real,intent(inout) :: ucov(iip1,jjb_u:jje_u,llm) ! covariant zonal wind
66  real,intent(inout) :: vcov(iip1,jjb_v:jje_v,llm) ! covariant meridional wind
67  real,intent(inout) :: teta(iip1,jjb_u:jje_u,llm) ! potential temperature
68  real,intent(in) :: masse(iip1,jjb_u:jje_u,llm) ! mass of atmosphere
69  real,intent(in) :: dt ! time step (s) of sponge model
[1632]70
[5246]71   ! REAL dv(iip1,jjb_v:jje_v,llm),du(iip1,jjb_u:jje_u,llm)
72   ! REAL dh(iip1,jjb_u:jje_u,llm)
[1793]73
[5246]74  !   Local:
75  !   ------
76  REAL :: massebx(iip1,jjb_u:jje_u,llm),masseby(iip1,jjb_v:jje_v,llm)
77  REAL :: zm
78  REAL :: uzon(jjb_u:jje_u,llm),vzon(jjb_v:jje_v,llm)
79  REAL :: tzon(jjb_u:jje_u,llm)
[1632]80
[5246]81  integer :: i
82  REAL,SAVE :: rdamp(llm)
83  real,save :: lambda(llm) ! inverse or quenching time scale (Hz)
84  LOGICAL,SAVE :: first=.true.
85  INTEGER :: j,l,jjb,jje
[1632]86
[1793]87
[5246]88  if (iflag_top_bound == 0) return
[1793]89
[5246]90  if (first) then
91!$OMP BARRIER
92!$OMP MASTER
93     if (iflag_top_bound == 1) then
94  ! sponge quenching over the topmost 4 atmospheric layers
95         lambda(:)=0.
96         lambda(llm)=tau_top_bound
97         lambda(llm-1)=tau_top_bound/2.
98         lambda(llm-2)=tau_top_bound/4.
99         lambda(llm-3)=tau_top_bound/8.
100     else if (iflag_top_bound == 2) then
101  ! sponge quenching over topmost layers down to pressures which are
102  ! higher than 100 times the topmost layer pressure
103         lambda(:)=tau_top_bound &
104               *max(presnivs(llm)/presnivs(:)-0.01,0.)
105     endif
[1793]106
[5246]107  ! quenching coefficient rdamp(:)
108      ! rdamp(:)=dt*lambda(:) ! Explicit Euler approx.
109     rdamp(:)=1.-exp(-lambda(:)*dt)
[1632]110
[5246]111     write(lunout,*)'TOP_BOUND mode',mode_top_bound
112     write(lunout,*)'Sponge layer coefficients'
113     write(lunout,*)'p (Pa)  z(km)  tau(s)   1./tau (Hz)'
114     do l=1,llm
115       if (rdamp(l).ne.0.) then
116         write(lunout,'(6(1pe12.4,1x))') &
117               presnivs(l),log(preff/presnivs(l))*scaleheight, &
118               1./lambda(l),lambda(l)
119       endif
120     enddo
121     first=.false.
122!$OMP END MASTER
123!$OMP BARRIER
124  endif ! of if (first)
[1632]125
126
[5246]127  CALL massbar_loc(masse,massebx,masseby)
[1632]128
[5246]129  ! ! compute zonal average of vcov (or set it to zero)
130  if (mode_top_bound.ge.2) then
131   jjb=jj_begin
132   jje=jj_end
133   IF (pole_sud) jje=jj_end-1
134!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
135   do l=1,llm
136    do j=jjb,jje
137      zm=0.
138      vzon(j,l)=0
139      do i=1,iim
140  ! NB: we can work using vcov zonal mean rather than v since the
141  ! cv coefficient (which relates the two) only varies with latitudes
142        vzon(j,l)=vzon(j,l)+vcov(i,j,l)*masseby(i,j,l)
143        zm=zm+masseby(i,j,l)
144      enddo
145      vzon(j,l)=vzon(j,l)/zm
146    enddo
147   enddo
148!$OMP END DO NOWAIT
149  else
150!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
151   do l=1,llm
152     vzon(:,l)=0.
153   enddo
154!$OMP END DO NOWAIT
155  endif ! of if (mode_top_bound.ge.2)
[1632]156
[5246]157  ! ! compute zonal average of u (or set it to zero)
158  if (mode_top_bound.ge.2) then
159   jjb=jj_begin
160   jje=jj_end
161   IF (pole_nord) jjb=jj_begin+1
162   IF (pole_sud)  jje=jj_end-1
163!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
164   do l=1,llm
165    do j=jjb,jje
166      uzon(j,l)=0.
167      zm=0.
168      do i=1,iim
169        uzon(j,l)=uzon(j,l)+massebx(i,j,l)*ucov(i,j,l)/cu(i,j)
170        zm=zm+massebx(i,j,l)
171      enddo
172      uzon(j,l)=uzon(j,l)/zm
173    enddo
174   enddo
175!$OMP END DO NOWAIT
176  else
177!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
178   do l=1,llm
179     uzon(:,l)=0.
180   enddo
181!$OMP END DO NOWAIT
182  endif ! of if (mode_top_bound.ge.2)
[1632]183
[5246]184  ! ! compute zonal average of potential temperature, if necessary
185  if (mode_top_bound.ge.3) then
186   jjb=jj_begin
187   jje=jj_end
188   IF (pole_nord) jjb=jj_begin+1
189   IF (pole_sud)  jje=jj_end-1
190!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
191   do l=1,llm
192    do j=jjb,jje
193      zm=0.
194      tzon(j,l)=0.
195      do i=1,iim
196        tzon(j,l)=tzon(j,l)+teta(i,j,l)*masse(i,j,l)
197        zm=zm+masse(i,j,l)
198      enddo
199      tzon(j,l)=tzon(j,l)/zm
200    enddo
201   enddo
202!$OMP END DO NOWAIT
203  endif ! of if (mode_top_bound.ge.3)
[1632]204
[5246]205  if (mode_top_bound.ge.1) then
206   ! ! Apply sponge quenching on vcov:
207   jjb=jj_begin
208   jje=jj_end
209   IF (pole_sud) jje=jj_end-1
[1632]210
[5246]211!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
212   do l=1,llm
213    do j=jjb,jje
214      do i=1,iip1
215        vcov(i,j,l)=vcov(i,j,l) &
216              -rdamp(l)*(vcov(i,j,l)-vzon(j,l))
217      enddo
218    enddo
219   enddo
220!$OMP END DO NOWAIT
[1793]221
[5246]222   ! ! Apply sponge quenching on ucov:
223   jjb=jj_begin
224   jje=jj_end
225   IF (pole_nord) jjb=jj_begin+1
226   IF (pole_sud)  jje=jj_end-1
[1793]227
[5246]228!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
229   do l=1,llm
230    do j=jjb,jje
231      do i=1,iip1
232        ucov(i,j,l)=ucov(i,j,l) &
233              -rdamp(l)*(ucov(i,j,l)-cu(i,j)*uzon(j,l))
234      enddo
235   enddo
236   enddo
237!$OMP END DO NOWAIT
238  endif ! of if (mode_top_bound.ge.1)
[1793]239
[5246]240  if (mode_top_bound.ge.3) then
241   ! ! Apply sponge quenching on teta:
242   jjb=jj_begin
243   jje=jj_end
244   IF (pole_nord) jjb=jj_begin+1
245   IF (pole_sud)  jje=jj_end-1
[1793]246
[5246]247!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
248   do l=1,llm
249    do j=jjb,jje
250      do i=1,iip1
251        teta(i,j,l)=teta(i,j,l) &
252              -rdamp(l)*(teta(i,j,l)-tzon(j,l))
253      enddo
254   enddo
255   enddo
256!$OMP END DO NOWAIT
257  endif ! of if (mode_top_bond.ge.3)
258
259END SUBROUTINE top_bound_loc
Note: See TracBrowser for help on using the repository browser.