Changeset 4143 for LMDZ6/trunk/libf/dyn3dmem/check_isotopes_loc.F90
- Timestamp:
- May 9, 2022, 12:35:40 PM (2 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/trunk/libf/dyn3dmem/check_isotopes_loc.F90
r4142 r4143 1 subroutine check_isotopes(q,ijb,ije,err_msg) 2 USE infotrac, ONLY: nqtot, nqo, niso, ntraciso, nzone, 3 & use_iso, ntraceurs_zone, 4 & iqiso, indnum_fn_num, index_trac, tnat 5 USE parallel_lmdz 6 implicit none 1 SUBROUTINE check_isotopes(q, ijb, ije, err_msg) 2 USE parallel_lmdz 3 USE strings_mod, ONLY: maxlen, msg, strIdx, strStack, int2str, real2str 4 USE infotrac, ONLY: nqtot, niso, nphas, isotope, isoCheck, iqIsoPha, isoSelect, & 5 ntiso, iH2O, nzone, tracers, isoName, itZonIso, tnat 6 IMPLICIT NONE 7 include "dimensions.h" 8 REAL, INTENT(INOUT) :: q(ijb_u:ije_u,llm,nqtot) 9 INTEGER, INTENT(IN) :: ijb, ije !--- Can be local and different from ijb_u,ije_u, for example in qminimum 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 :: xtractot, xiiso, deltaD, q1, q2 15 REAL, PARAMETER :: borne = 1e19, & 16 errmax = 1e-8, & !--- Max. absolute error 17 errmaxrel = 1e-3, & !--- Max. relative error 18 qmin = 1e-11, & 19 deltaDmax =1000.0, & 20 deltaDmin =-999.0, & 21 ridicule = 1e-12 22 INTEGER, SAVE :: iso_eau, iso_HDO, iso_O18, & !--- OpenMP shared variables 23 iso_O17, iso_HTO 24 LOGICAL, SAVE :: first=.TRUE. 25 !$OMP THREADPRIVATE(first) 7 26 8 #include "dimensions.h" 27 modname='check_isotopes' 28 IF(.NOT.isoCheck) RETURN !--- No need to check => finished 29 IF(isoSelect('H2O')) RETURN !--- No H2O isotopes group found 30 IF(niso == 0) RETURN !--- No isotopes => finished 31 IF(first) THEN 32 !$OMP MASTER 33 iso_eau = strIdx(isoName,'H2[16]O') 34 iso_HDO = strIdx(isoName,'H[2]HO') 35 iso_O18 = strIdx(isoName,'H2[18]O') 36 iso_O17 = strIdx(isoName,'H2[17]O') 37 iso_HTO = strIdx(isoName,'H[3]HO') 38 !$OMP END MASTER 39 !$OMP BARRIER 40 first = .FALSE. 41 END IF 42 CALL msg('31: err_msg='//TRIM(err_msg), modname) 9 43 10 ! inputs 11 integer ijb,ije ! peut être local et différent de ijb_u,ije_u, ex: dans qminimum 12 real q(ijb_u:ije_u,llm,nqtot) 13 character*(*) err_msg ! message d''erreur à afficher 44 !--- CHECK FOR NaNs (FOR ALL THE ISOTOPES, INCLUDING GEOGRAPHIC TAGGING TRACERS) 45 modname = 'check_isotopes:iso_verif_noNaN' 46 DO ixt = 1, ntiso 47 DO ipha = 1, nphas 48 iq = iqIsoPha(ixt,ipha) 49 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 50 DO k = 1, llm 51 DO i = ijb, ije 52 IF(ABS(q(i,k,iq))<=borne) CYCLE 53 WRITE(msg1,'(s,"(",i0,",",i0,",",i0,") = ",ES12.4)')TRIM(isoName(ixt)),i,k,iq,q(i,k,iq) 54 CALL msg(msg1, modname) 55 CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1) 56 END DO 57 END DO 58 !$OMP END DO NOWAIT 59 END DO 60 END DO 14 61 15 ! locals 16 integer ixt,phase,k,i,iq,iiso,izone,ieau,iqeau 17 real xtractot,xiiso 18 real borne 19 real qmin 20 real errmax ! erreur maximale en absolu. 21 real errmaxrel ! erreur maximale en relatif autorisée 22 real deltaDmax,deltaDmin 23 real ridicule 24 parameter (borne=1e19) 25 parameter (errmax=1e-8) 26 parameter (errmaxrel=1e-3) 27 parameter (qmin=1e-11) 28 parameter (deltaDmax=1000.0,deltaDmin=-999.0) 29 parameter (ridicule=1e-12) 30 real deltaD 62 !--- CHECK CONSERVATION (MAIN ISOTOPE AND PARENT CONCENTRATIONS MUST BE EQUAL) 63 modname = 'check_isotopes:iso_verif_egalite' 64 ixt = iso_eau 65 IF(ixt /= 0) THEN 66 DO ipha = 1, nphas 67 iq = iqIsoPha(ixt,ipha) 68 iqpar = tracers(iq)%iqParent 69 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 70 DO k = 1, llm 71 DO i = ijb, ije 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 !$OMP END DO NOWAIT 91 END DO 92 END IF 31 93 32 if (niso > 0) then 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 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 105 DO k = 1, llm 106 DO i = ijb, ije 107 q1 = q(i,k,iqpar) 108 q2 = q(i,k,iq) 109 !--- IMPROVEMENT in case at least one isotope is not negligible compared to the main isotopic form. 110 ! This would be probably required to sum from smallest to highest concentrations ; the corresponding 111 ! indices vector can be computed once only (in the initializations stage), using mean concentrations. 112 ! q2 = SUM(q(i,k,tracers(iqPar)%iqDesc), DIM=3) 113 IF(q2 <= qmin) CYCLE 114 deltaD = (q2/q1/tnat(ixt)-1.)*1000. 115 IF(deltaD <= deltaDmax .AND. deltaD >= deltaDmin) CYCLE 116 CALL msg('ixt, iq = '//TRIM(strStack(int2str([ixt,iq]))), modname) 117 msg1 = '('//TRIM(strStack(int2str([i,k])))//')' 118 CALL msg(TRIM(tracers(iqpar)%name)//TRIM(msg1)//' = '//TRIM(real2str(q1)), modname) 119 CALL msg(TRIM(tracers(iq )%name)//TRIM(msg1)//' = '//TRIM(real2str(q2)), modname) 120 CALL msg(TRIM(nm(iiso))//TRIM(real2str(deltaD)), modname) 121 CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1) 122 END DO 123 END DO 124 !$OMP END DO NOWAIT 125 END DO 126 END DO 33 127 34 ! write(*,*) 'check_isotopes 31: err_msg=',err_msg 35 ! verifier que rien n'est NaN 36 do ixt=1,ntraciso 37 do phase=1,nqo 38 iq=iqiso(ixt,phase) 39 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 40 do k=1,llm 41 DO i = ijb,ije 42 if ((q(i,k,iq).gt.-borne).and. 43 : (q(i,k,iq).lt.borne)) then 44 else !if ((x(ixt,i,j).gt.-borne).and. 45 write(*,*) 'erreur detectee par iso_verif_noNaN:' 46 write(*,*) err_msg 47 write(*,*) 'q,i,k,iq=',q(i,k,iq),i,k,iq 48 write(*,*) 'borne=',borne 49 call abort_gcm('check_isotopes_loc','plantage iso',0) 50 endif !if ((x(ixt,i,j).gt.-borne).and. 51 enddo !DO i = ijb,ije 52 enddo !do k=1,llm 53 c$OMP END DO NOWAIT 54 enddo !do phase=1,nqo 55 enddo !do ixt=1,ntraciso 128 IF(nzone == 0) RETURN 56 129 57 ! write(*,*) 'check_isotopes 52' 58 ! verifier que l'eau normale est OK 59 if (use_iso(1)) then 60 ixt=indnum_fn_num(1) 61 do phase=1,nqo 62 iq=iqiso(ixt,phase) 63 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 64 do k=1,llm 65 DO i = ijb,ije 66 if ((abs(q(i,k,phase)-q(i,k,iq)).gt.errmax).and. 67 : (abs((q(i,k,phase)-q(i,k,iq))/ 68 : max(max(abs(q(i,k,phase)),abs(q(i,k,iq))),1e-18)) 69 : .gt.errmaxrel)) then 70 write(*,*) 'erreur detectee par iso_verif_egalite:' 71 write(*,*) err_msg 72 write(*,*) 'ixt,phase,ijb=',ixt,phase,ijb 73 write(*,*) 'q,iq,i,k=',q(i,k,iq),iq,i,k 74 write(*,*) 'q(i,k,phase)=',q(i,k,phase) 75 call abort_gcm('check_isotopes_loc','plantage iso',0) 76 endif !if ((abs(q(i,k,phase)-q(i,k,iq)).gt.errmax).and. 77 ! bidouille pour éviter divergence: 78 q(i,k,iq)= q(i,k,phase) 79 enddo ! DO i = ijb,ije 80 enddo !do k=1,llm 81 c$OMP END DO NOWAIT 82 enddo ! do phase=1,nqo 83 endif !if (use_iso(1)) then 84 85 ! write(*,*) 'check_isotopes 78' 86 ! verifier que HDO est raisonable 87 if (use_iso(2)) then 88 ixt=indnum_fn_num(2) 89 do phase=1,nqo 90 iq=iqiso(ixt,phase) 91 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 92 do k=1,llm 93 DO i = ijb,ije 94 if (q(i,k,iq).gt.qmin) then 95 deltaD=(q(i,k,iq)/q(i,k,phase)/tnat(2)-1)*1000 96 if ((deltaD.gt.deltaDmax).or.(deltaD.lt.deltaDmin)) then 97 write(*,*) 'erreur detectee par iso_verif_aberrant:' 98 write(*,*) err_msg 99 write(*,*) 'ixt,phase=',ixt,phase 100 write(*,*) 'q,iq,i,k,=',q(i,k,iq),iq,i,k 101 write(*,*) 'q=',q(i,k,:) 102 write(*,*) 'deltaD=',deltaD 103 call abort_gcm('check_isotopes_loc','plantage iso',0) 104 endif !if ((deltaD.gt.deltaDmax).or.(deltaD.lt.deltaDmin)) then 105 endif !if (q(i,k,iq).gt.qmin) then 106 enddo !DO i = ijb,ije 107 enddo !do k=1,llm 108 c$OMP END DO NOWAIT 109 enddo ! do phase=1,nqo 110 endif !if (use_iso(2)) then 130 !--- CHECK FOR TAGGING TRACERS DELTAD ANOMALIES 131 modname = 'check_isotopes:iso_verif_aberrant' 132 IF(iso_eau /= 0 .AND. iso_HDO /= 0) THEN 133 DO izon = 1, nzone 134 ixt = itZonIso(izon, iso_HDO) 135 ieau = itZonIso(izon, iso_eau) 136 DO ipha = 1, nphas 137 iq = iqIsoPha(ixt, ipha) 138 iqeau = iqIsoPha(ieau, ipha) 139 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 140 DO k = 1, llm 141 DO i = ijb, ije 142 q1 = q(i,k,iqeau) 143 q2 = q(i,k,iq) 144 IF(q2<=qmin) CYCLE 145 deltaD = (q2/q1/tnat(iso_HDO)-1.)*1000. 146 IF(deltaD <= deltaDmax .AND. deltaD >= deltaDmin) CYCLE 147 CALL msg('izon, ipha = '//TRIM(strStack(int2str([izon, ipha]))), modname) 148 CALL msg( 'ixt, ieau = '//TRIM(strStack(int2str([ ixt, ieau]))), modname) 149 msg1 = '('//TRIM(strStack(int2str([i,k])))//')' 150 CALL msg(TRIM(tracers(iqeau)%name)//TRIM(msg1)//' = '//TRIM(real2str(q1)), modname) 151 CALL msg(TRIM(tracers(iq )%name)//TRIM(msg1)//' = '//TRIM(real2str(q2)), modname) 152 CALL msg('deltaD = '//TRIM(real2str(deltaD)), modname) 153 CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1) 154 END DO 155 END DO 156 !$OMP END DO NOWAIT 157 END DO 158 END DO 159 END IF 111 160 112 ! write(*,*) 'check_isotopes 103' 113 ! verifier que O18 est raisonable 114 if (use_iso(3)) then 115 ixt=indnum_fn_num(3) 116 do phase=1,nqo 117 iq=iqiso(ixt,phase) 118 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 119 do k=1,llm 120 DO i = ijb,ije 121 if (q(i,k,iq).gt.qmin) then 122 deltaD=(q(i,k,iq)/q(i,k,phase)/tnat(3)-1)*1000 123 if ((deltaD.gt.deltaDmax).or.(deltaD.lt.deltaDmin)) then 124 write(*,*) 'erreur detectee iso_verif_aberrant O18:' 125 write(*,*) err_msg 126 write(*,*) 'ixt,phase=',ixt,phase 127 write(*,*) 'q,iq,i,k,=',q(i,k,phase),iq,i,k 128 write(*,*) 'xt=',q(i,k,:) 129 write(*,*) 'deltaO18=',deltaD 130 call abort_gcm('check_isotopes_loc','plantage iso',0) 131 endif !if ((deltaD.gt.deltaDmax).or.(deltaD.lt.deltaDmin)) then 132 endif !if (q(i,k,iq).gt.qmin) then 133 enddo !DO i = ijb,ije 134 enddo !do k=1,llm 135 c$OMP END DO NOWAIT 136 enddo ! do phase=1,nqo 137 endif !if (use_iso(2)) then 161 !--- CHECK FOR TAGGING TRACERS CONSERVATION (PARENT AND TAGGING TRACERS SUM OVER ALL REGIONS MUST BE EQUAL) 162 DO iiso = 1, niso 163 DO ipha = 1, nphas 164 iq = iqIsoPha(iiso, ipha) 165 !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) 166 DO k = 1, llm 167 DO i = ijb, ije 168 xiiso = q(i,k,iq) 169 xtractot = SUM(q(i, k, iqIsoPha(itZonIso(1:nzone,iiso), ipha))) 170 IF(ABS(xtractot-xiiso) > errmax .AND. ABS(xtractot-xiiso)/MAX(MAX(ABS(xtractot),ABS(xiiso)),1e-18) > errmaxrel) THEN 171 CALL msg('Error in iso_verif_aberrant trac: '//TRIM(err_msg)) 172 CALL msg('iiso, ipha = '//TRIM(strStack(int2str([iiso, ipha]))), modname) 173 CALL msg('q('//TRIM(strStack(int2str([i,k])))//',:) = '//TRIM(strStack(real2str(q(i,k,:)))), modname) 174 CALL abort_gcm(modname, 'Error with isotopes: '//TRIM(err_msg), 1) 175 END IF 176 IF(ABS(xtractot) <= ridicule) CYCLE 177 DO izon = 1, nzone 178 q(i,k,iq) = q(i,k,iq) / xtractot * xiiso !--- Bidouille pour convergence 179 END DO 180 END DO 181 END DO 182 !$OMP END DO NOWAIT 183 END DO 184 END DO 138 185 186 END SUBROUTINE check_isotopes 139 187 140 ! write(*,*) 'check_isotopes 129'141 if (nzone > 0) then142 143 if (use_iso(2).and.use_iso(1)) then144 do izone=1,ntraceurs_zone145 ixt=index_trac(izone,indnum_fn_num(2))146 ieau=index_trac(izone,indnum_fn_num(1))147 do phase=1,nqo148 iq=iqiso(ixt,phase)149 iqeau=iqiso(ieau,phase)150 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)151 do k=1,llm152 DO i = ijb,ije153 if (q(i,k,iq).gt.qmin) then154 deltaD=(q(i,k,iq)/q(i,k,iqeau)/tnat(2)-1)*1000155 if ((deltaD.gt.deltaDmax).or.156 & (deltaD.lt.deltaDmin)) then157 write(*,*) 'erreur dans iso_verif_aberrant trac:'158 write(*,*) err_msg159 write(*,*) 'izone,phase=',izone,phase160 write(*,*) 'ixt,ieau=',ixt,ieau161 write(*,*) 'q,iq,i,k,=',q(i,k,iq),iq,i,k162 write(*,*) 'deltaD=',deltaD163 call abort_gcm('check_isotopes_loc','plantage iso',0)164 endif !if ((deltaD.gt.deltaDmax).or.165 endif !if (q(i,k,iq).gt.qmin) then166 enddo !DO i = ijb,ije167 enddo ! do k=1,llm168 c$OMP END DO NOWAIT169 enddo ! do phase=1,nqo170 enddo !do izone=1,ntraceurs_zone171 endif !if (use_iso(2).and.use_iso(1)) then172 173 do iiso=1,niso174 do phase=1,nqo175 iq=iqiso(iiso,phase)176 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)177 do k=1,llm178 DO i = ijb,ije179 xtractot=0.0180 xiiso=q(i,k,iq)181 do izone=1,ntraceurs_zone182 iq=iqiso(index_trac(izone,iiso),phase)183 xtractot=xtractot+ q(i,k,iq)184 enddo !do izone=1,ntraceurs_zone185 if ((abs(xtractot-xiiso).gt.errmax).and.186 : (abs(xtractot-xiiso)/187 : max(max(abs(xtractot),abs(xiiso)),1e-18)188 : .gt.errmaxrel)) then189 write(*,*) 'erreur detectee par iso_verif_traceurs:'190 write(*,*) err_msg191 write(*,*) 'iiso,phase=',iiso,phase192 write(*,*) 'i,k,=',i,k193 write(*,*) 'q(i,k,:)=',q(i,k,:)194 call abort_gcm('check_isotopes_loc','plantage iso',0)195 endif !if ((abs(q(i,k,phase)-q(i,k,iq)).gt.errmax).and.196 197 ! bidouille pour éviter divergence:198 if (abs(xtractot).gt.ridicule) then199 do izone=1,ntraceurs_zone200 ixt=index_trac(izone,iiso)201 q(i,k,iq)=q(i,k,iq)/xtractot*xiiso202 enddo !do izone=1,ntraceurs_zone203 endif !if ((abs(xtractot).gt.ridicule) then204 enddo !DO i = ijb,ije205 enddo !do k=1,llm206 c$OMP END DO NOWAIT207 enddo !do phase=1,nqo208 enddo !do iiso=1,niso209 210 endif !if (nzone > 0)211 212 endif ! if (niso > 0)213 ! write(*,*) 'check_isotopes 198'214 215 end216 217
Note: See TracChangeset
for help on using the changeset viewer.