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

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

rename modules properly lmdz_*
move ismin, ismax, minmax into new lmdz_libmath.f90
(lint) uppercase fortran keywords

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