1 | ;+ |
---|
2 | ; |
---|
3 | ; @file_comments |
---|
4 | ; compute the barotropic (along the model grid) stream function in Sv using |
---|
5 | ; the following equation: total(total(e2u*e3u*un),3), 2, /cumulative)/1.e6 |
---|
6 | ; |
---|
7 | ; @categories |
---|
8 | ; diagnostics |
---|
9 | ; |
---|
10 | ; @param z3d {in} {type=3D xyz array} |
---|
11 | ; zonal velocity |
---|
12 | ; |
---|
13 | ; @keyword NOSTRUCTURE {default=0}{type=scalar: 0 or 1} |
---|
14 | ; activate if you do not want that msf returns a structure |
---|
15 | ; but only the array referring to the field. |
---|
16 | ; |
---|
17 | ; @keyword REFPOINT {type=2 element vector} |
---|
18 | ; a 2 element vector [x,y] giving the (approximative) position of the |
---|
19 | ; point that should be taken as a reference. This position should be |
---|
20 | ; given with the same coordinates system as the one used in |
---|
21 | ; glam/gphi. see example |
---|
22 | ; |
---|
23 | ; @keyword REFVALUE {type=scalar} {default=0.} |
---|
24 | ; the bsf value that we want to speficy at the position defined by refpoint |
---|
25 | ; |
---|
26 | ; @returns {type=2D xy array} |
---|
27 | ; barotropic stream function in Sv |
---|
28 | ; |
---|
29 | ; @uses |
---|
30 | ; <pro>cm_4mesh</pro> |
---|
31 | ; <pro>cm_4data</pro> |
---|
32 | ; <pro>grille</pro> |
---|
33 | ; <pro>litchamp</pro> |
---|
34 | ; <pro>fitintobox</pro> |
---|
35 | ; |
---|
36 | ; @restrictions |
---|
37 | ; - T and U boxzoom parameters must be the same |
---|
38 | ; - to be valid, mask must be equal to 0 at the bottom and on each |
---|
39 | ; side of the domain along x direction |
---|
40 | ; - define the common variables (of cm_4data) |
---|
41 | ; varname = 'BSF' |
---|
42 | ; varunit = 'Sv' |
---|
43 | ; vargrid = 'F' |
---|
44 | ; |
---|
45 | ; @examples |
---|
46 | ; |
---|
47 | ; IDL> initorca05 |
---|
48 | ; IDL> file = '/Volumes/pim/F31/oce/1y/F31_1y_0040_0040_grid_U.nc' |
---|
49 | ; IDL> un = read_ncdf('vozocrtx', 0, 0, /timestep, file = file) |
---|
50 | ; IDL> bar = bsf(un, refvalue = 0., refpoint = [0, 20]) |
---|
51 | ; IDL> plt, bar, -150, 150, int = 10, style = 'so0so', format = '(i4)', lct = 64 |
---|
52 | ; |
---|
53 | ; @history |
---|
54 | ; Gurvan Madec, Christian Ethe, Claude Talandier and Sebastien Masson, Dec 2008 |
---|
55 | ; |
---|
56 | ; @version |
---|
57 | ; $Id$ |
---|
58 | ; |
---|
59 | ;- |
---|
60 | ; |
---|
61 | FUNCTION bsf, z3d, NOSTRUCTURE = nostructure, REFPOINT = refpoint, REFVALUE = refvalue |
---|
62 | ; |
---|
63 | compile_opt idl2, strictarrsubs |
---|
64 | ; |
---|
65 | @cm_4mesh |
---|
66 | @cm_4data |
---|
67 | ; |
---|
68 | CASE 1 OF |
---|
69 | firstxt NE firstxu OR lastxt NE lastxu: return, report('T and U box must be defined over the same x indexes, use /memeindices when calling domdef') |
---|
70 | firstyt NE firstyu OR lastyt NE lastyu: return, report('T and U box must be defined over the same y indexes, use /memeindices when calling domdef') |
---|
71 | ELSE: |
---|
72 | ENDCASE |
---|
73 | ; |
---|
74 | grille, -1, -1, -1, -1, nx, ny, nz, firstx, firsty, firstz, lastx, lasty, lastz, grid = 'T' |
---|
75 | umsk = (umask())[firstx:lastx, firsty:lasty, firstz:lastz] |
---|
76 | IF total(umsk[*, *, nz-1]) NE 0 THEN return, report('The bottom of the box (defined by lastzt) must be set to land value (=0)') |
---|
77 | IF total(umsk[*, 0, *]) NE 0 THEN return, report('southern boudary must be land point if you want to compute the bsf with this function') |
---|
78 | ; |
---|
79 | un = litchamp(z3d) |
---|
80 | IF size(un, /n_dimensions) NE 3 THEN return, report('input data must be a 3D array') |
---|
81 | un = fitintobox(temporary(un)) |
---|
82 | ; |
---|
83 | IF keyword_set(key_partialstep) THEN BEGIN |
---|
84 | ; 2D e3u at the bottom of the ocean |
---|
85 | ; see zgr_zps: e3u (ji,jj,jk) = MIN( e3t(ji,jj,jk), e3t(ji+1,jj,jk)) |
---|
86 | e3u_ps = [[[e3t_ps[firstx:lastx, firsty:lasty]]], [[shift(e3t_ps[firstx:lastx, firsty:lasty], -1, 0)]]] |
---|
87 | e3u_ps = min(temporary(e3u_ps), dimension = 3) |
---|
88 | flagdata = NOT (keyword_set(key_periodic) AND nx EQ jpi) AND total(umsk[nx-1, *, *]) NE 0 |
---|
89 | ; level of the bottom of the ocean |
---|
90 | bottom = total(tmask[firstx:lastx, firsty:lasty, firstz:lastz], 3) |
---|
91 | bottom = 0L > ( long(temporary(bottom)) - 1L ) |
---|
92 | ; the bottom of the ocean in 3D index is: |
---|
93 | bottom = lindgen(nx*ny) + temporary(bottom)*nx*ny |
---|
94 | ; 3D e3t array |
---|
95 | e33 = replicate(1., nx*ny) # e3t[firstz:lastz] |
---|
96 | ; apply e3u_ps to e33 at the bottom of the ocean |
---|
97 | e33[temporary(bottom)] = e3u_ps |
---|
98 | ; 3D e2u array |
---|
99 | e23d = (e2u[firstx:lastx, firsty:lasty])[*] # replicate(1., nzt) |
---|
100 | ; e2u*e3u |
---|
101 | e23 = temporary(e23d) * temporary(e33) |
---|
102 | ENDIF ELSE BEGIN |
---|
103 | e23 = (e2u[firstx:lastx, firsty:lasty])[*] # e3t[firstz:lastz] |
---|
104 | ENDELSE |
---|
105 | ; |
---|
106 | ; mask the array |
---|
107 | un = temporary(umsk) * temporary(un) |
---|
108 | ; compute the bsf |
---|
109 | bsf = 1.e-6 * total(total(temporary(un) * temporary(e23), 3), 2, /cumulative) |
---|
110 | ; set bsf to 0 in the largest continent... no done... |
---|
111 | IF keyword_set(refpoint) THEN BEGIN |
---|
112 | refind = neighbor(refpoint[0], refpoint[1], glamf[firstx:lastx, firsty:lasty], gphif[firstx:lastx, firsty:lasty], SPHERE = key_onearth) |
---|
113 | IF n_elements(refvalue) EQ 0 THEN refval = - bsf[refind[0]] ELSE refval = refvalue - bsf[refind[0]] |
---|
114 | bsf = temporary(bsf) + refval |
---|
115 | ENDIF |
---|
116 | IF keyword_set(flagdata) THEN bsf[nx-1, *] = !values.f_nan |
---|
117 | ; |
---|
118 | ; update data informations |
---|
119 | varname = 'BSF' |
---|
120 | varunit = 'Sv' |
---|
121 | vargrid = 'F' |
---|
122 | ; |
---|
123 | IF keyword_set(nostructure) THEN return, bsf |
---|
124 | |
---|
125 | IF keyword_set(key_forgetold) THEN BEGIN |
---|
126 | return, {arr:temporary(bsf), grid:vargrid, unit:varunit, experiment:varexp, name:varname} |
---|
127 | ENDIF ELSE BEGIN |
---|
128 | return, {tab:temporary(bsf), grille:vargrid, unite:varunit, experience:varexp, nom:varname} |
---|
129 | ENDELSE |
---|
130 | |
---|
131 | END |
---|