Home > fvcom_prepro > write_FVCOM_tsobc_old.m

write_FVCOM_tsobc_old

PURPOSE ^

Export temperature and salinity forcing at the open boundary.

SYNOPSIS ^

function write_FVCOM_tsobc(basename,time,nSiglay,in_temp,in_salt,Mobj,varargin)

DESCRIPTION ^

 Export temperature and salinity forcing at the open boundary.

 function write_FVCOM_tsobc(basename,time,nSiglay,in_temp,in_salt)

 DESCRIPTION:
    Setup an FVCOM hydrographic open boundary forcing file. Supply either
    uniform values for temperature and salinity or 3D arrays (node,
    sigma_layers, time).

 INPUT
    basename - Model case name (to find the bathymetry and open boundary
    .dat files).
    time - Time (Modified Julian Days)
    nSiglay - Number of sigma layers
    in_temp - Boundary temperature (Celsius)
    in_salt - Boundary salinity (psu)
    Mobj - Mesh Object
    Optional keyword-argument pairs. These control the time variables.
    This script defaults to writing 'Times' only.
    FVCOM needs only one of:
        1. Times: character string of times
        2. Itime and Itime2: integer days and milliseconds since midnight
        3. time: float days.
    FVCOM checks for these in the order above and this script defaults to
    writing Times only. Adjust the keyword-argument pairs to your liking:

    'strtime' = set to true to output the 'Times' variable
    'inttime' = set to true to output the 'Itime' and 'Itime2' variables
    'floattime' = set to true to output the 'time' variable

 OUTPUT:
    FVCOM hydrographic open boundary netCDF file

 Author(s):
    Geoff Cowles (University of Massachusetts Dartmouth)
    Pierre Cazenave (Plymouth Marine Laboratory)
    Karen Amoudry (National Oceanography Centre, Liverpool)

 PWC Revision history
    2012-06-15 Added support for native MATLAB NetCDF routines. Requires
    MATLAB 2010a or higher.
    2012-07-16 Removed hard-coded nSiglay and nSiglev and instead moved to
    arguments list.
    2012-10-08 Updated help to reflect the fact nSiglev is calculated as
    nSiglay+1.
    2012-11-09 Add new arguments to use user defined temperature and
    salinity.
    2013-01-09 Add support for 3D input temperature and salinity (such as
    might be generated with get_POLCOMS_tsobc.m.

 KJA Revision history
    Undated - Add better check for the size of the input arrays (works
    with scalars).
    2013-08-16 - Updated output of Itime2 to avoid rounding errors
    when converting from double to single format.

==============================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function write_FVCOM_tsobc(basename,time,nSiglay,in_temp,in_salt,Mobj,varargin)
0002 % Export temperature and salinity forcing at the open boundary.
0003 %
0004 % function write_FVCOM_tsobc(basename,time,nSiglay,in_temp,in_salt)
0005 %
0006 % DESCRIPTION:
0007 %    Setup an FVCOM hydrographic open boundary forcing file. Supply either
0008 %    uniform values for temperature and salinity or 3D arrays (node,
0009 %    sigma_layers, time).
0010 %
0011 % INPUT
0012 %    basename - Model case name (to find the bathymetry and open boundary
0013 %    .dat files).
0014 %    time - Time (Modified Julian Days)
0015 %    nSiglay - Number of sigma layers
0016 %    in_temp - Boundary temperature (Celsius)
0017 %    in_salt - Boundary salinity (psu)
0018 %    Mobj - Mesh Object
0019 %    Optional keyword-argument pairs. These control the time variables.
0020 %    This script defaults to writing 'Times' only.
0021 %    FVCOM needs only one of:
0022 %        1. Times: character string of times
0023 %        2. Itime and Itime2: integer days and milliseconds since midnight
0024 %        3. time: float days.
0025 %    FVCOM checks for these in the order above and this script defaults to
0026 %    writing Times only. Adjust the keyword-argument pairs to your liking:
0027 %
0028 %    'strtime' = set to true to output the 'Times' variable
0029 %    'inttime' = set to true to output the 'Itime' and 'Itime2' variables
0030 %    'floattime' = set to true to output the 'time' variable
0031 %
0032 % OUTPUT:
0033 %    FVCOM hydrographic open boundary netCDF file
0034 %
0035 % Author(s):
0036 %    Geoff Cowles (University of Massachusetts Dartmouth)
0037 %    Pierre Cazenave (Plymouth Marine Laboratory)
0038 %    Karen Amoudry (National Oceanography Centre, Liverpool)
0039 %
0040 % PWC Revision history
0041 %    2012-06-15 Added support for native MATLAB NetCDF routines. Requires
0042 %    MATLAB 2010a or higher.
0043 %    2012-07-16 Removed hard-coded nSiglay and nSiglev and instead moved to
0044 %    arguments list.
0045 %    2012-10-08 Updated help to reflect the fact nSiglev is calculated as
0046 %    nSiglay+1.
0047 %    2012-11-09 Add new arguments to use user defined temperature and
0048 %    salinity.
0049 %    2013-01-09 Add support for 3D input temperature and salinity (such as
0050 %    might be generated with get_POLCOMS_tsobc.m.
0051 %
0052 % KJA Revision history
0053 %    Undated - Add better check for the size of the input arrays (works
0054 %    with scalars).
0055 %    2013-08-16 - Updated output of Itime2 to avoid rounding errors
0056 %    when converting from double to single format.
0057 %
0058 %==============================================================================
0059 
0060 if nargin == 5
0061     warning(['Assuming uniform terrain-following sigma coordinates. ', ...
0062         'To specify different sigma coordintes, supply a MATLAB mesh ', ...
0063         'structure with fields siglay and siglev.'])
0064 end
0065 
0066 subname = 'write_FVCOM_tsobc';
0067 global ftbverbose;
0068 if ftbverbose
0069   fprintf('\nbegin : %s\n', subname)
0070 end
0071 
0072 % Default to string times as FVCOM looks for these first.
0073 strtime = true;
0074 inttime = false;
0075 floattime = false;
0076 for vv = 1:2:length(varargin)
0077     switch varargin{vv}
0078         case 'strtime'
0079             strtime = true;
0080         case 'inttime'
0081             inttime = true;
0082         case 'floattime'
0083             floattime = true;
0084     end
0085 end
0086 
0087 fvcom_bathy = [basename, '_dep.dat'];
0088 fvcom_obc   = [basename, '_obc.dat'];
0089 tsOBCFile = [basename, '_tsobc.nc'];
0090 
0091 %------------------------------------------------------------------------------
0092 % read in the FVCOM open boundary node data (need node numbers and dimension)
0093 %------------------------------------------------------------------------------
0094 fid = fopen(fvcom_obc,'r');
0095 if(fid  < 0)
0096   error(['file: ' fvcom_obc ' does not exist']);
0097 end
0098 C = textscan(fid, '%s %s %s %s %d', 1);
0099 nObc = C{5};
0100 obc_nodes = zeros(nObc,1);
0101 if(ftbverbose); fprintf('reading obc file\n'); end;
0102 if(ftbverbose); fprintf('# nodes %d\n',nObc); end;
0103 for i=1:nObc
0104   C = textscan(fid, '%d %d %d', 1);
0105   obc_nodes(i) = C{2};
0106 end
0107 
0108 if(ftbverbose); fprintf('obc reading complete\n');end;
0109 
0110 %------------------------------------------------------------------------------
0111 % read in the FVCOM bathymetry data (need bathymetry on open boundary nodes)
0112 %------------------------------------------------------------------------------
0113 fid = fopen(fvcom_bathy,'r');
0114 if(fid  < 0)
0115   error(['file: ' fvcom_bathy ' does not exist']);
0116 end
0117 C = textscan(fid, '%s %s %s %d', 1);
0118 Nverts = C{4};
0119 h = zeros(Nverts,1);
0120 if(ftbverbose); fprintf('reading bathymetry file\n');end;
0121 if(ftbverbose); fprintf('# nodes %d\n',Nverts);end;
0122 for i=1:Nverts
0123   C = textscan(fid, '%f %f %f', 1);
0124   h(i) = C{3};
0125 end
0126 if(ftbverbose); fprintf('min depth %f max depth %f\n',min(h),max(h));end;
0127 if(ftbverbose); fprintf('bathymetry reading complete\n');end;
0128 fclose(fid);
0129 
0130 %--------------------------------------------------------------
0131 % Generate the requisite data
0132 %--------------------------------------------------------------
0133 
0134 % extract bathymetry at open boundary nodes
0135 obc_h = h(obc_nodes);
0136 
0137 % time
0138 % time = 0:1:31.;
0139 nTimes = numel(time);
0140 
0141 nSiglev = nSiglay + 1;
0142 
0143 % Create or process the temperature and salinity arrays.
0144 if max(size(in_temp)) == 1
0145     inc = 1/real(nSiglay);
0146     siglev = 0:-inc:-1;
0147     siglay = nan(1, nSiglay);
0148     for i=1:nSiglay
0149         siglay(i) = mean(siglev(i:i+1));
0150     end
0151     % initialize temperature/salinity arrays
0152     temp = zeros(nObc,nSiglay,nTimes);
0153     salt = zeros(nObc,nSiglay,nTimes);
0154 
0155     % set a constant temperature and salinity
0156     obc_temp = repmat(in_temp, 1, nTimes);
0157     obc_salt = repmat(in_salt, 1, nTimes);
0158 
0159     % set variable temperature and salinity
0160     % for i=1:nTimes
0161     %     obc_temp(i) = 18. + 2.*real(i-1)/nTimes;
0162     %     obc_salt(i) = 30. - 5.*real(i-1)/nTimes;
0163     % end
0164 
0165     % Create 3D array from three 1D arrays
0166     % temp = repmat(obc_temp, [nObc, nSiglay, 1]);
0167     % salt = repmat(obc_salt, [nObc, nSiglay, 1]);
0168     for i=1:nObc
0169         for j=1:nSiglay
0170             temp(i,j,:) = obc_temp;
0171             salt(i,j,:) = obc_salt;
0172         end
0173     end
0174 else
0175     % We have a 3D array already so we just need a couple of stats.
0176     temp = in_temp;
0177     salt = in_salt;
0178 
0179     if nargin == 6 && isfield(Mobj, 'siglay') && isfield(Mobj, 'siglev')
0180         siglev = Mobj.siglev(obc_nodes, :);
0181         siglay = Mobj.siglay(obc_nodes, :);
0182     else
0183         warning('Assuming uniform terrain-following sigma coordinates')
0184         inc = 1/real(nSiglay);
0185         siglev = 0:-inc:-1;
0186         siglay = nan(1, nSiglay);
0187     end
0188 
0189     if nSiglev ~= size(in_temp, 2) + 1 || size(siglev, 2) ~= size(in_temp, 2) + 1 || size(siglev, 2) ~= size(in_salt, 2) + 1
0190         error('Specified number sigma levels does not match supplied data')
0191     end
0192     if nSiglay ~= size(in_temp, 2) || size(siglay, 2) ~= size(in_temp, 2) || size(siglay, 2) ~= size(in_salt, 2)
0193         error('Specified number of sigma layers does not match supplied data')
0194     end
0195 end
0196 
0197 %--------------------------------------------------------------
0198 % set NetCDF variables and dump to file
0199 %--------------------------------------------------------------
0200 
0201 % open boundary forcing
0202 nc = netcdf.create(tsOBCFile, 'clobber');
0203 
0204 % define global attributes
0205 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'title','Open boundary temperature and salinity nudging')
0206 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'type','FVCOM TIME SERIES OBC TS FILE')
0207 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'history', sprintf('File created with %s from the MATLAB fvcom-toolbox', subname))
0208 
0209 
0210 % define dimensions
0211 nobc_dimid=netcdf.defDim(nc,'nobc',nObc);
0212 datestrlen_dimid=netcdf.defDim(nc,'DateStrLen',26);
0213 time_dimid=netcdf.defDim(nc,'time',netcdf.getConstant('NC_UNLIMITED'));
0214 siglay_dimid=netcdf.defDim(nc,'siglay',nSiglay);
0215 siglev_dimid=netcdf.defDim(nc,'siglev',nSiglev);
0216 
0217 % variables
0218 if strtime
0219     Times_varid=netcdf.defVar(nc,'Times','NC_CHAR',[datestrlen_dimid, time_dimid]);
0220     netcdf.putAtt(nc,Times_varid,'time_zone','UTC');
0221 end
0222 
0223 if floattime
0224     time_varid=netcdf.defVar(nc,'time','NC_FLOAT',time_dimid);
0225     netcdf.putAtt(nc,time_varid,'long_name','time');
0226     netcdf.putAtt(nc,time_varid,'units','days since 1858-11-17 00:00:00');
0227     netcdf.putAtt(nc,time_varid,'time_zone','UTC');
0228 end
0229 
0230 if inttime
0231     itime_varid=netcdf.defVar(nc,'Itime','NC_INT',time_dimid);
0232     netcdf.putAtt(nc,itime_varid,'units','days since 1858-11-17 00:00:00');
0233     netcdf.putAtt(nc,itime_varid,'format','modified julian day (MJD)');
0234     netcdf.putAtt(nc,itime_varid,'time_zone','UTC');
0235 
0236     itime2_varid=netcdf.defVar(nc,'Itime2','NC_INT',time_dimid);
0237     netcdf.putAtt(nc,itime2_varid,'units','msec since 00:00:00');
0238     netcdf.putAtt(nc,itime2_varid,'time_zone','UTC');
0239 end
0240 
0241 nobc_varid=netcdf.defVar(nc,'obc_nodes','NC_INT',nobc_dimid);
0242 netcdf.putAtt(nc,nobc_varid,'long_name','Open Boundary Node Number');
0243 netcdf.putAtt(nc,nobc_varid,'grid','obc_grid');
0244 netcdf.putAtt(nc,nobc_varid,'type','data');
0245 
0246 obc_h_varid=netcdf.defVar(nc,'obc_h','NC_FLOAT',nobc_dimid);
0247 netcdf.putAtt(nc,obc_h_varid,'long_name','Open Boundary Depth');
0248 netcdf.putAtt(nc,obc_h_varid,'units','m');
0249 netcdf.putAtt(nc,obc_h_varid,'grid','obc_grid');
0250 netcdf.putAtt(nc,obc_h_varid,'type','data');
0251 
0252 obc_siglev_varid=netcdf.defVar(nc,'siglev','NC_FLOAT',[nobc_dimid,siglev_dimid]);
0253 netcdf.putAtt(nc,obc_siglev_varid,'long_name','ocean_sigma/general_coordinate');
0254 netcdf.putAtt(nc,obc_siglev_varid,'grid','obc_grid');
0255 
0256 obc_siglay_varid=netcdf.defVar(nc,'siglay','NC_FLOAT',[nobc_dimid,siglay_dimid]);
0257 netcdf.putAtt(nc,obc_siglay_varid,'long_name','ocean_sigma/general_coordinate');
0258 netcdf.putAtt(nc,obc_siglay_varid,'grid','obc_grid');
0259 
0260 obc_temp_varid=netcdf.defVar(nc,'obc_temp','NC_FLOAT',[nobc_dimid,siglay_dimid,time_dimid]);
0261 netcdf.putAtt(nc,obc_temp_varid,'long_name','sea_water_temperature');
0262 netcdf.putAtt(nc,obc_temp_varid,'units','Celcius');
0263 netcdf.putAtt(nc,obc_temp_varid,'grid','obc_grid');
0264 
0265 obc_salinity_varid=netcdf.defVar(nc,'obc_salinity','NC_FLOAT',[nobc_dimid,siglay_dimid,time_dimid]);
0266 netcdf.putAtt(nc,obc_salinity_varid,'long_name','sea_water_salinity');
0267 netcdf.putAtt(nc,obc_salinity_varid,'units','PSU');
0268 netcdf.putAtt(nc,obc_salinity_varid,'grid','obc_grid');
0269 
0270 % end definitions
0271 netcdf.endDef(nc);
0272 
0273 % write data
0274 netcdf.putVar(nc,nobc_varid,obc_nodes);
0275 netcdf.putVar(nc,obc_h_varid,obc_h);
0276 netcdf.putVar(nc,obc_siglev_varid,siglev);
0277 netcdf.putVar(nc,obc_siglay_varid,siglay);
0278 if strtime
0279     nStringOut = char();
0280     [nYr, nMon, nDay, nHour, nMin, nSec] = mjulian2greg(time);
0281     for i=1:nTimes
0282         nDate = [nYr(i), nMon(i), nDay(i), nHour(i), nMin(i), nSec(i)];
0283         nStringOut = [nStringOut, sprintf('%04i/%02i/%02i %02i:%02i:%09.6f', nDate)];
0284     end
0285     netcdf.putVar(nc,Times_varid,[0, 0], [26, nTimes],nStringOut);
0286 end
0287 if floattime
0288     netcdf.putVar(nc,time_varid,0,numel(time),time);
0289 end
0290 if inttime
0291     netcdf.putVar(nc,itime_varid,floor(time));
0292     %netcdf.putVar(nc,itime2_varid,0,numel(time),mod(time,1)*24*3600*1000); % PWC original
0293     % KJA edit: avoids rounding errors when converting from double to single
0294     % Rounds to nearest multiple of the number of msecs in an hour
0295     netcdf.putVar(nc,itime2_varid,0,numel(time),round((mod(time,1)*24*3600*1000)/(3600*1000))*(3600*1000));
0296 end
0297 netcdf.putVar(nc,obc_temp_varid,temp);
0298 netcdf.putVar(nc,obc_salinity_varid,salt);
0299 
0300 % close file
0301 netcdf.close(nc);
0302 
0303 if ftbverbose; fprintf('end   : %s\n', subname); end

Generated on Wed 10-Aug-2016 16:44:39 by m2html © 2005