source: LMDZ6/branches/Amaury_dev/libf/dyn3d/check_isotopes.F90 @ 5159

Last change on this file since 5159 was 5159, checked in by abarral, 3 months ago

Put dimensions.h and paramet.h into modules

File size: 8.1 KB
Line 
1SUBROUTINE check_isotopes_seq(q, ip1jmp1, err_msg)
2   USE lmdz_strings, ONLY: maxlen, msg, strIdx, strStack, int2str, real2str
3   USE infotrac,    ONLY: nqtot, niso, nphas, isotope, isoCheck, iqIsoPha, isoSelect, &
4                          ntiso, iH2O, nzone, tracers, isoName,  itZonIso, getKey
5
6USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
7   IMPLICIT NONE
8
9   REAL,             INTENT(INOUT) :: q(ip1jmp1,llm,nqtot)
10   INTEGER,          INTENT(IN)    :: ip1jmp1
11   CHARACTER(LEN=*), INTENT(IN)    :: err_msg    !--- Error message to display
12   CHARACTER(LEN=maxlen) :: modname, msg1, nm(2)
13   INTEGER :: ixt, ipha, k, i, iq, iiso, izon, ieau, iqeau, iqpar
14   INTEGER, ALLOCATABLE ::   ix(:)
15   REAL,    ALLOCATABLE, SAVE :: tnat(:)
16   REAL    :: xtractot, xiiso, deltaD, q1, q2
17   REAL, PARAMETER :: borne     = 1e19,  &
18                      errmax    = 1e-8,  &       !--- Max. absolute error
19                      errmaxrel = 1e-3,  &       !--- Max. relative error
20                      qmin      = 1e-11, &
21                      deltaDmax =1000.0, &
22                      deltaDmin =-999.0, &
23                      ridicule  = 1e-12
24   INTEGER, SAVE :: iso_eau, iso_HDO, iso_O18, &
25                             iso_O17, iso_HTO
26   LOGICAL, SAVE :: first=.TRUE.
27   LOGICAL, PARAMETER :: tnat1=.TRUE.
28
29   modname='check_isotopes'
30   IF(.NOT.isoCheck)    RETURN                   !--- No need to check => finished
31   IF(isoSelect('H2O')) RETURN                   !--- No H2O isotopes group found
32   IF(niso == 0)        RETURN                   !--- No isotopes => finished
33   IF(first) THEN
34      iso_eau = strIdx(isoName,'H216O')
35      iso_HDO = strIdx(isoName,'HDO')
36      iso_O18 = strIdx(isoName,'H218O')
37      iso_O17 = strIdx(isoName,'H217O')
38      iso_HTO = strIdx(isoName,'HTO')
39      IF (tnat1) THEN
40              tnat(:)=1.0
41      else
42         IF(getKey('tnat', tnat)) CALL abort_gcm(modname, 'missing isotopic parameter', 1)
43      endif
44      first = .FALSE.
45   END IF
46   CALL msg('31: err_msg='//TRIM(err_msg), modname)
47
48   !--- CHECK FOR NaNs (FOR ALL THE ISOTOPES, INCLUDING GEOGRAPHIC TAGGING TRACERS)
49   modname = 'check_isotopes:iso_verif_noNaN'
50   DO ixt = 1, ntiso
51      DO ipha = 1, nphas
52         iq = iqIsoPha(ixt,ipha)
53         DO k = 1, llm
54            DO i = 1, ip1jmp1
55               IF(ABS(q(i,k,iq)) < borne) CYCLE
56               WRITE(msg1,'(s,"(",i0,",",i0,",",i0,") = ",ES12.4)')TRIM(isoName(ixt)),i,k,iq,q(i,k,iq)
57               CALL msg(msg1, modname)
58               CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1)
59            END DO
60         END DO
61      END DO
62   END DO
63
64   !--- CHECK CONSERVATION (MAIN ISOTOPE AND PARENT CONCENTRATIONS MUST BE EQUAL)
65   modname = 'check_isotopes:iso_verif_egalite'
66   ixt = iso_eau
67   IF(ixt /= 0) THEN
68      DO ipha = 1, nphas
69         iq = iqIsoPha(ixt,ipha)
70         iqpar = tracers(iq)%iqParent
71         DO k = 1, llm
72            DO i = 1, ip1jmp1
73               q1 = q(i,k,iqpar)
74               q2 = q(i,k,iq)
75!--- IMPROVEMENT in case at least one isotope is not negligible compared to the main isotopic form.
76!    This would be probably required to sum from smallest to highest concentrations ; the corresponding
77!    indices vector can be computed once only (in the initializations stage), using mean concentrations.
78!              q2 = SUM(q(i,k,tracers(iqPar)%iqDesc), DIM=3)
79               IF(ABS(q1-q2) <= errmax .OR. ABS(q1-q2)/MAX(MAX(ABS(q1),ABS(q2)),1e-18) <= errmaxrel) THEN
80                  q(i,k,iq) = q1                 !--- Bidouille pour convergence
81!                 q(i,k,tracers(iqPar)%iqDesc) = q(i,k,tracers(iqPar)%iqDesc) * q1 / q2
82                  CYCLE
83               END IF
84               CALL msg('ixt, iq = '//TRIM(strStack(int2str([ixt,iq]))), modname)
85               msg1 = '('//TRIM(strStack(int2str([i,k])))//')'
86               CALL msg(TRIM(tracers(iqpar)%name)//TRIM(msg1)//' = '//TRIM(real2str(q1)), modname)
87               CALL msg(TRIM(tracers(iq   )%name)//TRIM(msg1)//' = '//TRIM(real2str(q2)), modname)
88               CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1)
89            END DO
90         END DO
91      END DO
92   END IF
93
94   !--- CHECK DELTA ANOMALIES
95   modname = 'check_isotopes:iso_verif_aberrant'
96   ix = [ iso_HDO  ,   iso_O18 ]
97   nm = ['deltaD  ', 'deltaO18']
98   DO iiso = 1, SIZE(ix)
99      ixt = ix(iiso)
100      IF(ixt  == 0) CYCLE
101      DO ipha = 1, nphas
102         iq = iqIsoPha(ixt,ipha)
103         iqpar = tracers(iq)%iqParent
104         DO k = 1, llm
105            DO i = 1, ip1jmp1
106               q1 = q(i,k,iqpar)
107               q2 = q(i,k,iq)
108!--- IMPROVEMENT in case at least one isotope is not negligible compared to the main isotopic form.
109!    This would be probably required to sum from smallest to highest concentrations ; the corresponding
110!    indices vector can be computed once only (in the initializations stage), using mean concentrations.
111!              q2 = SUM(q(i,k,tracers(iqPar)%iqDesc), DIM=3)
112               IF(q2 <= qmin) CYCLE
113               deltaD = (q2/q1/tnat(ixt)-1.)*1000.
114               IF(deltaD <= deltaDmax .AND. deltaD >= deltaDmin) CYCLE
115               CALL msg('ixt, iq = '//TRIM(strStack(int2str([ixt,iq]))), modname)
116               msg1 = '('//TRIM(strStack(int2str([i,k])))//')'
117               CALL msg(TRIM(tracers(iqpar)%name)//TRIM(msg1)//' = '//TRIM(real2str(q1)), modname)
118               CALL msg(TRIM(tracers(iq   )%name)//TRIM(msg1)//' = '//TRIM(real2str(q2)), modname)
119               CALL msg(TRIM(nm(iiso))//TRIM(real2str(deltaD)), modname)
120               CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1)
121            END DO
122         END DO
123      END DO
124   END DO
125
126   IF(nzone == 0) RETURN
127
128   !--- CHECK FOR TAGGING TRACERS DELTAD ANOMALIES
129   modname = 'check_isotopes:iso_verif_aberrant'
130   IF(iso_eau /= 0 .AND. iso_HDO /= 0) THEN
131      DO izon = 1, nzone
132         ixt  = itZonIso(izon, iso_HDO)
133         ieau = itZonIso(izon, iso_eau)
134         DO ipha = 1, nphas
135            iq    = iqIsoPha(ixt,  ipha)
136            iqeau = iqIsoPha(ieau, ipha)
137            DO k = 1, llm
138               DO i = 1, ip1jmp1
139                  q1 = q(i,k,iqeau)
140                  q2 = q(i,k,iq)
141                  IF(q2<=qmin) CYCLE
142                  deltaD = (q2/q1/tnat(iso_HDO)-1.)*1000.
143                  IF(deltaD <= deltaDmax .AND. deltaD >= deltaDmin) CYCLE
144                  CALL msg('izon, ipha = '//TRIM(strStack(int2str([izon, ipha]))), modname)
145                  CALL msg( 'ixt, ieau = '//TRIM(strStack(int2str([ ixt, ieau]))), modname)
146                  msg1 = '('//TRIM(strStack(int2str([i,k])))//')'
147                  CALL msg(TRIM(tracers(iqeau)%name)//TRIM(msg1)//' = '//TRIM(real2str(q1)), modname)
148                  CALL msg(TRIM(tracers(iq   )%name)//TRIM(msg1)//' = '//TRIM(real2str(q2)), modname)
149                  CALL msg('deltaD = '//TRIM(real2str(deltaD)), modname)
150                  CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1)
151               END DO
152            END DO
153         END DO
154      END DO
155   END IF
156
157   !--- CHECK FOR TAGGING TRACERS CONSERVATION (PARENT AND TAGGING TRACERS SUM OVER ALL REGIONS MUST BE EQUAL)
158   DO iiso = 1, niso
159      DO ipha = 1, nphas
160         iq = iqIsoPha(iiso, ipha)
161         DO k = 1, llm
162            DO i = 1, ip1jmp1
163               xiiso = q(i,k,iq)
164               xtractot = SUM(q(i, k, iqIsoPha(itZonIso(1:nzone,iiso), ipha)))
165               IF(ABS(xtractot-xiiso) > errmax .AND. ABS(xtractot-xiiso)/MAX(MAX(ABS(xtractot),ABS(xiiso)),1e-18) > errmaxrel) THEN
166                  CALL msg('Error in iso_verif_aberrant trac: '//TRIM(err_msg))
167                  CALL msg('iiso, ipha = '//TRIM(strStack(int2str([iiso, ipha]))), modname)
168                  CALL msg('q('//TRIM(strStack(int2str([i,k])))//',:) = '//TRIM(strStack(real2str(q(i,k,:)))), modname)
169                  CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1)
170               END IF
171               IF(ABS(xtractot) <= ridicule) CYCLE
172               DO izon = 1, nzone
173                  q(i,k,iq) = q(i,k,iq) / xtractot * xiiso !--- Bidouille pour convergence
174               END DO
175            END DO
176         END DO
177      END DO
178   END DO
179
180END SUBROUTINE check_isotopes_seq
181
Note: See TracBrowser for help on using the repository browser.