| Directory: | ./ |
|---|---|
| File: | dyn/top_bound.f |
| Date: | 2022-01-11 19:19:34 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 53 | 60 | 88.3% |
| Branches: | 53 | 60 | 88.3% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | ! | ||
| 2 | ! $Id: top_bound.F 2600 2016-07-23 05:45:38Z emillour $ | ||
| 3 | ! | ||
| 4 | 490 | SUBROUTINE top_bound(vcov,ucov,teta,masse,dt) | |
| 5 | |||
| 6 | USE comconst_mod, ONLY: iflag_top_bound, mode_top_bound, | ||
| 7 | & tau_top_bound | ||
| 8 | USE comvert_mod, ONLY: presnivs, preff, scaleheight | ||
| 9 | |||
| 10 | IMPLICIT NONE | ||
| 11 | c | ||
| 12 | include "dimensions.h" | ||
| 13 | include "paramet.h" | ||
| 14 | include "comgeom2.h" | ||
| 15 | |||
| 16 | |||
| 17 | c .. DISSIPATION LINEAIRE A HAUT NIVEAU, RUN MESO, | ||
| 18 | C F. LOTT DEC. 2006 | ||
| 19 | c ( 10/12/06 ) | ||
| 20 | |||
| 21 | c======================================================================= | ||
| 22 | c | ||
| 23 | c Auteur: F. LOTT | ||
| 24 | c ------- | ||
| 25 | c | ||
| 26 | c Objet: | ||
| 27 | c ------ | ||
| 28 | c | ||
| 29 | c Dissipation lin�aire (ex top_bound de la physique) | ||
| 30 | c | ||
| 31 | c======================================================================= | ||
| 32 | |||
| 33 | ! top_bound sponge layer model: | ||
| 34 | ! Quenching is modeled as: A(t)=Am+A0*exp(-lambda*t) | ||
| 35 | ! where Am is the zonal average of the field (or zero), and lambda the inverse | ||
| 36 | ! of the characteristic quenching/relaxation time scale | ||
| 37 | ! Thus, assuming Am to be time-independent, field at time t+dt is given by: | ||
| 38 | ! A(t+dt)=A(t)-(A(t)-Am)*(1-exp(-lambda*t)) | ||
| 39 | ! Moreover lambda can be a function of model level (see below), and relaxation | ||
| 40 | ! can be toward the average zonal field or just zero (see below). | ||
| 41 | |||
| 42 | ! NB: top_bound sponge is only called from leapfrog if ok_strato=.true. | ||
| 43 | |||
| 44 | ! sponge parameters: (loaded/set in conf_gcm.F ; stored in comconst_mod) | ||
| 45 | ! iflag_top_bound=0 for no sponge | ||
| 46 | ! iflag_top_bound=1 for sponge over 4 topmost layers | ||
| 47 | ! iflag_top_bound=2 for sponge from top to ~1% of top layer pressure | ||
| 48 | ! mode_top_bound=0: no relaxation | ||
| 49 | ! mode_top_bound=1: u and v relax towards 0 | ||
| 50 | ! mode_top_bound=2: u and v relax towards their zonal mean | ||
| 51 | ! mode_top_bound=3: u,v and pot. temp. relax towards their zonal mean | ||
| 52 | ! tau_top_bound : inverse of charactericstic relaxation time scale at | ||
| 53 | ! the topmost layer (Hz) | ||
| 54 | |||
| 55 | |||
| 56 | ! | ||
| 57 | ! $Header$ | ||
| 58 | ! | ||
| 59 | ! Attention : ce fichier include est compatible format fixe/format libre | ||
| 60 | ! veillez à n'utiliser que des ! pour les commentaires | ||
| 61 | ! et à bien positionner les & des lignes de continuation | ||
| 62 | ! (les placer en colonne 6 et en colonne 73) | ||
| 63 | !----------------------------------------------------------------------- | ||
| 64 | ! INCLUDE comdissipn.h | ||
| 65 | |||
| 66 | REAL tetaudiv, tetaurot, tetah, cdivu, crot, cdivh | ||
| 67 | ! | ||
| 68 | COMMON/comdissipn/ tetaudiv(llm),tetaurot(llm),tetah(llm) , & | ||
| 69 | & cdivu, crot, cdivh | ||
| 70 | |||
| 71 | ! | ||
| 72 | ! Les parametres de ce common proviennent des calculs effectues dans | ||
| 73 | ! Inidissip . | ||
| 74 | ! | ||
| 75 | !----------------------------------------------------------------------- | ||
| 76 | ! | ||
| 77 | ! $Header$ | ||
| 78 | ! | ||
| 79 | ! | ||
| 80 | ! gestion des impressions de sorties et de d�bogage | ||
| 81 | ! lunout: unit� du fichier dans lequel se font les sorties | ||
| 82 | ! (par defaut 6, la sortie standard) | ||
| 83 | ! prt_level: niveau d'impression souhait� (0 = minimum) | ||
| 84 | ! | ||
| 85 | INTEGER lunout, prt_level | ||
| 86 | COMMON /comprint/ lunout, prt_level | ||
| 87 | |||
| 88 | c Arguments: | ||
| 89 | c ---------- | ||
| 90 | |||
| 91 | real,intent(inout) :: ucov(iip1,jjp1,llm) ! covariant zonal wind | ||
| 92 | real,intent(inout) :: vcov(iip1,jjm,llm) ! covariant meridional wind | ||
| 93 | real,intent(inout) :: teta(iip1,jjp1,llm) ! potential temperature | ||
| 94 | real,intent(in) :: masse(iip1,jjp1,llm) ! mass of atmosphere | ||
| 95 | real,intent(in) :: dt ! time step (s) of sponge model | ||
| 96 | |||
| 97 | c Local: | ||
| 98 | c ------ | ||
| 99 | |||
| 100 | REAL massebx(iip1,jjp1,llm),masseby(iip1,jjm,llm),zm | ||
| 101 | REAL uzon(jjp1,llm),vzon(jjm,llm),tzon(jjp1,llm) | ||
| 102 | |||
| 103 | integer i | ||
| 104 | REAL,SAVE :: rdamp(llm) ! quenching coefficient | ||
| 105 | real,save :: lambda(llm) ! inverse or quenching time scale (Hz) | ||
| 106 | |||
| 107 | LOGICAL,SAVE :: first=.true. | ||
| 108 | |||
| 109 | INTEGER j,l | ||
| 110 | |||
| 111 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 480 times.
|
480 | if (iflag_top_bound.eq.0) return |
| 112 | |||
| 113 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 479 times.
|
480 | if (first) then |
| 114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (iflag_top_bound.eq.1) then |
| 115 | ! sponge quenching over the topmost 4 atmospheric layers | ||
| 116 | ✗ | lambda(:)=0. | |
| 117 | ✗ | lambda(llm)=tau_top_bound | |
| 118 | ✗ | lambda(llm-1)=tau_top_bound/2. | |
| 119 | ✗ | lambda(llm-2)=tau_top_bound/4. | |
| 120 | ✗ | lambda(llm-3)=tau_top_bound/8. | |
| 121 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | else if (iflag_top_bound.eq.2) then |
| 122 | ! sponge quenching over topmost layers down to pressures which are | ||
| 123 | ! higher than 100 times the topmost layer pressure | ||
| 124 | lambda(:)=tau_top_bound | ||
| 125 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | s *max(presnivs(llm)/presnivs(:)-0.01,0.) |
| 126 | endif | ||
| 127 | |||
| 128 | ! quenching coefficient rdamp(:) | ||
| 129 | ! rdamp(:)=dt*lambda(:) ! Explicit Euler approx. | ||
| 130 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | rdamp(:)=1.-exp(-lambda(:)*dt) |
| 131 | |||
| 132 | 1 | write(lunout,*)'TOP_BOUND mode',mode_top_bound | |
| 133 | 1 | write(lunout,*)'Sponge layer coefficients' | |
| 134 | 1 | write(lunout,*)'p (Pa) z(km) tau(s) 1./tau (Hz)' | |
| 135 |
2/2✓ Branch 0 taken 39 times.
✓ Branch 1 taken 1 times.
|
40 | do l=1,llm |
| 136 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 32 times.
|
40 | if (rdamp(l).ne.0.) then |
| 137 | write(lunout,'(6(1pe12.4,1x))') | ||
| 138 | 7 | & presnivs(l),log(preff/presnivs(l))*scaleheight, | |
| 139 | 14 | & 1./lambda(l),lambda(l) | |
| 140 | endif | ||
| 141 | enddo | ||
| 142 | 1 | first=.false. | |
| 143 | endif ! of if (first) | ||
| 144 | |||
| 145 | 480 | CALL massbar(masse,massebx,masseby) | |
| 146 | |||
| 147 | ! compute zonal average of vcov and u | ||
| 148 |
1/2✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
|
480 | if (mode_top_bound.ge.2) then |
| 149 |
2/2✓ Branch 0 taken 18720 times.
✓ Branch 1 taken 480 times.
|
19200 | do l=1,llm |
| 150 |
2/2✓ Branch 0 taken 599040 times.
✓ Branch 1 taken 18720 times.
|
618240 | do j=1,jjm |
| 151 | 599040 | vzon(j,l)=0. | |
| 152 | zm=0. | ||
| 153 |
2/2✓ Branch 0 taken 19169280 times.
✓ Branch 1 taken 599040 times.
|
19768320 | do i=1,iim |
| 154 | ! NB: we can work using vcov zonal mean rather than v since the | ||
| 155 | ! cv coefficient (which relates the two) only varies with latitudes | ||
| 156 | 19169280 | vzon(j,l)=vzon(j,l)+vcov(i,j,l)*masseby(i,j,l) | |
| 157 | 19768320 | zm=zm+masseby(i,j,l) | |
| 158 | enddo | ||
| 159 | 617760 | vzon(j,l)=vzon(j,l)/zm | |
| 160 | enddo | ||
| 161 | enddo | ||
| 162 | |||
| 163 |
2/2✓ Branch 0 taken 480 times.
✓ Branch 1 taken 18720 times.
|
19200 | do l=1,llm |
| 164 |
2/2✓ Branch 0 taken 580320 times.
✓ Branch 1 taken 18720 times.
|
599520 | do j=2,jjm ! excluding poles |
| 165 | 580320 | uzon(j,l)=0. | |
| 166 | zm=0. | ||
| 167 |
2/2✓ Branch 0 taken 18570240 times.
✓ Branch 1 taken 580320 times.
|
19150560 | do i=1,iim |
| 168 | 18570240 | uzon(j,l)=uzon(j,l)+massebx(i,j,l)*ucov(i,j,l)/cu(i,j) | |
| 169 | 19150560 | zm=zm+massebx(i,j,l) | |
| 170 | enddo | ||
| 171 | 599040 | uzon(j,l)=uzon(j,l)/zm | |
| 172 | enddo | ||
| 173 | enddo | ||
| 174 | else ! ucov and vcov will relax towards 0 | ||
| 175 | ✗ | vzon(:,:)=0. | |
| 176 | ✗ | uzon(:,:)=0. | |
| 177 | endif ! of if (mode_top_bound.ge.2) | ||
| 178 | |||
| 179 | ! compute zonal average of potential temperature, if necessary | ||
| 180 |
1/2✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
|
480 | if (mode_top_bound.ge.3) then |
| 181 |
2/2✓ Branch 0 taken 18720 times.
✓ Branch 1 taken 480 times.
|
19200 | do l=1,llm |
| 182 |
2/2✓ Branch 0 taken 580320 times.
✓ Branch 1 taken 18720 times.
|
599520 | do j=2,jjm ! excluding poles |
| 183 | zm=0. | ||
| 184 | 580320 | tzon(j,l)=0. | |
| 185 |
2/2✓ Branch 0 taken 18570240 times.
✓ Branch 1 taken 580320 times.
|
19150560 | do i=1,iim |
| 186 | 18570240 | tzon(j,l)=tzon(j,l)+teta(i,j,l)*masse(i,j,l) | |
| 187 | 19150560 | zm=zm+masse(i,j,l) | |
| 188 | enddo | ||
| 189 | 599040 | tzon(j,l)=tzon(j,l)/zm | |
| 190 | enddo | ||
| 191 | enddo | ||
| 192 | endif ! of if (mode_top_bound.ge.3) | ||
| 193 | |||
| 194 |
1/2✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
|
480 | if (mode_top_bound.ge.1) then |
| 195 | ! Apply sponge quenching on vcov: | ||
| 196 |
2/2✓ Branch 0 taken 18720 times.
✓ Branch 1 taken 480 times.
|
19200 | do l=1,llm |
| 197 |
2/2✓ Branch 0 taken 617760 times.
✓ Branch 1 taken 18720 times.
|
636960 | do i=1,iip1 |
| 198 |
2/2✓ Branch 0 taken 19768320 times.
✓ Branch 1 taken 617760 times.
|
20404800 | do j=1,jjm |
| 199 | vcov(i,j,l)=vcov(i,j,l) | ||
| 200 | 20386080 | & -rdamp(l)*(vcov(i,j,l)-vzon(j,l)) | |
| 201 | enddo | ||
| 202 | enddo | ||
| 203 | enddo | ||
| 204 | |||
| 205 | ! Apply sponge quenching on ucov: | ||
| 206 |
2/2✓ Branch 0 taken 18720 times.
✓ Branch 1 taken 480 times.
|
19200 | do l=1,llm |
| 207 |
2/2✓ Branch 0 taken 617760 times.
✓ Branch 1 taken 18720 times.
|
636960 | do i=1,iip1 |
| 208 |
2/2✓ Branch 0 taken 19150560 times.
✓ Branch 1 taken 617760 times.
|
19787040 | do j=2,jjm ! excluding poles |
| 209 | ucov(i,j,l)=ucov(i,j,l) | ||
| 210 | 19768320 | & -rdamp(l)*(ucov(i,j,l)-cu(i,j)*uzon(j,l)) | |
| 211 | enddo | ||
| 212 | enddo | ||
| 213 | enddo | ||
| 214 | endif ! of if (mode_top_bound.ge.1) | ||
| 215 | |||
| 216 |
1/2✓ Branch 0 taken 480 times.
✗ Branch 1 not taken.
|
480 | if (mode_top_bound.ge.3) then |
| 217 | ! Apply sponge quenching on teta: | ||
| 218 |
2/2✓ Branch 0 taken 18720 times.
✓ Branch 1 taken 480 times.
|
19200 | do l=1,llm |
| 219 |
2/2✓ Branch 0 taken 617760 times.
✓ Branch 1 taken 18720 times.
|
636960 | do i=1,iip1 |
| 220 |
2/2✓ Branch 0 taken 19150560 times.
✓ Branch 1 taken 617760 times.
|
19787040 | do j=2,jjm ! excluding poles |
| 221 | teta(i,j,l)=teta(i,j,l) | ||
| 222 | 19768320 | & -rdamp(l)*(teta(i,j,l)-tzon(j,l)) | |
| 223 | enddo | ||
| 224 | enddo | ||
| 225 | enddo | ||
| 226 | endif ! of if (mode_top_bound.ge.3) | ||
| 227 | |||
| 228 | END | ||
| 229 |