Changeset 167 for trunk/SRC/Computation/div.pro
- Timestamp:
- 09/05/06 14:24:07 (18 years ago)
- Location:
- trunk/SRC/Computation
- Files:
-
- 1 added
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/SRC/Computation/div.pro
r164 r167 5 5 ; 6 6 ; @file_comments 7 ; c alculation of the divergence of a 2dfield7 ; compute the horizontal divergence of a vectors field 8 8 ; 9 9 ; @categories … … 11 11 ; 12 12 ; @param UU 13 ; Matrix representing coordinates of a field of vectors 13 ; Matrix representing the zonal coordinates (U point) of a field of vectors 14 ; A 2D (xy), 3D (xyz or yt) or a structure readable by litchamp and containing 15 ; a 2D (xy), 3D (xyz or yt) array (4d case is not coded yet). 16 ; note that the dimension of the arry must suit the domain dimension. 14 17 ; 15 18 ; @param VV 16 ; Matrix representing coordinates of a field of vectors 19 ; Matrix representing the meridional coordinates (V point) of a field of vectors 20 ; A 2D (xy), 3D (xyz or yt) or a structure readable by litchamp and containing 21 ; a 2D (xy), 3D (xyz or yt) array (4d case is not coded yet). 22 ; note that the dimension of the arry must suit the domain dimension. 23 ; 24 ; @keyword DIREC {type=scalar string} 25 ; Use if you want to call moyenne or grossemoyenne after the div computation 26 ; (stupid ?) with a mean done in the DIREC direction 17 27 ; 18 28 ; @returns RES 19 ; A 2d matrix29 ; the divergence of the input data (with the same size) 20 30 ; 21 31 ; @uses 22 ; c ommon.pro32 ; cm_4cal, cm_4data, cm_4mmesh 23 33 ; 24 34 ; @restrictions 25 ; U and V matrices can be 2 or 4d. 26 ; Beware, to discern different configuration of U and V (xy, xyz, xyt, xyzt), 27 ; we look at the variable of the common 28 ; -time which contain the calendar in IDL julian days to which U and 29 ; V refered to, in the same way as the variable 30 ; -jpt which is the number of time's step to consider in time. 31 ; U and V arrays are cut in the same geographic domain. Because of the gap of 32 ; T, U, V and F grids, it is possible that these two arrays has not the same 33 ; size and refered to different indexes. In this case, arrays are re-cut on 34 ; common indexes and the domain is redefined to match with these common 35 ; indexes. To avoid these re-cuts, use the keyword /memeindice in domdef.pro 36 ; 37 ; 38 ; Points on the drawing edge are at !values.f_nan 39 ; 35 ; 36 ; - Works only for Arakawa C-grid. 37 ; - UU must be on U grid, VV must be on V grid 38 ; - 4d case is not coded yet 39 ; - the common variable jpt is used to differ xyz (jpt=1) and xyt (jpt\=1) cases. 40 ; - U and V arrays are cut in the same geographic domain. Because of the shift between 41 ; T, U, V and F grids, it is possible that these two arrays do not have the same 42 ; size and refer to different indexes. In this case, arrays are re-cut on 43 ; common indexes. To avoid these re-cuts, use the keyword /memeindice in domdef.pro 44 ; - When computing the divergence, we update, vargrid, varname, varunits and the 45 ; grid position parameters (firstxt, lastxt, nxt, firstyt, lastyt, nyt). 46 ; - points that cannot be computed (domain bondaries, coastline) are set to NaN 47 ; 48 ; @examples 49 ; IDL> @tst_initorca2 50 ; IDL> plt, div(dist(jpi,jpj), dist(jpi,jpj)) 40 51 ; 41 52 ; @history 42 ; Guillaume Roullet (grlod\@ipsl.jussieu.fr) 43 ; Creation : printemps 1998 44 ; Sebastien Masson (smasson\@lodyc.jussieu.fr) 45 ; adaptation to work with a reduce domain 46 ; 12/1/2000; 53 ; Guillaume Roullet (grlod\@ipsl.jussieu.fr): creation; spring 1998 54 ; Sebastien Masson (smasson\@lodyc.jussieu.fr) 55 ; adaptation to work with a reduce domain; 12/1/2000 47 56 ; 48 57 ; @version 49 58 ; $Id$ 50 59 ; 60 ; @todo 61 ; code the 4d case 51 62 ;- 52 63 ;------------------------------------------------------------ 53 64 ;------------------------------------------------------------ 54 65 ;------------------------------------------------------------ 55 FUNCTION div, uu, vv 66 FUNCTION div, uu, vv, DIREC = DIREC 56 67 ; 57 68 compile_opt idl2, strictarrsubs 58 69 ; 59 tempsun = systime(1) ; For key_performance 60 @common 61 ; 62 IF finite(glamu[0])*finite(gphiu[0])*finite(glamv[0])*finite(gphiv[0]) EQ 0 THEN $ 70 @cm_4cal ; for jpt 71 @cm_4data ; for varname, vargrid, vardate, varunit, valmask 72 @cm_4mesh 73 ; 74 tempsun = systime(1) ; For key_performance 75 ; 76 IF finite(glamu[0])*finite(gphiu[0])*finite(glamv[0])*finite(gphiv[0]) EQ 0 THEN $ 63 77 return, report(['This version of div is based on Arakawa C-grid.' $ 64 78 , 'U and V grids must therefore be defined']) 65 79 ; 66 u = litchamp(uu) 67 v = litchamp(vv) 68 ; 69 date1 = time[0] 70 if n_elements(jpt) EQ 0 then date2 = date1 ELSE date2 = time[jpt-1] 71 if (size(u))[0] NE (size(v))[0] then return, -1 80 u = litchamp(uu) 81 v = litchamp(vv) 82 ; 83 szu = size(u) 84 szv = size(v) 85 86 if szu[0] NE szv[0] then return, report('U and V input data must have the same number of dimensions') 72 87 73 88 ;------------------------------------------------------------ 74 89 ; We find common points between U and V 75 90 ;------------------------------------------------------------ 76 indicexu = (lindgen(jpi))[firstxu:firstxu+nxu-1] 77 indicexv = (lindgen(jpi))[firstxv:firstxv+nxv-1] 78 indicex = inter(indicexu, indicexv) 79 indiceyu = (lindgen(jpj))[firstyu:firstyu+nyu-1] 80 indiceyv = (lindgen(jpj))[firstyv:firstyv+nyv-1] 81 indicey = inter(indiceyu, indiceyv) 82 nx = n_elements(indicex) 83 ny = n_elements(indicey) 84 indice2d = lindgen(jpi, jpj) 85 indice2d = indice2d[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1] 86 case 1 of 87 ;---------------------------------------------------------------------------- 91 indicexu = (lindgen(jpi))[firstxu:firstxu+nxu-1] 92 indicexv = (lindgen(jpi))[firstxv:firstxv+nxv-1] 93 indicex = inter(indicexu, indicexv) 94 indiceyu = (lindgen(jpj))[firstyu:firstyu+nyu-1] 95 indiceyv = (lindgen(jpj))[firstyv:firstyv+nyv-1] 96 indicey = inter(indiceyu, indiceyv) 97 nx = n_elements(indicex) 98 ny = n_elements(indicey) 99 indice2d = lindgen(jpi, jpj) 100 indice2d = indice2d[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1] 101 ;---------------------------------------------------------------------------- 102 vargrid = 'T' 103 varname = 'div' 104 varunits = '1.e6*s-1' 105 if n_elements(valmask) EQ 0 THEN valmask = 1.e20 106 firstxt = indicex[0] & lastxt = indicex[0]+nx-1 & nxt = nx 107 firstyt = indicey[0] & lastyt = indicey[0]+ny-1 & nyt = ny 108 ;---------------------------------------------------------------------------- 109 ;---------------------------------------------------------------------------- 110 case 1 of 88 111 ;---------------------------------------------------------------------------- 89 112 ;xyz 90 113 ;---------------------------------------------------------------------------- 91 (size(u))[0] EQ 3 AND date1 EQ date2:BEGIN114 szu[0] EQ 3 AND jpt EQ 1:BEGIN 92 115 ;------------------------------------------------------------ 93 116 ; extraction of U and V on the appropriated domain 94 117 ;------------------------------------------------------------ 95 case 1 of 96 (size(v))[0] NE 3: return, -1 97 (size(u))[1] EQ nxu AND (size(u))[2] EQ nyu AND $ 98 (size(v))[1] EQ nxv AND (size(v))[2] EQ nyv:BEGIN 99 case 1 of 100 nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *] 101 nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 102 nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *] 103 nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 104 ELSE : 105 endcase 106 END 107 (size(u))[1] EQ jpi AND (size(u))[2] EQ jpj AND $ 108 (size(v))[1] EQ jpi AND (size(v))[2] EQ jpj:BEGIN 109 u = u[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 110 v = v[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 111 END 112 ELSE:BEGIN 113 zdiv = -1 114 GOTO, sortie 115 end 116 117 endcase 118 ;------------------------------------------------------------ 119 ; calcul de la divergence 120 ;------------------------------------------------------------ 121 zu = (e2u[indice2d])[*]#replicate(1, nzt) 122 zu = reform(zu, nx, ny, nzt, /over) 123 zu = temporary(u)*temporary(zu) $ 124 *(umask())[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 125 terreu = where(zu EQ 0) 126 if terreu[0] NE -1 then zu[temporary(terreu)] = !values.f_nan 127 ; 128 zv = (e1v[indice2d])[*]#replicate(1, nzt) 129 zv = reform(zv, nx, ny, nzt, /over) 130 zv = temporary(v)*temporary(zv) $ 131 *(vmask())[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 132 terrev = where(zv EQ 0) 133 if terrev[0] NE -1 then zv[temporary(terrev)] = !values.f_nan 134 ; 135 zdiv = 1e6/(e1t[indice2d]*e2t[indice2d]) 136 zdiv = (zdiv)[*]#replicate(1, nzt) 137 zdiv = reform(zdiv, nx, ny, nzt, /over) 138 zdiv = temporary(zdiv)*(zu-shift(zu, 1, 0, 0)+zv-shift(zv, 0, 1, 0)) $ 139 *tmask[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 118 case 1 of 119 szu[1] EQ nxu AND szu[2] EQ nyu AND $ 120 szv[1] EQ nxv AND szv[2] EQ nyv:BEGIN 121 case 1 of 122 nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *] 123 nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 124 nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *] 125 nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 126 ELSE : 127 endcase 128 END 129 szu[1] EQ jpi AND szu[2] EQ jpj AND $ 130 szv[1] EQ jpi AND szv[2] EQ jpj:BEGIN 131 u = u[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 132 v = v[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 133 END 134 ELSE:return, -1 135 endcase 136 ;------------------------------------------------------------ 137 ; divergence computation 138 ;------------------------------------------------------------ 139 zu = (e2u[indice2d])[*]#replicate(1., nzt) 140 landu = where((umask())[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, firstzt:lastzt] EQ 0) 141 if landu[0] NE -1 then zu[temporary(landu)] = !values.f_nan 142 zu = temporary(u) * temporary(zu) 143 ; 144 zv = (e1v[indice2d])[*]#replicate(1., nzt) 145 landv = where((vmask())[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, firstzt:lastzt] EQ 0) 146 if landv[0] NE -1 then zv[temporary(landv)] = !values.f_nan 147 zv = temporary(v) * temporary(zv) 148 ; 149 zdiv = (e1t[indice2d]*e2t[indice2d])[*]#replicate(1.e6, nzt) 150 zdiv = ( zu - shift(zu, 1, 0, 0) + zv - shift(zv, 0, 1, 0) ) * temporary(zdiv) 140 151 ;------------------------------------------------------------ 141 152 ; Edging put at !values.f_nan 142 153 ;------------------------------------------------------------ 143 if NOT keyword_set(key_periodic) OR nx NE jpi then begin 144 zdiv[0, *, *] = !values.f_nan 145 zdiv[nx-1, *, *] = !values.f_nan 146 endif 147 zdiv[*, 0, *] = !values.f_nan 148 zdiv[*, ny-1, *] = !values.f_nan 149 ; 150 zdiv = temporary(zdiv) 151 ; 152 if n_elements(valmask) EQ 0 THEN valmask = 1e20 153 terre = where(tmask[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] EQ 0) 154 if terre[0] NE -1 then zdiv[temporary(terre)] = valmask 155 ;------------------------------------------------------------ 156 ; For the graphic drawing 157 ;------------------------------------------------------------ 158 vargrid = 'T' 159 varname = 'div' 160 varunits = '1e6*s-1' 161 domdef, (glamt[indice2d])[0, 0], (glamu[indice2d])[nx-1, 0],(gphit[indice2d])[0, 0], (gphiv[indice2d])[0, ny-1], vert1, vert2, gridtype = ['t'] 162 if keyword_set(direc) then zdiv = moyenne(zdiv,direc,/nan) 163 END 154 if NOT keyword_set(key_periodic) OR nx NE jpi then begin 155 zdiv[0, *, *] = !values.f_nan 156 zdiv[nx-1, *, *] = !values.f_nan 157 endif 158 zdiv[*, 0, *] = !values.f_nan 159 zdiv[*, ny-1, *] = !values.f_nan 160 ; 161 land = where(tmask[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, firstzt:lastzt] EQ 0) 162 if land[0] NE -1 then zdiv[temporary(land)] = valmask 163 if keyword_set(direc) then zdiv = moyenne(zdiv, direc, /nan) 164 END 164 165 ;---------------------------------------------------------------------------- 165 166 ;---------------------------------------------------------------------------- … … 167 168 ;---------------------------------------------------------------------------- 168 169 ;---------------------------------------------------------------------------- 169 date1 NE date2 AND (size(u))[0] EQ 3:BEGIN170 szu[0] EQ 3 AND jpt GT 1:BEGIN 170 171 ;------------------------------------------------------------ 171 172 ; extraction of U and V on the appropriated domain 172 173 ;------------------------------------------------------------ 173 case 1 of 174 (size(u))[0] NE 3 OR (size(v))[0] NE 3: return, -1 175 (size(u))[1] EQ nxu AND (size(u))[2] EQ nyu AND $ 176 (size(v))[1] EQ nxv AND (size(v))[2] EQ nyv:BEGIN 177 case 1 of 178 nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *] 179 nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 180 nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *] 181 nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 182 ELSE : 183 endcase 184 END 185 (size(u))[1] EQ jpi AND (size(u))[2] EQ jpj AND $ 186 (size(v))[1] EQ jpi AND (size(v))[2] EQ jpj:BEGIN 187 u = u[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 188 v = v[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 189 END 190 ELSE:return, -1 191 endcase 192 ;------------------------------------------------------------ 193 ; Calculation of the divergence 194 ;------------------------------------------------------------ 195 zu = e2u[indice2d]*(umask())[indice2d+jpi*jpj*firstzt] 196 terreu = where(zu EQ 0) 197 if terreu[0] NE -1 then zu[temporary(terreu)] = !values.f_nan 198 zu = (zu)[*]#replicate(1, jpt) 199 zu = reform(zu, nx, ny, jpt, /over) 200 zu = temporary(u)*temporary(zu) 201 ; 202 zv = e1v[indice2d]*(vmask())[indice2d+jpi*jpj*firstzt] 203 terrev = where(zv EQ 0) 204 if terrev[0] NE -1 then zv[temporary(terrev)] = !values.f_nan 205 zv = (zv)[*]#replicate(1, jpt) 206 zv = reform(zv, nx, ny, jpt, /over) 207 zv = temporary(v)*temporary(zv) 208 ; 209 zdiv = 1e6*tmask[indice2d+jpi*jpj*firstzt]/(e1t[indice2d]*e2t[indice2d]) 210 zdiv = (zdiv)[*]#replicate(1, jpt) 211 zdiv = reform(zdiv, nx, ny, jpt, /over) 212 terre = where(zdiv EQ 0) 213 zdiv = temporary(zdiv)*(zu-shift(zu, 1, 0, 0)+zv-shift(zv, 0, 1, 0)) 174 case 1 of 175 szu[1] EQ nxu AND szu[2] EQ nyu AND $ 176 szv[1] EQ nxv AND szv[2] EQ nyv:BEGIN 177 case 1 of 178 nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *] 179 nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 180 nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *] 181 nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 182 ELSE : 183 endcase 184 END 185 szu[1] EQ jpi AND szu[2] EQ jpj AND $ 186 szv[1] EQ jpi AND szv[2] EQ jpj:BEGIN 187 u = u[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 188 v = v[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 189 END 190 ELSE:return, -1 191 endcase 192 ;------------------------------------------------------------ 193 ; divergence computation 194 ;------------------------------------------------------------ 195 zu = e2u[indice2d] 196 landu = where((umask())[indice2d+jpi*jpj*firstzt] EQ 0) 197 if landu[0] NE -1 then zu[temporary(landu)] = !values.f_nan 198 zu = (temporary(zu))[*]#replicate(1., jpt) 199 zu = temporary(u) * temporary(zu) 200 ; 201 zv = e1v[indice2d] 202 landv = where((vmask())[indice2d+jpi*jpj*firstzt] EQ 0) 203 if landv[0] NE -1 then zv[temporary(landv)] = !values.f_nan 204 zv = (temporary(zv))[*]#replicate(1., jpt) 205 zv = temporary(v) * temporary(zv) 206 ; 207 zdiv = (e1t[indice2d]*e2t[indice2d])[*]#replicate(1.e6, jpt) 208 zdiv = ( zu - shift(zu, 1, 0, 0) + zv - shift(zv, 0, 1, 0) ) * temporary(zdiv) 214 209 ;------------------------------------------------------------ 215 210 ; Edging put at !values.f_nan 216 211 ;------------------------------------------------------------ 217 if NOT keyword_set(key_periodic) OR nx NE jpi then begin 218 zdiv[0, *, *] = !values.f_nan 219 zdiv[nx-1, *, *] = !values.f_nan 220 endif 221 zdiv[*, 0, *] = !values.f_nan 222 zdiv[*, ny-1, *] = !values.f_nan 223 ; 224 if n_elements(valmask) EQ 0 THEN valmask = 1e20 225 if terre[0] NE -1 then zdiv[temporary(terre)] = valmask 226 ;------------------------------------------------------------ 227 ; for the graphic drawing 228 ;------------------------------------------------------------ 229 vargrid = 'T' 230 varname = 'div' 231 varunits = '1e6*s-1' 232 domdef, (glamt[indice2d])[0, 0], (glamu[indice2d])[nx-1, 0],(gphit[indice2d])[0, 0], (gphiv[indice2d])[0, ny-1], vert1, vert2, gridtype = ['t'] 233 if keyword_set(direc) then zdiv = grossemoyenne(zdiv,direc,/nan) 234 END 212 if NOT keyword_set(key_periodic) OR nx NE jpi then begin 213 zdiv[0, *, *] = !values.f_nan 214 zdiv[nx-1, *, *] = !values.f_nan 215 endif 216 zdiv[*, 0, *] = !values.f_nan 217 zdiv[*, ny-1, *] = !values.f_nan 218 ; 219 land = where(tmask[indice2d+jpi*jpj*firstzt] EQ 0, cnt) 220 if land[0] NE -1 then BEGIN 221 land = (temporary(land))#replicate(1L, jpt) + replicate(1L, cnt)#(nx*ny*lindgen(jpt)) 222 zdiv[temporary(land)] = valmask 223 ENDIF 224 if keyword_set(direc) then zdiv = grossemoyenne(zdiv, direc, /nan) 225 END 235 226 ;---------------------------------------------------------------------------- 236 227 ;---------------------------------------------------------------------------- … … 238 229 ;---------------------------------------------------------------------------- 239 230 ;---------------------------------------------------------------------------- 240 date1 NE date2 AND (size(u))[0] EQ 4:BEGIN241 return, report('non code!')242 231 szu[0] EQ 4:BEGIN 232 return, report('Case not coded contact saxo team or make a do loop!') 233 END 243 234 ;---------------------------------------------------------------------------- 244 235 ;---------------------------------------------------------------------------- … … 246 237 ;---------------------------------------------------------------------------- 247 238 ;---------------------------------------------------------------------------- 248 ELSE:BEGIN ;xy 249 indice3d = lindgen(jpi, jpj, jpk) 250 indice3d = indice3d[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt] 239 szu[0] EQ 2:BEGIN 251 240 ;------------------------------------------------------------ 252 241 ; extraction of U and V on the appropriated domain 253 242 ;------------------------------------------------------------ 254 255 (size(u))[0] NE 2 OR (size(v))[0] NE 2: BEGIN256 zdiv = -1257 GOTO, sortie258 end259 (size(u))[1] EQ nxu AND (size(u))[2] EQ nyu AND $260 (size(v))[1] EQ nxv AND (size(v))[2] EQ nyv:BEGIN261 case 1 of262 nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *] ELSE u = u[1: nx, *]263 nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *] ELSE v = v[1: nx, *]264 nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1] ELSE u = u[*, 1: ny]265 nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1] ELSE v = v[*, 1: ny]266 ELSE :267 endcase268 END269 (size(u))[1] EQ jpi AND (size(u))[2] EQ jpj AND $270 (size(v))[1] EQ jpi AND (size(v))[2] EQ jpj:BEGIN271 u = u[indice2d]272 v = v[indice2d] 273 END 274 ELSE:return, -1 275 endcase276 ;------------------------------------------------------------ 277 ; Calculation of the divergence 278 ;------------------------------------------------------------ 279 zu = temporary(u)*e2u[indice2d]*(umask())[indice3d] 280 terreu = where(zu EQ 0)281 if terreu[0] NE -1 then zu[temporary(terreu)] = !values.f_nan282 zv = temporary(v)*e1v[indice2d]*(vmask())[indice3d]283 terrev = where(zv EQ 0)284 if terrev[0] NE -1 then zv[temporary(terrev)] = !values.f_nan 285 zdiv = zu-shift(zu, 1, 0)+zv-shift(zv, 0, 1)286 zdiv = temporary(zdiv)*tmask[indice3d]/(e1t[indice2d]*e2t[indice2d])243 case 1 of 244 szu[1] EQ nxu AND szu[2] EQ nyu AND $ 245 szv[1] EQ nxv AND szv[2] EQ nyv:BEGIN 246 case 1 of 247 nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *] ELSE u = u[1: nx, *] 248 nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *] ELSE v = v[1: nx, *] 249 nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1] ELSE u = u[*, 1: ny] 250 nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1] ELSE v = v[*, 1: ny] 251 ELSE : 252 endcase 253 END 254 szu[1] EQ jpi AND szu[2] EQ jpj AND $ 255 szv[1] EQ jpi AND szv[2] EQ jpj:BEGIN 256 u = u[indice2d] 257 v = v[indice2d] 258 END 259 ELSE:return, -1 260 endcase 261 ;------------------------------------------------------------ 262 ; divergence computation 263 ;------------------------------------------------------------ 264 zu = e2u[indice2d] 265 landu = where((umask())[indice2d+jpi*jpj*firstzt] EQ 0) 266 if landu[0] NE -1 then zu[temporary(landu)] = !values.f_nan 267 zu = temporary(u) * temporary(zu) 268 269 zv = e1v[indice2d] 270 landv = where((vmask())[indice2d+jpi*jpj*firstzt] EQ 0) 271 if landv[0] NE -1 then zv[temporary(landv)] = !values.f_nan 272 zv = temporary(v) * temporary(zv) 273 274 zdiv = 1.e6 / (e1t[indice2d]*e2t[indice2d]) 275 zdiv = ( zu - shift(zu, 1, 0) + zv - shift(zv, 0, 1) ) * temporary(zdiv) 287 276 ;------------------------------------------------------------ 288 277 ; Edging put at !values.f_nan 289 278 ;------------------------------------------------------------ 290 if NOT keyword_set(key_periodic) OR nx NE jpi then begin 291 zdiv[0, *] = !values.f_nan 292 zdiv[nx-1, *] = !values.f_nan 293 endif 294 zdiv[*, 0] = !values.f_nan 295 zdiv[*, ny-1] = !values.f_nan 296 ; 297 zdiv = temporary(zdiv)*1e6 298 ; 299 if n_elements(valmask) EQ 0 THEN valmask = 1e20 300 terre = where(tmask[indice3d] EQ 0) 301 if terre[0] NE -1 then zdiv[temporary(terre)] = valmask 302 ;------------------------------------------------------------ 303 ; for the graphic drawing 304 ;------------------------------------------------------------ 305 vargrid = 'T' 306 varname = 'div' 307 varunits = '1e6*s-1' 308 domdef, (glamt[indice2d])[0, 0], (glamu[indice2d])[nx-1, 0],(gphit[indice2d])[0, 0], (gphiv[indice2d])[0, ny-1], vert1, vert2, gridtype = ['t'] 309 if keyword_set(direc) then zdiv = moyenne(zdiv,direc,/nan) 310 311 END 312 endcase 313 314 ;------------------------------------------------------------ 315 sortie: 316 if keyword_set(key_performance) THEN print, 'temps div', systime(1)-tempsun 317 318 return, zdiv 279 if NOT keyword_set(key_periodic) OR nx NE jpi then begin 280 zdiv[0, *] = !values.f_nan 281 zdiv[nx-1, *] = !values.f_nan 282 endif 283 zdiv[*, 0] = !values.f_nan 284 zdiv[*, ny-1] = !values.f_nan 285 ; 286 land = where(tmask[indice2d+jpi*jpj*firstzt] EQ 0) 287 if land[0] NE -1 then zdiv[temporary(land)] = valmask 288 if keyword_set(direc) then zdiv = moyenne(zdiv, direc, /nan) 289 END 290 ;---------------------------------------------------------------------------- 291 ;---------------------------------------------------------------------------- 292 ELSE:return, report('U and V input arrays must have 2, 3 or 4 dimensions') 293 ENDCASE 294 ;------------------------------------------------------------ 295 if keyword_set(key_performance) THEN print, 'temps div', systime(1)-tempsun 296 297 return, zdiv 319 298 end
Note: See TracChangeset
for help on using the changeset viewer.