Home > fvcom_prepro > read_sigma.m

read_sigma

PURPOSE ^

Read an FVCOM sigma layers file and output z values into Mobj.

SYNOPSIS ^

function Mobj = read_sigma(Mobj, sigmafile)

DESCRIPTION ^

 Read an FVCOM sigma layers file and output z values into Mobj.

 Mobj = read_sigma(Mobj, sigmafile)

 DESCRIPTION:
   Read a sigma file and calculate the sigma layer depths

 INPUT:
   Mobj:       Mesh object which must contain Mobj.h (depths).
   sigmafile : Full path to an FVCOM sigma.dat file.

 OUTPUT:
   Mobj:       Mesh object with four new fields:
               - siglayz and siglevz: contain depths of the sigma layers
               and levels at each grid node.
               - siglayzc and siglevzc: contain depths of the sigma layers
               and levels at each element centre.
               - siglay and siglev: the sigma layer and levels in the
               range 0 to -1.

 EXAMPLE USAGE:
   Mobj = read_sigma(Mobj, 'sigma.dat')

 Author(s):
   Pierre Cazenave (Plymouth Marine Laboratory)

 Revision history
   2013-01-08 Based on the code in show_sigma.m but instead of calculating
   sigma layers along a user-defined line, the depths are calculated for
   each node in the unstructured grid.
   2013-01-10 Added two new outputs to the returned Mobj (siglay and
   siglev). They're useful in write_FVCOM_tsobc.m.
   2013-04-23 Add support for geometric sigma distributions as well as
   slightly more robust reading of and checks on the parameters in the
   input file. Also changed the way the uniform distribution is calculated
   (by using a P_SIGMA value of 1 and the sigma_geo.m function rather than
   fiddling around with ranges, although the output is the same).
   2014-04-28 Add the sigma levels for the element centres in addition to
   the element nodes.
   2016-05-25 Made the sigma distributions be spatially resolved for the
   UNIFORM, GEOMETRIC and GENERALIZED cases. Also removed the UNIFORM
   distribution from the checks on the values of parameters which only
   belong in the GENERALIZED case.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function Mobj = read_sigma(Mobj, sigmafile)
0002 % Read an FVCOM sigma layers file and output z values into Mobj.
0003 %
0004 % Mobj = read_sigma(Mobj, sigmafile)
0005 %
0006 % DESCRIPTION:
0007 %   Read a sigma file and calculate the sigma layer depths
0008 %
0009 % INPUT:
0010 %   Mobj:       Mesh object which must contain Mobj.h (depths).
0011 %   sigmafile : Full path to an FVCOM sigma.dat file.
0012 %
0013 % OUTPUT:
0014 %   Mobj:       Mesh object with four new fields:
0015 %               - siglayz and siglevz: contain depths of the sigma layers
0016 %               and levels at each grid node.
0017 %               - siglayzc and siglevzc: contain depths of the sigma layers
0018 %               and levels at each element centre.
0019 %               - siglay and siglev: the sigma layer and levels in the
0020 %               range 0 to -1.
0021 %
0022 % EXAMPLE USAGE:
0023 %   Mobj = read_sigma(Mobj, 'sigma.dat')
0024 %
0025 % Author(s):
0026 %   Pierre Cazenave (Plymouth Marine Laboratory)
0027 %
0028 % Revision history
0029 %   2013-01-08 Based on the code in show_sigma.m but instead of calculating
0030 %   sigma layers along a user-defined line, the depths are calculated for
0031 %   each node in the unstructured grid.
0032 %   2013-01-10 Added two new outputs to the returned Mobj (siglay and
0033 %   siglev). They're useful in write_FVCOM_tsobc.m.
0034 %   2013-04-23 Add support for geometric sigma distributions as well as
0035 %   slightly more robust reading of and checks on the parameters in the
0036 %   input file. Also changed the way the uniform distribution is calculated
0037 %   (by using a P_SIGMA value of 1 and the sigma_geo.m function rather than
0038 %   fiddling around with ranges, although the output is the same).
0039 %   2014-04-28 Add the sigma levels for the element centres in addition to
0040 %   the element nodes.
0041 %   2016-05-25 Made the sigma distributions be spatially resolved for the
0042 %   UNIFORM, GEOMETRIC and GENERALIZED cases. Also removed the UNIFORM
0043 %   distribution from the checks on the values of parameters which only
0044 %   belong in the GENERALIZED case.
0045 
0046 [~, subname] = fileparts(mfilename('fullpath'));
0047 
0048 global ftbverbose
0049 if ftbverbose
0050     fprintf('\nbegin : %s\n', subname)
0051 end
0052 
0053 fid = fopen(sigmafile,'r');
0054 assert(fid >= 0, 'Sigma file: %s does not exist', sigmafile)
0055 
0056 while ~feof(fid)
0057     line = fgetl(fid);
0058     if isempty(line) || strncmp(line, '!', 1) || ~ischar(line)
0059         continue
0060     end
0061 
0062     % Clean up the input string to make matching a bit easier (trim
0063     % whitespace and remove duplicate spaces in the keywords).
0064     C = strtrim(regexpi(regexprep(line, '\s+', ' '), '=', 'split'));
0065 
0066     switch lower(C{1})
0067         case 'number of sigma levels'
0068             nlev = str2double(C{2});
0069         case 'sigma coordinate type'
0070             sigtype = C{2};
0071         case 'sigma power'
0072             sigpow = str2double(C{2});
0073         case 'du'
0074             du = str2double(C{2});
0075         case 'dl'
0076             dl = str2double(C{2});
0077         case 'min constant depth'
0078             min_constant_depth = str2double(C{2});
0079         case 'ku'
0080             ku = str2double(C{2});
0081         case 'kl'
0082             kl = str2double(C{2});
0083         case 'zku'
0084             s = str2double(regexp(C{2}, ' ', 'split'));
0085             zku = zeros(ku, 1);
0086             for i = 1:ku
0087                 zku(i) = s(i);
0088             end
0089         case 'zkl'
0090             s = str2double(regexp(C{2}, ' ', 'split'));
0091             zkl = zeros(kl, 1);
0092             for i = 1:kl
0093                 zkl(i) = s(i);
0094             end
0095     end
0096 end
0097 
0098 % Do some checks if we've got uniform or generalised coordinates to make
0099 % sure the input is correct.
0100 if strcmpi(sigtype, 'GENERALIZED')
0101     if numel(zku) ~= ku
0102         warning('Number of zku values does not match the number specified in ku')
0103     end
0104     if numel(zkl) ~= kl
0105         warning('Number of zkl values does not match the number specified in kl')
0106     end
0107 end
0108 
0109 if ftbverbose
0110     % Should be present in all sigma files.
0111     fprintf('nlev\t%d\n', nlev)
0112     fprintf('sigtype\t%s\n', sigtype)
0113     Mobj.nlev = nlev;
0114     Mobj.sigtype = sigtype;
0115     % Only present in geometric sigma files.
0116     if strcmpi(sigtype, 'GEOMETRIC')
0117         fprintf('sigpow\t%d\n', sigpow)
0118         Mobj.sigpow = sigpow;
0119     end
0120     
0121     % Only in the generalised or uniform sigma files.
0122     if strcmpi(sigtype, 'GENERALIZED')
0123         fprintf('du\t%d\n', du)
0124         fprintf('dl\t%d\n', dl)
0125         fprintf('min_constant_depth\t%f\n', min_constant_depth)
0126         fprintf('ku\t%d\n', ku)
0127         fprintf('kl\t%d\n', kl)
0128         fprintf('zku\t%d\n', zku)
0129         fprintf('zkl\t%d\n', zkl)
0130         Mobj.du = du;
0131         Mobj.dl = dl;
0132         Mobj.min_constant_depth = min_constant_depth;
0133         Mobj.ku = ku;
0134         Mobj.kl = kl;
0135         Mobj.zku = zku;
0136         Mobj.zkl = zkl;
0137     end
0138     if strcmpi(sigtype, 'TANH')
0139         fprintf('du\t%d\n', du)
0140         fprintf('dl\t%d\n', dl)
0141         Mobj.du = du;
0142         Mobj.dl = dl;
0143     end
0144 end
0145 
0146 % Calculate the sigma distributions at each grid node.
0147 nx = length(Mobj.h);
0148 switch lower(sigtype)
0149     case 'generalized'
0150         z = nan([nx, nlev]);
0151         h = Mobj.h; % avoids broadcasting Mobj on every iteration
0152         % Not sure if a parfor is wise here as the pool start up time might
0153         % exceed the run time. For big grids, the parfor is probably a wise
0154         % move.
0155         parfor i = 1:nx
0156             z(i, :) = sigma_gen(nlev, dl, du, kl, ku, zkl, zku, ...
0157                 h(i), min_constant_depth);
0158         end
0159         clear h
0160     case 'uniform'
0161         z = repmat(sigma_geo(nlev, 1), [nx, 1]);
0162     case 'geometric'
0163         z = repmat(sigma_geo(nlev, sigpow), [nx, 1]);
0164     case 'tanh'
0165         z = repmat(sigma_tanh(nlev, dl,du), [nx, 1]);
0166     otherwise
0167         error('Don''t recognise sigtype %s (is it supported?)', sigtype)
0168 end
0169 
0170 % Create a depth array for the element centres.
0171 hc = nodes2elems(Mobj.h, Mobj);
0172 ne = length(hc);
0173 
0174 % Create a siglay variable (i.e. midpoint in the sigma levels).
0175 zlay = z(:, 1:end - 1) + (diff(z, [], 2) ./ 2);
0176 zlayc = nan(ne, nlev - 1);
0177 zc = nan(ne, nlev);
0178 for i = 1:nlev
0179     zc(:, i) = nodes2elems(z(:, i), Mobj);
0180     if i ~= nlev
0181         zlayc(:, i) = nodes2elems(zlay(:, i), Mobj);
0182     end
0183 end
0184 Mobj.siglevz = repmat(Mobj.h, 1, nlev) .* z;
0185 Mobj.siglayz = repmat(Mobj.h, 1, nlev-1) .* zlay;
0186 Mobj.siglevzc = repmat(hc, 1, nlev) .* zc;
0187 Mobj.siglayzc = repmat(hc, 1, nlev-1) .* zlayc;
0188 Mobj.siglayc = zlayc;
0189 Mobj.siglevc = zc;
0190 % Add the sigma levels and layers to the Mobj.
0191 Mobj.siglev = z;
0192 Mobj.siglay = zlay;
0193 
0194 if ftbverbose
0195     fprintf('end   : %s\n', subname)
0196 end

Generated on Wed 20-Feb-2019 16:06:01 by m2html © 2005