Ignore:
Timestamp:
09/05/06 14:24:07 (18 years ago)
Author:
smasson
Message:

clean div, curl, grad + minors bugfix

Location:
trunk/SRC/Computation
Files:
1 added
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/SRC/Computation/curl.pro

    r164 r167  
    1111;  
    1212; @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. 
    1417; 
    1518; @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; with a mean done in the DIREC direction 
    1727; 
    1828; @returns RES 
    19 ; A 2d matrix 
     29; the vertical component of the curl of the input data (with the same size) 
    2030; 
    2131; @uses 
    22 ; common.pro 
     32; cm_4cal, cm_4data, cm_4mmesh  
    2333; 
    2434; @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 ae 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  
     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 (firstxf, lastxf, nxf, firstyf, lastyf, nyf). 
     46; - points that cannot be computed (domain bondaries, coastline) are set to NaN 
     47; 
     48; @examples 
     49; IDL> @tst_initorca2 
     50; IDL> plt, curl(dist(jpi,jpj), dist(jpi,jpj)) 
    3951; 
    4052; @history  
    4153; Guillaume Roullet (grlod\@ipsl.jussieu.fr) 
    42 ;  
    4354; Sebastien Masson (smasson\@lodyc.jussieu.fr) 
    4455; adaptation to work with a reduce domain 
     
    4859; $Id$ 
    4960; 
     61; @todo  
     62; code the 4d case 
    5063;- 
    5164;------------------------------------------------------------ 
    5265;------------------------------------------------------------ 
    5366;------------------------------------------------------------ 
    54 FUNCTION curl, uu, vv 
     67FUNCTION curl, uu, vv, DIREC = DIREC 
    5568; 
    5669  compile_opt idl2, strictarrsubs 
    5770; 
    58 @common 
    59    tempsun = systime(1)         ; To key_performance 
    60 ; 
    61    IF finite(glamu[0])*finite(gphiu[0])*finite(glamv[0])*finite(gphiv[0]) EQ 0 THEN $ 
     71@cm_4cal                        ; for jpt 
     72@cm_4data                       ; for varname, vargrid, vardate, varunit, valmask 
     73@cm_4mesh  
     74; 
     75  tempsun = systime(1)          ; To key_performance 
     76; 
     77  IF finite(glamu[0])*finite(gphiu[0])*finite(glamv[0])*finite(gphiv[0]) EQ 0 THEN $ 
    6278     return, report(['This version of curl is based on Arakawa C-grid.' $ 
    6379                     , 'U and V grids must therefore be defined']) 
    6480; 
    65    u = litchamp(uu) 
    66    v = litchamp(vv) 
    67  
    68    date1 = time[0] 
    69    if n_elements(jpt) EQ 0 then date2 = date1 ELSE date2 = time[jpt-1] 
    70    if (size(u))[0] NE (size(v))[0] then return,  -1 
     81  u = litchamp(uu) 
     82  v = litchamp(vv) 
     83 
     84  szu = size(u) 
     85  szv = size(v) 
     86   
     87  if szu[0] NE szv[0] then return, report('U and V input data must have the same number of dimensions') 
    7188 
    7289;------------------------------------------------------------ 
    7390; We find common points between U and V 
    7491;------------------------------------------------------------ 
    75    indicexu = (lindgen(jpi))[firstxu:firstxu+nxu-1] 
    76    indicexv = (lindgen(jpi))[firstxv:firstxv+nxv-1] 
    77    indicex = inter(indicexu, indicexv) 
    78    indiceyu = (lindgen(jpj))[firstyu:firstyu+nyu-1] 
    79    indiceyv = (lindgen(jpj))[firstyv:firstyv+nyv-1] 
    80    indicey = inter(indiceyu, indiceyv) 
    81    nx = n_elements(indicex)  
    82    ny = n_elements(indicey) 
    83    case 1 of 
    84 ;---------------------------------------------------------------------------- 
     92  indicexu = (lindgen(jpi))[firstxu:firstxu+nxu-1] 
     93  indicexv = (lindgen(jpi))[firstxv:firstxv+nxv-1] 
     94  indicex = inter(indicexu, indicexv) 
     95  indiceyu = (lindgen(jpj))[firstyu:firstyu+nyu-1] 
     96  indiceyv = (lindgen(jpj))[firstyv:firstyv+nyv-1] 
     97  indicey = inter(indiceyu, indiceyv) 
     98  nx = n_elements(indicex)  
     99  ny = n_elements(indicey) 
     100  indice2d = lindgen(jpi, jpj) 
     101  indice2d = indice2d[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1] 
     102;---------------------------------------------------------------------------- 
     103  vargrid = 'F' 
     104  varname = 'vorticity' 
     105  varunits = 's-1' 
     106  if n_elements(valmask) EQ 0 THEN valmask = 1e20 
     107  firstxt = indicex[0] & lastxt = indicex[0]+nx-1 & nxt = nx  
     108  firstyt = indicey[0] & lastyt = indicey[0]+ny-1 & nyt = ny 
     109;---------------------------------------------------------------------------- 
     110;---------------------------------------------------------------------------- 
     111  case 1 of 
    85112;---------------------------------------------------------------------------- 
    86113;xyz 
    87114;---------------------------------------------------------------------------- 
    88       (size(u))[0] EQ 3 AND date1 EQ date2 :BEGIN  
    89          indice2d = lindgen(jpi, jpj) 
    90          indice2d = indice2d[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1] 
     115    szu[0] EQ 3 AND jpt EQ 1:BEGIN  
    91116;------------------------------------------------------------ 
    92117; extraction of U and V on the appropriated domain 
    93118;------------------------------------------------------------ 
    94          case 1 of 
    95             (size(u))[0] NE 3 OR (size(v))[0] NE 3: return,  -1 
    96             (size(u))[1] EQ nxu AND (size(u))[2] EQ nyu AND $ 
    97              (size(v))[1] EQ nxv AND (size(v))[2] EQ nyv:BEGIN  
    98             case 1 of 
    99                nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *] 
    100                nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 
    101                nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *] 
    102                nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 
    103                ELSE : 
    104             endcase 
    105             END 
    106             (size(u))[1] EQ jpi AND (size(u))[2] EQ jpj AND $ 
    107              (size(v))[1] EQ jpi AND (size(v))[2] EQ jpj:BEGIN  
    108                u = u[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 
    109                v = v[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 
    110             END 
    111             ELSE:return,  -1 
    112          endcase 
    113 ;------------------------------------------------------------ 
    114 ; calculation of the curl 
    115 ;------------------------------------------------------------ 
    116          coefu = (e1u[indice2d])[*]#replicate(1, nzt) 
    117          coefu = reform(coefu, nx, ny, nzt, /over) 
    118          coefu = coefu*(umask())[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 
    119          terreu = where(coefu EQ 0) 
    120          if terreu[0] NE -1 then coefu[temporary(terreu)] = !values.f_nan 
    121           
    122          coefv = (e2v[indice2d])[*]#replicate(1, nzt) 
    123          coefv = reform(coefv, nx, ny, nzt, /over) 
    124          coefv = coefv*(vmask())[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 
    125          terrev = where(coefv EQ 0) 
    126          if terrev[0] NE -1 then coefv[temporary(terrev)] = !values.f_nan 
    127  
    128          tabf = (fmask())[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 
    129          div = (e1f[indice2d]*e2f[indice2d])[*]#replicate(1, nzt) 
    130          div = reform(div, nx, ny, nzt, /over) 
    131          tabf = tabf/div 
    132 ; 
    133          zu = u*temporary(coefu) 
    134          zv = v*temporary(coefv) 
    135  
    136          psi =  (shift(zv, -1, 0, 0)-zv) + (zu-shift(zu, 0, -1, 0)) 
    137          psi = tabf*psi 
     119      case 1 of 
     120        szu[1] EQ nxu AND szu[2] EQ nyu AND $ 
     121           szv[1] EQ nxv AND szv[2] EQ nyv:BEGIN  
     122          case 1 of 
     123            nxu NE nx:if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *] 
     124            nxv NE nx:if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 
     125            nyu NE ny:if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *] 
     126            nyv NE ny:if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 
     127            ELSE : 
     128          endcase 
     129        END 
     130        szu[1] EQ jpi AND szu[2] EQ jpj AND $ 
     131           szv[1] EQ jpi AND szv[2] EQ jpj:BEGIN  
     132          u = u[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 
     133          v = v[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 
     134        END 
     135        ELSE:return,  -1 
     136      endcase 
     137;------------------------------------------------------------ 
     138; curl computation 
     139;------------------------------------------------------------ 
     140      coefu = ((e1u[indice2d])[*]#replicate(1., nzt)) $ 
     141              * (umask())[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 
     142      landu = where(coefu EQ 0) 
     143      if landu[0] NE -1 then coefu[temporary(landu)] = !values.f_nan 
     144       
     145      coefv = ((e2v[indice2d])[*]#replicate(1., nzt)) $ 
     146              *(vmask())[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, firstzt:lastzt] 
     147      landv = where(coefv EQ 0) 
     148      if landv[0] NE -1 then coefv[temporary(landv)] = !values.f_nan 
     149 
     150      tabf = (fmask())[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, firstzt:lastzt] $ 
     151             / ((e1f[indice2d]*e2f[indice2d])[*]#replicate(1., nzt)) 
     152      landf =  where(tabf EQ 0) 
     153; 
     154      zu = temporary(u) * temporary(coefu) 
     155      zv = temporary(v) * temporary(coefv) 
     156 
     157      psi = (shift(zv, -1, 0, 0)-zv) + (zu-shift(zu, 0, -1, 0)) 
     158      psi = temporary(tabf) * temporary(psi) 
    138159;------------------------------------------------------------ 
    139160; Edging put at !values.f_nan 
    140161;------------------------------------------------------------ 
    141          if NOT keyword_set(key_periodic)  OR nx NE jpi then begin 
    142             psi[0, *, *] = !values.f_nan 
    143             psi[nx-1, *, *] = !values.f_nan 
    144          endif 
    145          psi[*, 0, *] = !values.f_nan 
    146          psi[*, ny-1, *] = !values.f_nan 
    147 ; 
    148          if n_elements(valmask) EQ 0 THEN valmask = 1e20 
    149          terref =  where(tabf EQ 0) 
    150          if terref[0] NE -1 then psi[temporary(terref)] = valmask 
    151 ;------------------------------------------------------------ 
    152 ; For the graphic drawing 
    153 ;------------------------------------------------------------ 
    154          domdef, (glagmt[indice2d])[0, 0], (glamu[indice2d])[nx-1, 0],(gphit[indice2d])[0, 0], (gphiv[indice2d])[0, ny-1], vert1, vert2, gridtype = ['t', 'f'] 
    155          if keyword_set(direc) then psi = moyenne(psi,direc,/nan) 
    156  
    157 ;---------------------------------------------------------------------------- 
    158       END 
     162      if NOT keyword_set(key_periodic)  OR nx NE jpi then begin 
     163        psi[0, *, *] = !values.f_nan 
     164        psi[nx-1, *, *] = !values.f_nan 
     165      endif 
     166      psi[*, 0, *] = !values.f_nan 
     167      psi[*, ny-1, *] = !values.f_nan 
     168; 
     169      if landf[0] NE -1 then psi[temporary(landf)] = valmask 
     170      if keyword_set(direc) then psi = moyenne(psi, direc, /nan) 
     171    END 
    159172;---------------------------------------------------------------------------- 
    160173;---------------------------------------------------------------------------- 
     
    162175;---------------------------------------------------------------------------- 
    163176;---------------------------------------------------------------------------- 
    164       date1 NE date2 AND (size(u))[0] EQ 3 :BEGIN  
    165          indice2d = lindgen(jpi, jpj) 
    166          indice2d = indice2d[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1] 
     177    szu[0] EQ 3 AND jpt GT 1:BEGIN  
    167178;------------------------------------------------------------ 
    168179; extraction of U and V on the appropriated domain 
    169180;------------------------------------------------------------ 
    170          case 1 of 
    171             (size(u))[1] EQ nxu AND (size(u))[2] EQ nyu AND $ 
    172              (size(v))[1] EQ nxv AND (size(v))[2] EQ nyv:BEGIN  
    173                if nxu NE nx then $ 
    174                 if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *]  
    175                IF nxv NE nx THEN $ 
    176                 if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 
    177                IF nyu NE ny THEN $ 
    178                 if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *]  
    179                IF nyv NE ny THEN $ 
    180                 if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 
    181             END 
    182             (size(u))[1] EQ jpi AND (size(u))[2] EQ jpj AND $ 
    183              (size(v))[1] EQ jpi AND (size(v))[2] EQ jpj:BEGIN  
    184                u = u[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 
    185                v = v[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1, *] 
    186             END 
    187             ELSE:BEGIN  
    188                print, 'problemes d''adequation entre la taille du domaine et la taille des matrices necessaires a tracer des vecteurs' 
    189                return, -1 
    190             end 
    191          endcase 
    192 ;---------------------------------------------------------------------------- 
    193 ; Calculation of the curl 
    194 ;---------------------------------------------------------------------------- 
    195          coefu = e1u[indice2d]*(umask())[indice2d+jpi*jpj*firstzt] 
    196          terreu = where(coefu EQ 0) 
    197          if terreu[0] NE -1 then coefu[temporary(terreu)] = !values.f_nan 
    198          coefu = temporary(coefu[*])#replicate(1, jpt) 
    199          coefu = reform(coefu, nx, ny, jpt, /over) 
    200 ; 
    201          coefv = e2v[indice2d]*(vmask())[indice2d+jpi*jpj*firstzt] 
    202          terrev = where(coefv EQ 0) 
    203          if terrev[0] NE -1 then coefv[temporary(terrev)] = !values.f_nan 
    204          coefv = temporary(coefv[*])#replicate(1, jpt) 
    205          coefv = reform(coefv, nx, ny, jpt, /over) 
    206 ; 
    207          tabf = (fmask())[indice2d+jpi*jpj*firstzt]/(e1f[indice2d]*e2f[indice2d]) 
    208          tabf = temporary(tabf[*])#replicate(1, jpt) 
    209          tabf = reform(tabf, nx, ny, jpt, /over) 
    210 ;------------------------------------------------------------ 
    211 ; Calculation of the curl 
    212 ;------------------------------------------------------------ 
    213          zu = u*temporary(coefu) 
    214          zv = v*temporary(coefv) 
    215 ; 
    216          psi =  (shift(zv, -1, 0, 0)-zv) + (zu-shift(zu, 0, -1, 0)) 
    217          psi = tabf*psi 
     181      case 1 of 
     182        szu[1] EQ nxu AND szu[2] EQ nyu AND $ 
     183           szv[1] EQ nxv AND szv[2] EQ nyv:BEGIN  
     184          if nxu NE nx then $ 
     185             if indicex[0] EQ firstxu then u = u[0:nx-1, *, *] ELSE u = u[1: nx, *, *]  
     186          IF nxv NE nx THEN $ 
     187             if indicex[0] EQ firstxv then v = v[0:nx-1, *, *] ELSE v = v[1: nx, *, *] 
     188          IF nyu NE ny THEN $ 
     189             if indicey[0] EQ firstyu then u = u[*, 0:ny-1, *] ELSE u = u[*, 1: ny, *]  
     190          IF nyv NE ny THEN $ 
     191             if indicey[0] EQ firstyv then v = v[*, 0:ny-1, *] ELSE v = v[*, 1: ny, *] 
     192        END 
     193        szu[1] EQ jpi AND szu[2] EQ jpj AND $ 
     194           szv[1] EQ jpi AND szv[2] EQ jpj:BEGIN  
     195          u = u[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 
     196          v = v[indicex[0]:indicex[0]+nx-1, indicey[0]:indicey[0]+ny-1, *] 
     197        END 
     198        ELSE:BEGIN  
     199          print, 'problemes d''adequation entre la taille du domaine et la taille des matrices necessaires a tracer des vecteurs' 
     200          return, -1 
     201        end 
     202      endcase 
     203;---------------------------------------------------------------------------- 
     204; curl computation 
     205;---------------------------------------------------------------------------- 
     206      coefu = e1u[indice2d]*(umask())[indice2d+jpi*jpj*firstzt] 
     207      landu = where(coefu EQ 0) 
     208      if landu[0] NE -1 then coefu[temporary(landu)] = !values.f_nan 
     209      coefu = temporary(coefu[*])#replicate(1., jpt) 
     210; 
     211      coefv = e2v[indice2d]*(vmask())[indice2d+jpi*jpj*firstzt] 
     212      landv = where(coefv EQ 0) 
     213      if landv[0] NE -1 then coefv[temporary(landv)] = !values.f_nan 
     214      coefv = temporary(coefv[*])#replicate(1., jpt) 
     215; 
     216      tabf = (fmask())[indice2d+jpi*jpj*firstzt]/(e1f[indice2d]*e2f[indice2d]) 
     217      tabf = temporary(tabf[*])#replicate(1., jpt) 
     218      landf = where(tabf EQ 0) 
     219; 
     220      zu = temporary(u) * temporary(coefu) 
     221      zv = temporary(v) * temporary(coefv) 
     222; 
     223      psi = (shift(zv, -1, 0, 0)-zv) + (zu-shift(zu, 0, -1, 0)) 
     224      psi = temporary(tabf) * temporary(psi) 
    218225;------------------------------------------------------------ 
    219226; extraction of U and V on the appropriated domain 
    220227;------------------------------------------------------------ 
    221          if NOT keyword_set(key_periodic) OR nx NE jpi then begin 
    222             psi[0, *, *] = !values.f_nan 
    223             psi[nx-1, *, *] = !values.f_nan 
    224          endif 
    225          psi[*, 0, *] = !values.f_nan 
    226          psi[*, ny-1, *] = !values.f_nan 
    227          if n_elements(valmask) EQ 0 THEN valmask = 1e20 
    228          terref =  where(tabf EQ 0) 
    229          if terref[0] NE -1 then psi[temporary(terref)] = valmask 
    230 ;---------------------------------------------------------------------------- 
    231          domdef, (glamt[indice2d])[0, 0], (glamu[indice2d])[nx-1, 0],(gphit[indice2d])[0, 0], (gphiv[indice2d])[0, ny-1], vert1, vert2, gridtype = ['t', 'f'] 
    232          if keyword_set(direc) then psi = grossemoyenne(psi,direc,/nan) 
    233 ;---------------------------------------------------------------------------- 
    234       END 
     228      if NOT keyword_set(key_periodic) OR nx NE jpi then begin 
     229        psi[0, *, *] = !values.f_nan 
     230        psi[nx-1, *, *] = !values.f_nan 
     231      endif 
     232      psi[*, 0, *] = !values.f_nan 
     233      psi[*, ny-1, *] = !values.f_nan 
     234      if landf[0] NE -1 then psi[temporary(landf)] = valmask 
     235      if keyword_set(direc) then psi = grossemoyenne(psi, direc, /nan) 
     236    END 
    235237;---------------------------------------------------------------------------- 
    236238;---------------------------------------------------------------------------- 
     
    238240;---------------------------------------------------------------------------- 
    239241;---------------------------------------------------------------------------- 
    240       date1 NE date2 AND (size(u))[0] EQ 4:BEGIN  
    241          return, report('non code!') 
    242       END 
     242    szu[0] EQ 4:BEGIN  
     243      return, report('Case not coded contact saxo team or make a do loop!') 
     244    END 
    243245;---------------------------------------------------------------------------- 
    244246;---------------------------------------------------------------------------- 
     
    246248;---------------------------------------------------------------------------- 
    247249;---------------------------------------------------------------------------- 
    248       ELSE:BEGIN                ;xy 
    249          indice2d = lindgen(jpi, jpj) 
    250          indice2d = indice2d[indicex[0]:indicex[0]+nx-1,indicey[0]:indicey[0]+ny-1] 
    251 ;------------------------------------------------------------ 
    252 ;------------------------------------------------------------ 
    253          case 1 of 
    254             (size(u))[0] NE 2 OR (size(v))[0] NE 2: return,  -1 
    255             (size(u))[1] EQ nxu AND (size(u))[2] EQ nyu AND $ 
    256              (size(v))[1] EQ nxv AND (size(v))[2] EQ nyv:BEGIN  
    257                if nxu NE nx then $ 
    258                 if indicex[0] EQ firstxu then u = u[0:nx-1, *] ELSE u = u[1: nx, *]  
    259                IF nxv NE nx THEN $ 
    260                 if indicex[0] EQ firstxv then v = v[0:nx-1, *] ELSE v = v[1: nx, *] 
    261                IF nyu NE ny THEN $ 
    262                 if indicey[0] EQ firstyu then u = u[*, 0:ny-1] ELSE u = u[*, 1: ny]  
    263                IF nyv NE ny THEN $ 
    264                 if indicey[0] EQ firstyv then v = v[*, 0:ny-1] ELSE v = v[*, 1: ny] 
    265             END 
    266             (size(u))[1] EQ jpi AND (size(u))[2] EQ jpj AND $ 
    267              (size(v))[1] EQ jpi AND (size(v))[2] EQ jpj:BEGIN  
    268                u = u[indice2d] 
    269                v = v[indice2d] 
    270             END 
    271             ELSE:return,  -1 
    272          endcase 
    273 ;------------------------------------------------------------ 
    274 ; Calculation of the curl 
    275 ;------------------------------------------------------------ 
    276          coefu = e1u[indice2d]*(umask())[indice2d+jpi*jpj*firstzt] 
    277          terreu = where(coefu EQ 0) 
    278          if terreu[0] NE -1 then coefu[temporary(terreu)] = !values.f_nan 
    279          coefv = e2v[indice2d]*(vmask())[indice2d+jpi*jpj*firstzt] 
    280          terrev = where(coefv EQ 0) 
    281          if terrev[0] NE -1 then coefv[temporary(terrev)] = !values.f_nan 
    282          tabf = (fmask())[indice2d+jpi*jpj*firstzt]/(e1f[indice2d]*e2f[indice2d]) 
    283 ; 
    284          zu = u*temporary(coefu) 
    285          zv = v*temporary(coefv) 
    286  
    287          psi =  (shift(zv, -1, 0)-zv) + (zu-shift(zu, 0, -1)) 
    288          psi = tabf*psi 
    289  
     250    szu[0] EQ 2:BEGIN  
     251;------------------------------------------------------------ 
     252;------------------------------------------------------------ 
     253      case 1 of 
     254        szu[1] EQ nxu AND szu[2] EQ nyu AND $ 
     255           szv[1] EQ nxv AND szv[2] EQ nyv:BEGIN  
     256          if nxu NE nx then $ 
     257             if indicex[0] EQ firstxu then u = u[0:nx-1, *] ELSE u = u[1: nx, *]  
     258          IF nxv NE nx THEN $ 
     259             if indicex[0] EQ firstxv then v = v[0:nx-1, *] ELSE v = v[1: nx, *] 
     260          IF nyu NE ny THEN $ 
     261             if indicey[0] EQ firstyu then u = u[*, 0:ny-1] ELSE u = u[*, 1: ny]  
     262          IF nyv NE ny THEN $ 
     263             if indicey[0] EQ firstyv then v = v[*, 0:ny-1] ELSE v = v[*, 1: ny] 
     264        END 
     265        szu[1] EQ jpi AND szu[2] EQ jpj AND $ 
     266           szv[1] EQ jpi AND szv[2] EQ jpj:BEGIN  
     267          u = u[indice2d] 
     268          v = v[indice2d] 
     269        END 
     270        ELSE:return,  -1 
     271      endcase 
     272;------------------------------------------------------------ 
     273; curl computation 
     274;------------------------------------------------------------ 
     275      coefu = e1u[indice2d]*(umask())[indice2d+jpi*jpj*firstzt] 
     276      landu = where(coefu EQ 0) 
     277      if landu[0] NE -1 then coefu[temporary(landu)] = !values.f_nan 
     278      coefv = e2v[indice2d]*(vmask())[indice2d+jpi*jpj*firstzt] 
     279      landv = where(coefv EQ 0) 
     280      if landv[0] NE -1 then coefv[temporary(landv)] = !values.f_nan 
     281      tabf = (fmask())[indice2d+jpi*jpj*firstzt]/(e1f[indice2d]*e2f[indice2d]) 
     282      landf =  where(tabf EQ 0) 
     283; 
     284      zu = temporary(u) * temporary(coefu) 
     285      zv = temporary(v) * temporary(coefv) 
     286 
     287      psi = (shift(zv, -1, 0)-zv) + (zu-shift(zu, 0, -1)) 
     288      psi = temporary(tabf) * temporary(psi) 
    290289;------------------------------------------------------------ 
    291290; Edging put at !values.f_nan 
    292291;------------------------------------------------------------ 
    293          if  NOT keyword_set(key_periodic) OR nx NE jpi then begin 
    294             psi[0, *] = !values.f_nan 
    295             psi[nx-1, *] = !values.f_nan 
    296          endif 
    297          psi[*, 0] = !values.f_nan 
    298          psi[*, ny-1] = !values.f_nan 
    299 ; 
    300          if n_elements(valmask) EQ 0 THEN valmask = 1e20 
    301          terref =  where(tabf EQ 0) 
    302          if terref[0] NE -1 then psi[temporary(terref)] = valmask 
    303 ;------------------------------------------------------------ 
    304 ; for the graphic drawing 
    305 ;------------------------------------------------------------ 
    306          domdef, (glamt[indice2d])[0, 0], (glamf[indice2d])[nx-1, 0],(gphit[indice2d])[0, 0], (gphif[indice2d])[0, ny-1], vert1, vert2, gridtype = ['t', 'f'] 
    307          if keyword_set(direc) then psi = moyenne(psi,direc,/nan) 
    308  
    309       END 
    310 ;---------------------------------------------------------------------------- 
    311    endcase 
    312 ;------------------------------------------------------------ 
    313    if keyword_set(key_performance) THEN print, 'temps curl', systime(1)-tempsun  
    314 ;------------------------------------------------------------ 
    315    vargrid = 'F' 
    316    varname = 'vorticity' 
    317    return, psi 
     292      if  NOT keyword_set(key_periodic) OR nx NE jpi then begin 
     293        psi[0, *] = !values.f_nan 
     294        psi[nx-1, *] = !values.f_nan 
     295      endif 
     296      psi[*, 0] = !values.f_nan 
     297      psi[*, ny-1] = !values.f_nan 
     298; 
     299      if landf[0] NE -1 then psi[temporary(landf)] = valmask 
     300      if keyword_set(direc) then psi = moyenne(psi, direc, /nan) 
     301    END 
     302;---------------------------------------------------------------------------- 
     303;---------------------------------------------------------------------------- 
     304    ELSE:return, report('U and V input arrays must have 2, 3 or 4 dimensions') 
     305  ENDCASE 
     306;------------------------------------------------------------ 
     307  if keyword_set(key_performance) THEN print, 'temps curl', systime(1)-tempsun  
     308 
     309  return, psi 
    318310end 
Note: See TracChangeset for help on using the changeset viewer.