NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/gliderproc/trunk/MATLAB/opnml/FEM/vertsliceFEM.m

Revision 495 (checked in by cbc, 12 years ago)

Initial import of Stark code.

Line 
1 function qlev=horzslicefem(zgrid,q,zlev)
2 %HORZSLICEFEM slice a FEM domain horizontally
3 %   HORZSLICEFEM slices a 3-D FEM domain specified in zgrid
4 %   horizontally at vertical position zlev, mapping the
5 %   data in q to that level.
6 %
7 % Inputs (all three arguments REQUIRED):
8 %   zgrid - vertical position of FEM domain, in [nn x nnv] shape
9 %       q - [nn x nnv] scalar field, in [nn x nnv] shape
10 %           or a 3-d array of several variables to slice,
11 %           [nn x nnv x nqs], where nqs is the number of scalars
12 %           to slice
13 %    zlev - the vertical level at which to make slice
14 %
15 % Output:
16 %    qlev - quantity q mapped to zlev
17 %
18 % ALTERNATIVE: (not yet available)
19 %  Input (Both arguments REQUIRED):
20 %   fem_icq4_struct - structure containing .icq4 variables
21 %   zlev - the vertical level at which to make slice
22 %
23 % Output:
24 %    qlev - all 3-D .icq4 field variables mapped to zlev.
25 %           in the following order:
26 %            UZMID,VZMID,WZMID,Q2MID,Q2LMID,TMPMID,SALMID
27 %
28 % Call as: >> qlev=horzslicefem(zgrid,q,zlev)
29 %    OR:   >> qlev=horzslicefem(fem_icq4_struct,zlev)
30 %   
31 %
32 % Written by: Brian O. Blanton
33 %             December 1998   
34
35 nargchk(2,3,nargin);
36
37 if isstruct(zgrid)
38    error('fem_icq4_struct input to HORZSLICEFEM not yet supported')
39 end
40
41 [nn,nnv]=size(zgrid);
42 [n,m,nq]=size(q);
43 if n~=nn | nnv~=m
44    error('Size mismatch between zgrid and q in HORZSLICEFEM.')
45 end
46
47 % yank zgrid,q around a bit; now it's nnv X nn, top down
48 zgrid=flipud(zgrid');
49 %
50
51 if nq==1
52    q2=flipud(q');
53 else   % transpose and flipud each scalar component
54    q2=ones(m,n,nq);
55    for i=1:nq
56       q2(:,:,i)=flipud(q(:,:,i)');
57    end
58 end
59
60
61 % ilower is the vertical level immediately below the
62 % vertical position zlev for each horizontal node iok
63
64 ilower=zgrid<zlev;
65 % find which nodes can bound zlev by surface and bottom
66 % heights; inotok are the node numbers with zlev deeper than,
67 % or above, the water column;  iok are the nude numbers entirely
68 % within the water column.
69 inotok=find(sum(ilower)==0);
70 iok=find(sum(ilower)>0);
71 nok=length(iok);
72
73 % remove the "water columns" that do not bound zlev
74 ilower(:,inotok)=[];
75
76 % Determine which indices in zgrid represent the bounding
77 % vertical levels
78 [i,j]=find(ilower==1);
79 idx=[1 find(diff(j')==1)+1];
80 ilower=i(idx);
81 iupper=ilower-1;
82
83 % then convert them to vector access, whereby zgrid is essentially
84 % treated as a 1x(nn*nnv) vector
85 ilower=(0:length(iok)-1)*nnv+ilower';
86 iupper=(0:length(iok)-1)*nnv+iupper';
87 zt=zgrid(:,iok);
88 qt=q2(:,iok,:);
89
90 % extract the bounding depths for each node in iok
91 zup=zt(iupper);
92 zdown=zt(ilower);
93
94 % extract scalars similarly
95 if nq==1
96    qup=qt(iupper);
97    qdown=qt(ilower);
98 else
99    qup=ones(nok,nq);
100    qdown=ones(nok,nq);
101    for i=1:nq
102       temp=qt(:,:,i);
103       qup(:,i)=temp(iupper');
104       qdown(:,i)=temp(ilower');
105    end
106 end
107
108 % compute differential heights and 1-D linear basis functions
109 zdiff=zup-zdown;
110 b1=(zup-zlev)./zdiff;
111 b2=(zlev-zdown)./zdiff;
112
113 % Interpolate scalars to zlev.
114 if nq==1
115    qlev=NaN*ones(nn,nq);
116    qlev(iok)=qdown.*b1+qup.*b2;
117 else
118    qlev=NaN*ones(nn,nq);
119    for i=1:nq
120       qlev(iok,i)=qdown(:,i).*b1'+qup(:,i).*b2';
121    end
122 end
123
124
125
126 % IMPROVEMENTS: The only looping is over the number of scalars
127 % input, nq; this can and will be removes in the future.
128 % Also, zlev should be allowed to be a vector of vertical
129 % levels at which to slice.
Note: See TracBrowser for help on using the browser.