source: LMDZ6/branches/Amaury_dev/libf/dyn3d/top_bound.F90 @ 5136

Last change on this file since 5136 was 5136, checked in by abarral, 8 weeks 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
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1! $Id: top_bound.F90 5136 2024-07-28 14:17:54Z abarral $
2
3SUBROUTINE top_bound(vcov, ucov, teta, masse, dt)
4
5  USE comconst_mod, ONLY: iflag_top_bound, mode_top_bound, &
6          tau_top_bound
7  USE comvert_mod, ONLY: presnivs, preff, scaleheight
8  USE lmdz_iniprint, ONLY: lunout, prt_level
9  USE lmdz_comdissipn, ONLY: tetaudiv, tetaurot, tetah, cdivu, crot, cdivh
10  USE lmdz_comgeom2
11
12  IMPLICIT NONE
13  !
14  INCLUDE "dimensions.h"
15  INCLUDE "paramet.h"
16
17
18  ! ..  DISSIPATION LINEAIRE A HAUT NIVEAU, RUN MESO,
19  ! F. LOTT DEC. 2006
20  !                             (  10/12/06  )
21
22  !=======================================================================
23  !
24  !   Auteur:  F. LOTT
25  !   -------
26  !
27  !   Objet:
28  !   ------
29  !
30  !   Dissipation linéaire (ex top_bound de la physique)
31  !
32  !=======================================================================
33
34  ! top_bound sponge layer model:
35  ! Quenching is modeled as: A(t)=Am+A0*exp(-lambda*t)
36  ! where Am is the zonal average of the field (or zero), and lambda the inverse
37  ! of the characteristic quenching/relaxation time scale
38  ! Thus, assuming Am to be time-independent, field at time t+dt is given by:
39  ! A(t+dt)=A(t)-(A(t)-Am)*(1-exp(-lambda*t))
40  ! Moreover lambda can be a function of model level (see below), and relaxation
41  ! can be toward the average zonal field or just zero (see below).
42
43  ! NB: top_bound sponge is only called from leapfrog if ok_strato=.TRUE.
44
45  ! sponge parameters: (loaded/set in conf_gcm.F ; stored in comconst_mod)
46  !    iflag_top_bound=0 for no sponge
47  !    iflag_top_bound=1 for sponge over 4 topmost layers
48  !    iflag_top_bound=2 for sponge from top to ~1% of top layer pressure
49  !    mode_top_bound=0: no relaxation
50  !    mode_top_bound=1: u and v relax towards 0
51  !    mode_top_bound=2: u and v relax towards their zonal mean
52  !    mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean
53  !    tau_top_bound : inverse of charactericstic relaxation time scale at
54  !                   the topmost layer (Hz)
55
56  !   Arguments:
57  !   ----------
58
59  REAL, INTENT(INOUT) :: ucov(iip1, jjp1, llm) ! covariant zonal wind
60  REAL, INTENT(INOUT) :: vcov(iip1, jjm, llm) ! covariant meridional wind
61  REAL, INTENT(INOUT) :: teta(iip1, jjp1, llm) ! potential temperature
62  REAL, INTENT(IN) :: masse(iip1, jjp1, llm) ! mass of atmosphere
63  REAL, INTENT(IN) :: dt ! time step (s) of sponge model
64
65  !   Local:
66  !   ------
67
68  REAL :: massebx(iip1, jjp1, llm), masseby(iip1, jjm, llm), zm
69  REAL :: uzon(jjp1, llm), vzon(jjm, llm), tzon(jjp1, llm)
70
71  INTEGER :: i
72  REAL, SAVE :: rdamp(llm) ! quenching coefficient
73  REAL, save :: lambda(llm) ! inverse or quenching time scale (Hz)
74
75  LOGICAL, SAVE :: first = .TRUE.
76
77  INTEGER :: j, l
78
79  IF (iflag_top_bound==0) return
80
81  IF (first) THEN
82    IF (iflag_top_bound==1) THEN
83      ! sponge quenching over the topmost 4 atmospheric layers
84      lambda(:) = 0.
85      lambda(llm) = tau_top_bound
86      lambda(llm - 1) = tau_top_bound / 2.
87      lambda(llm - 2) = tau_top_bound / 4.
88      lambda(llm - 3) = tau_top_bound / 8.
89    ELSE IF (iflag_top_bound==2) THEN
90      ! sponge quenching over topmost layers down to pressures which are
91      ! higher than 100 times the topmost layer pressure
92      lambda(:) = tau_top_bound &
93              * max(presnivs(llm) / presnivs(:) - 0.01, 0.)
94    endif
95
96    ! quenching coefficient rdamp(:)
97    ! rdamp(:)=dt*lambda(:) ! Explicit Euler approx.
98    rdamp(:) = 1. - exp(-lambda(:) * dt)
99
100    WRITE(lunout, *)'TOP_BOUND mode', mode_top_bound
101    WRITE(lunout, *)'Sponge layer coefficients'
102    WRITE(lunout, *)'p (Pa)  z(km)  tau(s)   1./tau (Hz)'
103    do l = 1, llm
104      IF (rdamp(l)/=0.) THEN
105        WRITE(lunout, '(6(1pe12.4,1x))') &
106                presnivs(l), log(preff / presnivs(l)) * scaleheight, &
107                1. / lambda(l), lambda(l)
108      endif
109    enddo
110    first = .FALSE.
111  ENDIF ! of if (first)
112
113  CALL massbar(masse, massebx, masseby)
114
115  ! compute zonal average of vcov and u
116  IF (mode_top_bound>=2) THEN
117    do l = 1, llm
118      do j = 1, jjm
119        vzon(j, l) = 0.
120        zm = 0.
121        do i = 1, iim
122          ! NB: we can work using vcov zonal mean rather than v since the
123          ! cv coefficient (which relates the two) only varies with latitudes
124          vzon(j, l) = vzon(j, l) + vcov(i, j, l) * masseby(i, j, l)
125          zm = zm + masseby(i, j, l)
126        enddo
127        vzon(j, l) = vzon(j, l) / zm
128      enddo
129    enddo
130
131    do l = 1, llm
132      do j = 2, jjm ! excluding poles
133        uzon(j, l) = 0.
134        zm = 0.
135        do i = 1, iim
136          uzon(j, l) = uzon(j, l) + massebx(i, j, l) * ucov(i, j, l) / cu(i, j)
137          zm = zm + massebx(i, j, l)
138        enddo
139        uzon(j, l) = uzon(j, l) / zm
140      enddo
141    enddo
142  else ! ucov and vcov will relax towards 0
143    vzon(:, :) = 0.
144    uzon(:, :) = 0.
145  ENDIF ! of if (mode_top_bound.ge.2)
146
147  ! compute zonal average of potential temperature, if necessary
148  IF (mode_top_bound>=3) THEN
149    do l = 1, llm
150      do j = 2, jjm ! excluding poles
151        zm = 0.
152        tzon(j, l) = 0.
153        do i = 1, iim
154          tzon(j, l) = tzon(j, l) + teta(i, j, l) * masse(i, j, l)
155          zm = zm + masse(i, j, l)
156        enddo
157        tzon(j, l) = tzon(j, l) / zm
158      enddo
159    enddo
160  ENDIF ! of if (mode_top_bound.ge.3)
161
162  IF (mode_top_bound>=1) THEN
163    ! Apply sponge quenching on vcov:
164    do l = 1, llm
165      do i = 1, iip1
166        do j = 1, jjm
167          vcov(i, j, l) = vcov(i, j, l) &
168                  - rdamp(l) * (vcov(i, j, l) - vzon(j, l))
169        enddo
170      enddo
171    enddo
172
173    ! Apply sponge quenching on ucov:
174    do l = 1, llm
175      do i = 1, iip1
176        do j = 2, jjm ! excluding poles
177          ucov(i, j, l) = ucov(i, j, l) &
178                  - rdamp(l) * (ucov(i, j, l) - cu(i, j) * uzon(j, l))
179        enddo
180      enddo
181    enddo
182  ENDIF ! of if (mode_top_bound.ge.1)
183
184  IF (mode_top_bound>=3) THEN
185    ! Apply sponge quenching on teta:
186    do l = 1, llm
187      do i = 1, iip1
188        do j = 2, jjm ! excluding poles
189          teta(i, j, l) = teta(i, j, l) &
190                  - rdamp(l) * (teta(i, j, l) - tzon(j, l))
191        enddo
192      enddo
193    enddo
194  ENDIF ! of if (mode_top_bound.ge.3)
195
196END SUBROUTINE top_bound
Note: See TracBrowser for help on using the repository browser.