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

Last change on this file since 5139 was 5134, checked in by abarral, 4 months ago

Replace academic.h, alpale.h, comdissip.h, comdissipn.h, comdissnew.h by modules
Remove unused clesph0.h

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