;+ ;; ;; Extrapole zinout[jpi,jpj] sur les continents en utilisant les 4 ;; plus proches voisins masques oceaniquement et construit un nouveau ; masque ;; contenant l'ancien masque oceanique PLUSles points extrapoles. ;; Reitere le processus niter fois. ;; C'est pas clair, essayez ! ;; ;; ; ; /Nan: to fill the point which have the value ; !values.f_nan. Whitout this keyword, these point are not filling ; and stays at !values.f_nan. ; ; ; @todo seb ; ;- FUNCTION remplit, zinput, NAN = nan, NITER = niter, BASIQUE = basique, mask = mask, FILLXDIR = fillxdir, FILLYDIR = fillydir, FILLVAL = fillval, _extra = ex ; compile_opt idl2, strictarrsubs ; @common tempsun = systime(1) ; pour key_performance ; les points non remplis sont masques a valmask IF n_elements(niter) EQ 0 THEN niter = 1 IF niter EQ 0 THEN return, zinput z = zinput if n_elements(key_gridtype) EQ 0 then key_gridtype = 'c' if keyword_set(basique) then begin oldkey_gridtype = key_gridtype key_gridtype = 'c' nx = (size(zinput))[1] ny = (size(zinput))[2] if NOT keyword_set(mask) then mmmask = basique ELSE mmmask = mask if key_gridtype eq 'e' then begin case vargrid of 'T':glam = glamt[firstxt:lastxt, firstyt:lastyt] 'U':glam = glamu[firstxu:lastxu, firstyu:lastyu] endcase endif ENDIF ELSE grille, mmmask, glam, gphi, gdep, nx, ny, nz, _extra = ex if keyword_set(mask) then mmmask = mask ;--------------------------------------------------------------- if (size(mmmask))[0] EQ 3 THEN mmmask = mmmask[*, *, 0] ; if n_elements(mmmask) EQ 1 then mmmask = replicate(1b, nx, ny) if keyword_set(nan) then begin nanpoint = where(finite(z) EQ 0) if nanpoint[0] NE -1 then begin mmmask[nanpoint] = 0b z[nanpoint] = 0 endif ENDIF mmmask = byte(mmmask) ;--------------------------------------------------------------- ; on ajoute un cadre de zero a z, mask, e1, e2 ; comme ca apres on peut faire des shifts ds tous les sens sans se ; soucier des bords du domaine! ;--------------------------------------------------------------- tempdeux = systime(1) ; pour key_performance =2 nx2 = nx+2 case key_gridtype of 'c':BEGIN ztmp = bytarr(nx+2, ny+2) ztmp[1:nx, 1:ny] = mmmask mmmask = temporary(ztmp) ztmp = fltarr(nx+2, ny+2) ztmp[1:nx, 1:ny] = z if keyword_set(key_periodic) AND nx EQ jpi then begin ztmp[0, 1:ny] = z[jpi-1, *] ztmp[nx+1, 1:ny] = z[0, *] endif z = temporary(ztmp) END 'e':BEGIN ztmp = bytarr(nx+2, ny+4) ztmp[1:nx, 2:ny+1] = mmmask mmmask = temporary(ztmp) ztmp = fltarr(nx+2, ny+4) ztmp[1:nx, 2:ny+1] = z if keyword_set(key_periodic) AND nx EQ jpi then begin ztmp[0, 2:ny+1] = z[jpi-1, *] ztmp[nx+1, 2:ny+1] = z[0, *] endif z = temporary(ztmp) END endcase IF testvar(var = key_performance) EQ 2 THEN $ print, 'temps remplit: on ajoute un cadre de zero ', systime(1)-tempdeux ;--------------------------------------------------------------- ;--------------------------------------------------------------- ; iteration ;--------------------------------------------------------------- ;--------------------------------------------------------------- FOR n = 1, niter DO BEGIN ; on trouve les points coast tempdeux = systime(1) ; pour key_performance =2 ; les points du bord du cadre ne doivent pas etre selectionnes comme ; la coast case key_gridtype of 'c':BEGIN mmmask[0, *] = 1b mmmask[nx+1, *] = 1b mmmask[*, 0] = 1b mmmask[*, ny+1] = 1b END 'e':BEGIN mmmask[0, *] = 1b mmmask[nx+1, *] = 1b mmmask[*, 0:1] = 1b mmmask[*, ny+2:ny+3] = 1b END endcase ; liste des points terre restant IF keyword_set(fillxdir) THEN BEGIN ; we stop if all the lines, that contains data, have been filled test = total(mmmask[1:nx, *], 1) IF total((test EQ 0)+(test EQ nx)) EQ ny+2 THEN GOTO, fini ENDIF IF keyword_set(fillydir) THEN BEGIN ; we stop if all the columns, that contains data, have been filled test = total(mmmask[*, 1:ny], 2) IF total((test EQ 0)+(test EQ ny)) EQ nx+2 THEN GOTO, fini ENDIF land = where(mmmask EQ 0) if land[0] EQ -1 then GOTO, fini ; les points du bord du cadre doivent maintenant etre dans la terre case key_gridtype of 'c':BEGIN mmmask[0, *] = 0b mmmask[nx+1, *] = 0b mmmask[*, 0] = 0b mmmask[*, ny+1] = 0b END 'e':BEGIN mmmask[0, *] = 0b mmmask[nx+1, *] = 0b mmmask[*, 0:1] = 0b mmmask[*, ny+2:ny+3] = 0b END endcase if keyword_set(key_periodic) AND nx EQ jpi then begin mmmask[0, *] = mmmask[nx, *] mmmask[nx+1, *] = mmmask[1, *] endif ; liste des voisins mer case key_gridtype of 'c':BEGIN CASE 1 OF keyword_set(fillxdir):weight = mmmask[1+land]+mmmask[-1+land] keyword_set(fillydir):weight = mmmask[nx2+land]+mmmask[-nx2+land] ELSE:weight = mmmask[1+land]+mmmask[-1+land]+mmmask[nx2+land]+mmmask[-nx2+land] $ +1./sqrt(2)*(mmmask[nx2+1+land]+mmmask[nx2-1+land] $ +mmmask[-nx2+1+land]+mmmask[-nx2-1+land]) ENDCASE END 'e':BEGIN shifted = glam[0, 0] LT glam[0, 1] oddeven = (land/nx2+1-shifted) MOD 2 weight = mmmask[1+land]+mmmask[-1+land] $ +mmmask[2*nx2+land]+mmmask[-2*nx2+land] $ +sqrt(2)*(mmmask[-nx2+oddeven+land]+mmmask[-nx2-1+oddeven+land] $ +mmmask[nx2+oddeven+land]+mmmask[nx2-1+oddeven+land]) END endcase ok = where(weight GT 0) weight = weight[ok] coast = land[temporary(ok)] ; IF testvar(var = key_performance) EQ 2 THEN $ print, 'temps remplit: trouver la coast ', systime(1)-tempdeux ;--------------------------------------------------------------- ; remplissage des points coast ;--------------------------------------------------------------- tempdeux = systime(1) ; pour key_performance =2 ; on masque z z = temporary(z)*mmmask ; case key_gridtype of 'c':BEGIN CASE 1 OF keyword_set(fillxdir):zcoast = z[1+coast]+z[-1+coast] keyword_set(fillydir):zcoast = z[nx2+coast]+z[-nx2+coast] ELSE:zcoast = z[1+coast]+z[-1+coast]+z[nx2+coast]+z[-nx2+coast] $ +1./sqrt(2)*(z[nx2+1+coast]+z[nx2-1+coast] $ +z[-nx2+1+coast]+z[-nx2-1+coast]) ENDCASE END 'e':BEGIN oddeven = (coast/nx2+1-shifted) MOD 2 zcoast = z[1+coast]+z[-1+coast]+z[2*nx2+coast]+z[-2*nx2+coast] $ +sqrt(2)*(z[-nx2+oddeven+coast]+z[-nx2-1+oddeven+coast] $ +z[nx2+oddeven+coast]+z[nx2-1+oddeven+coast]) END endcase ; z[coast] = temporary(zcoast)/ temporary(weight) ; we update the the boundary conditions of z if keyword_set(key_periodic) AND nx EQ jpi then begin z[0, *] = z[nx, *] z[nx+1, *] = z[1, *] endif ;--------------------------------------------------------------- ; IV) on reduit le masque ;--------------------------------------------------------------- mmmask[ temporary(coast)] = 1 ; IF testvar(var = key_performance) EQ 2 THEN $ print, 'temps remplit: une iteration ', systime(1)-tempdeux ENDFOR fini: ; ; on masque les valeurs sur les lands restantes ; IF n_elements(valmask) EQ 0 then valmask = 1e20 IF n_elements(fillval) EQ 0 THEN fillval = valmask z = temporary(z)*mmmask + fillval*(1b-mmmask) ;--------------------------------------------------------------- ; on redecoupe le tableau pour retirer le cadre! ;--------------------------------------------------------------- case key_gridtype of 'c':BEGIN z = z[1:nx, 1:ny] END 'e':BEGIN z = z[1:nx, 2:ny+1] END endcase ; if keyword_set(basique) then key_gridtype = oldkey_gridtype ;--------------------------------------------------------------- if keyword_set(key_performance) THEN print, 'temps remplit', systime(1)-tempsun return, z END