source: trunk/SRC/Computation/msf.pro

Last change on this file was 495, checked in by pinsard, 10 years ago

fix thanks to coding rules; typo; dupe empty lines; trailing blanks

  • Property svn:keywords set to Id
File size: 5.3 KB
Line 
1;+
2;
3; @file_comments
4; compute the meridional (along the model grid) stream function in Sv using
5; the following equation: total(total(e1v*e3v*vn),1), 2, /cumulative)/1.e6
6;
7; @categories
8; diagnostics
9;
10; @param z3d {in} {type=3D xyz array}
11; meridional velocity
12;
13; @param mask2d {in} {type=2D xy array} {optional} {default=1 everywhere}
14; land/sea (0/1) mask to be applied (in addition to the 3D mask
15; of the model) to mask some parts of the domain (and keep for example
16; the northend atlantic).
17;
18; @keyword NOSTRUCTURE {default=0}{type=scalar: 0 or 1}
19; activate if you do not want that msf returns a structure
20; but only the array referring to the field.
21;
22; @keyword INDEXBOXZOOM
23; Set this keyword to a named variable in which msf will return the x
24; and y indexes defining the zoom-box that should be used by pltz to do
25; the plot (see example)
26;
27; @keyword MASKOUT
28; Set this keyword to a named variable in which msf will return the 2d
29; array (yz) should be used by pltz to do plot the land/sea mask(see example)
30;
31; @keyword TRANSPORT {type=scalar: 0 or 1} {default=0.}
32; activate to specify that z3d is not a zonal current but a zonal
33; transport (e1v*e3v*vn)
34;
35; @returns {type=2D yz array}
36; meridional stream function in Sv
37;
38; @uses
39; <pro>cm_4mesh</pro>
40; <pro>cm_4data</pro>
41; <pro>grille</pro>
42; <pro>litchamp</pro>
43; <pro>fitintobox</pro>
44;
45; @restrictions
46; - T and V boxzoom parameters must be the same
47; - to be valid, mask must be equal to 0 at the bottom and on each
48;   side of the domain along x direction
49; - define the common variables (of cm_4data)
50;       varname = 'MSF'
51;       varunit = 'Sv'
52;       vargrid = 'W' ; -> should introduce WF point...
53;
54; @examples
55;
56;   IDL> initorca05
57;   IDL> file = '/Volumes/pim/F31/oce/1y/F31_1y_0040_0040_grid_V.nc'
58;   IDL> vn = read_ncdf('vomecrty', 0, 0, /timestep, file = file)
59;   IDL> mm = msf(vn, mskatl, indexboxzoom = ind, maskout = ma)
60;   IDL> pltz, mm, -20, 20, int = 1, boxzoom = [ind, 0, 5200], /xindex  $
61;            , /yindex, zoom = 1000, maskdta = ma, /no_partial, style = 'so0so'
62;
63; @history
64; Gurvan Madec, Christian Ethe, Claude Talandier and Sebastien Masson, Dec 2008
65;
66; @version
67; $Id$
68;
69;-
70;
71FUNCTION msf, z3d, mask2d, INDEXBOXZOOM = indexboxzoom, MASKOUT = maskout, NOSTRUCTURE = nostructure, TRANSPORT = transport
72;
73  compile_opt idl2, strictarrsubs
74;
75@cm_4mesh
76@cm_4data
77;
78  CASE 1 OF
79    firstxt NE firstxv OR lastxt NE lastxv: return, report('T and V box must be defined over the same x indexes, use /memeindices when calling domdef')
80    firstyt NE firstyv OR lastyt NE lastyv: return, report('T and V box must be defined over the same y indexes, use /memeindices when calling domdef')
81    ELSE:
82  ENDCASE
83;
84  grille, -1, -1, -1, -1, nx, ny, nz, firstx, firsty, firstz, lastx, lasty, lastz, grid = 'T'
85;
86  vn = litchamp(z3d)
87  IF size(vn, /n_dimensions) NE 3 THEN return, report('input data must be a 3D array')
88  vn = fitintobox(temporary(vn))
89;
90  IF n_elements(mask2d) EQ 0 THEN mask2d = replicate(1b, nx, ny)
91  IF size(mask2d, /n_dimensions) NE 2 THEN return, report('input mask2d must be a 2D array')
92  msk = fitintobox(mask2d)
93  msk = (temporary(msk))[*]#replicate(1b, nz)
94  msk = (vmask())[firstx:lastx, firsty:lasty, firstz:lastz] * temporary(msk)
95;
96  IF total(msk[*, *, nz-1]) NE 0 THEN return, report('The bottom of the box (defined by lastzt) must be set to land value (=0)')
97  IF (total(msk[0, *, *]) NE 0 OR total(msk[nx-1, *, *]) NE 0) AND NOT (keyword_set(key_periodic) AND nx EQ jpi) THEN $
98     return, report('for non-periodic domains, eastern and western boundaries must be land point')
99  IF keyword_set(key_partialstep) AND total(msk[*, ny-1, *]) NE 0 THEN flagdata = 1
100;
101; current -> transport
102  IF NOT keyword_set(transport) THEN vn = temporary(vn) * e3v_3d(/e1)
103  vtr = temporary(vn) * msk
104;
105  IF arg_present(maskout) THEN BEGIN
106    msk = total(temporary(msk), 1)
107    maskout = temporary(msk) NE 0
108    maskout = shift(maskout, 0, 1) ; bottom value of W should be taken into account
109    maskout[*, 0] = maskout[*, 1]
110    maskout = reverse(temporary(maskout), 2)
111  ENDIF
112;
113; default computation:
114;  msf = 1.e-6 * total(total(temporary(vtr), 1), 2, /cumulative)
115; but we force the computation from bottom to up.
116  msf = total(temporary(vtr), 1) ; -> yz array
117  msf = reverse(temporary(msf), 2)
118  msf = 1.e-6 * total(temporary(msf), 2, /cumulative)
119  msf = -1.*reverse(temporary(msf), 2)
120  IF keyword_set(flagdata) THEN msf[ny-1, *] = !values.f_nan
121
122; set msf to 0 in the largest continent... no done...
123
124; update data informations
125  varname = 'MSF'
126  varunit = 'Sv'
127  vargrid = 'W' ; -> should introduce WF point...
128;
129; we must define a domain related to the section
130;
131; are we using an ORCA grid???
132
133  IF (jpiglo EQ 182 AND jpjglo EQ 149) OR (jpiglo EQ 722 AND jpjglo EQ 511) $
134     OR (jpiglo EQ 1442 AND jpjglo EQ 1021) OR (jpiglo EQ 4322 AND jpjglo EQ 3059) THEN BEGIN
135; find the i index with the northest latitude
136    ind = (where(gphit[firstx:lastx, firsty:lasty] EQ max(gphit[firstx:lastx, firsty:lasty])))[0] mod nx
137  ENDIF ELSE ind = 0
138;
139  indexboxzoom = [ind, ind, firsty, lasty]
140;
141  IF keyword_set(nostructure) THEN return, msf
142
143  IF keyword_set(key_forgetold) THEN BEGIN
144    return, {arr:temporary(msf), grid:vargrid, unit:varunit, experiment:varexp, name:varname}
145  ENDIF ELSE BEGIN
146    return, {tab:temporary(msf), grille:vargrid, unite:varunit, experience:varexp, nom:varname}
147  ENDELSE
148
149END
Note: See TracBrowser for help on using the repository browser.