source: LMDZ6/branches/Amaury_dev/libf/dyn3d_common/inidissip.F90 @ 5118

Last change on this file since 5118 was 5118, checked in by abarral, 2 months ago

Replace iniprint.h by lmdz_iniprint.f90
(lint) along the way

  • 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: inidissip.F90 5118 2024-07-24 14:39:59Z abarral $
2
3SUBROUTINE inidissip(lstardis, nitergdiv, nitergrot, niterh, &
4        tetagdiv, tetagrot, tetatemp, vert_prof_dissip)
5  !=======================================================================
6  !   initialisation de la dissipation horizontale
7  !=======================================================================
8  !-----------------------------------------------------------------------
9  !   declarations:
10  !   -------------
11
12  USE control_mod, ONLY: dissip_period, iperiod
13  USE comconst_mod, ONLY: dissip_deltaz, dissip_factz, dissip_zref, &
14          dtdiss, dtvr, rad
15  USE comvert_mod, ONLY: preff, presnivs
16  USE lmdz_filtreg, ONLY: filtreg
17  USE lmdz_libmath, ONLY: minmax
18  USE lmdz_ran1, ONLY: ran1
19  USE lmdz_iniprint, ONLY: lunout, prt_level
20
21  IMPLICIT NONE
22  include "dimensions.h"
23  include "paramet.h"
24  include "comdissipn.h"
25
26  LOGICAL, INTENT(IN) :: lstardis
27  INTEGER, INTENT(IN) :: nitergdiv, nitergrot, niterh
28  REAL, INTENT(IN) :: tetagdiv, tetagrot, tetatemp
29
30  INTEGER, INTENT(IN) :: vert_prof_dissip
31  ! Vertical profile of horizontal dissipation
32  ! Allowed values:
33  ! 0: rational fraction, function of pressure
34  ! 1: tanh of altitude
35
36  ! Local variables:
37  REAL fact, zvert(llm), zz
38  REAL zh(ip1jmp1), zu(ip1jmp1), gx(ip1jmp1), divgra(ip1jmp1)
39  REAL zv(ip1jm), gy(ip1jm), deltap(ip1jmp1, llm)
40  REAL ullm, vllm, umin, vmin, zhmin, zhmax
41  REAL zllm
42
43  INTEGER l, ij, idum, ii
44  REAL tetamin
45  REAL pseudoz
46  CHARACTER (LEN = 80) :: abort_message
47
48  !-----------------------------------------------------------------------
49
50  !   calcul des valeurs propres des operateurs par methode iterrative:
51  !   -----------------------------------------------------------------
52
53  crot = -1.
54  cdivu = -1.
55  cdivh = -1.
56
57  !   calcul de la valeur propre de divgrad:
58  !   --------------------------------------
59  idum = 0
60  DO l = 1, llm
61    DO ij = 1, ip1jmp1
62      deltap(ij, l) = 1.
63    ENDDO
64  ENDDO
65
66  idum = -1
67  zh(1) = RAN1(idum) - .5
68  idum = 0
69  DO ij = 2, ip1jmp1
70    zh(ij) = RAN1(idum) - .5
71  ENDDO
72
73  CALL filtreg (zh, jjp1, 1, 2, 1, .TRUE., 1)
74
75  CALL minmax(iip1 * jjp1, zh, zhmin, zhmax)
76
77  IF (zhmin >= zhmax)     THEN
78    WRITE(lunout, *)'  Inidissip  zh min max  ', zhmin, zhmax
79    abort_message = 'probleme generateur alleatoire dans inidissip'
80    CALL abort_gcm('inidissip', abort_message, 1)
81  ENDIF
82
83  zllm = ABS(zhmax)
84  DO l = 1, 50
85    IF(lstardis) THEN
86      CALL divgrad2(1, zh, deltap, niterh, divgra)
87    ELSE
88      CALL divgrad (1, zh, niterh, divgra)
89    ENDIF
90
91    zllm = ABS(maxval(divgra))
92    zh = divgra / zllm
93  ENDDO
94
95  IF(lstardis) THEN
96    cdivh = 1. / zllm
97  ELSE
98    cdivh = zllm ** (-1. / niterh)
99  ENDIF
100
101  !   calcul des valeurs propres de gradiv (ii =1) et  nxgrarot(ii=2)
102  !   -----------------------------------------------------------------
103  WRITE(lunout, *)'inidissip: calcul des valeurs propres'
104
105  DO    ii = 1, 2
106
107    DO ij = 1, ip1jmp1
108      zu(ij) = RAN1(idum) - .5
109    ENDDO
110    CALL filtreg (zu, jjp1, 1, 2, 1, .TRUE., 1)
111    DO ij = 1, ip1jm
112      zv(ij) = RAN1(idum) - .5
113    ENDDO
114    CALL filtreg (zv, jjm, 1, 2, 1, .FALSE., 1)
115
116    CALL minmax(iip1 * jjp1, zu, umin, ullm)
117    CALL minmax(iip1 * jjm, zv, vmin, vllm)
118
119    ullm = ABS (ullm)
120    vllm = ABS (vllm)
121
122    DO    l = 1, 50
123      IF(ii==1) THEN
124        !cccc             CALL covcont( 1,zu,zv,zu,zv )
125        IF(lstardis) THEN
126          CALL gradiv2(1, zu, zv, nitergdiv, gx, gy)
127        ELSE
128          CALL gradiv (1, zu, zv, nitergdiv, gx, gy)
129        ENDIF
130      ELSE
131        IF(lstardis) THEN
132          CALL nxgraro2(1, zu, zv, nitergrot, gx, gy)
133        ELSE
134          CALL nxgrarot(1, zu, zv, nitergrot, gx, gy)
135        ENDIF
136      ENDIF
137
138      zllm = max(abs(maxval(gx)), abs(maxval(gy)))
139      zu = gx / zllm
140      zv = gy / zllm
141    end DO
142
143    IF (ii==1) THEN
144      IF(lstardis) THEN
145        cdivu = 1. / zllm
146      ELSE
147        cdivu = zllm **(-1. / nitergdiv)
148      ENDIF
149    ELSE
150      IF(lstardis) THEN
151        crot = 1. / zllm
152      ELSE
153        crot = zllm **(-1. / nitergrot)
154      ENDIF
155    ENDIF
156
157  end DO
158
159  !   petit test pour les operateurs non star:
160  !   ----------------------------------------
161
162  !     IF(.NOT.lstardis) THEN
163  fact = rad * 24. / REAL(jjm)
164  fact = fact * fact
165  WRITE(lunout, *)'inidissip: coef u ', fact / cdivu, 1. / cdivu
166  WRITE(lunout, *)'inidissip: coef r ', fact / crot, 1. / crot
167  WRITE(lunout, *)'inidissip: coef h ', fact / cdivh, 1. / cdivh
168  !     ENDIF
169
170  !-----------------------------------------------------------------------
171  !   variation verticale du coefficient de dissipation:
172  !   --------------------------------------------------
173
174  IF (vert_prof_dissip == 1) THEN
175    do l = 1, llm
176      pseudoz = 8. * log(preff / presnivs(l))
177      zvert(l) = 1 + &
178              (tanh((pseudoz - dissip_zref) / dissip_deltaz) + 1.) / 2. &
179                      * (dissip_factz - 1.)
180    enddo
181  else
182    DO l = 1, llm
183      zvert(l) = 1.
184    ENDDO
185    fact = 2.
186    DO l = 1, llm
187      zz = 1. - preff / presnivs(l)
188      zvert(l) = fact - (fact - 1.) / (1. + zz * zz)
189    ENDDO
190  ENDIF
191
192  WRITE(lunout, *)'inidissip: Constantes de temps de la diffusion horizontale'
193
194  tetamin = 1.e+6
195
196  DO l = 1, llm
197    tetaudiv(l) = zvert(l) / tetagdiv
198    tetaurot(l) = zvert(l) / tetagrot
199    tetah(l) = zvert(l) / tetatemp
200
201    IF(tetamin> (1. / tetaudiv(l))) tetamin = 1. / tetaudiv(l)
202    IF(tetamin> (1. / tetaurot(l))) tetamin = 1. / tetaurot(l)
203    IF(tetamin> (1. / tetah(l))) tetamin = 1. / tetah(l)
204  ENDDO
205
206  ! If dissip_period=0 calculate value for dissipation period, else keep value read from gcm.def
207  IF (dissip_period == 0) THEN
208    dissip_period = INT(tetamin / (2. * dtvr * iperiod)) * iperiod
209    WRITE(lunout, *)'inidissip: tetamin dtvr iperiod dissip_period(intermed) ', tetamin, dtvr, iperiod, dissip_period
210    dissip_period = MAX(iperiod, dissip_period)
211  END IF
212
213  dtdiss = dissip_period * dtvr
214  WRITE(lunout, *)'inidissip: dissip_period=', dissip_period, ' dtdiss=', dtdiss, ' dtvr=', dtvr
215
216  DO l = 1, llm
217    WRITE(lunout, *)zvert(l), dtdiss * tetaudiv(l), dtdiss * tetaurot(l), &
218            dtdiss * tetah(l)
219  ENDDO
220
221END SUBROUTINE inidissip
Note: See TracBrowser for help on using the repository browser.