0001 function write_FVCOM_nested_forcing(nest, ncfile, nesttype)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 [~, subname] = fileparts(mfilename('fullpath'));
0106
0107 global ftbverbose
0108 if ftbverbose
0109 fprintf('\nbegin : %s\n', subname)
0110 end
0111
0112 if nargin == 2
0113 nesttype = 1;
0114 elseif nargin < 2 || nargin > 3
0115 error(['Incorrect input arguments. Supply netCDF file path, ', ...
0116 'nesting struct and optionally the nesting type (1, 2 or 3).'])
0117 end
0118
0119
0120 required = {'time', 'x', 'y', 'lon', 'lat', 'xc', 'yc', 'lonc', 'latc', ...
0121 'nv', 'h', 'hc', 'u', 'v', 'ua', 'va', 'temp', 'salinity', 'hyw', ...
0122 'weight_cell', 'weight_node', 'siglay', 'siglayc', 'siglev', 'siglevc'};
0123 fields = fieldnames(nest);
0124 for f = required
0125 if any(strcmpi(f{1}, {'weight_node', 'weight_cell'})) && nesttype == 3
0126 assert(any(strcmpi(f, fields)), 'Missing %s input struct field', f{1});
0127 elseif any(strcmpi(f{1}, {'weight_node', 'weight_cell'})) && nesttype ~= 3
0128 continue
0129 else
0130 assert(any(strcmpi(f, fields)), 'Missing %s input struct field', f{1});
0131 end
0132 end
0133
0134 [elems, nsiglay, ntimes] = size(nest.u);
0135 nsiglev = nsiglay + 1;
0136 [nodes, ~] = size(nest.zeta);
0137
0138
0139
0140 if exist(ncfile, 'file')
0141 delete(ncfile)
0142 end
0143 nc = netcdf.create(ncfile, 'NETCDF4');
0144
0145
0146 if ftbverbose
0147 fprintf('create attributes\n')
0148 end
0149 netcdf.putAtt(nc, netcdf.getConstant('NC_GLOBAL'), 'type', ...
0150 'FVCOM nestING TIME SERIES FILE')
0151 netcdf.putAtt(nc, netcdf.getConstant('NC_GLOBAL'), 'title', ...
0152 sprintf('FVCOM nestING TYPE %d TIME SERIES data for open boundary', ...
0153 nesttype))
0154 netcdf.putAtt(nc, netcdf.getConstant('NC_GLOBAL'), 'history', ...
0155 sprintf('File created using %s from the MATLAB fvcom-toolbox', subname))
0156 netcdf.putAtt(nc, netcdf.getConstant('NC_GLOBAL'), 'filename', ncfile)
0157 netcdf.putAtt(nc, netcdf.getConstant('NC_GLOBAL'), 'Conventions', 'CF-1.0')
0158
0159
0160 if ftbverbose
0161 fprintf('define dimensions\n')
0162 end
0163 elem_dimid = netcdf.defDim(nc, 'nele', elems);
0164 node_dimid = netcdf.defDim(nc, 'node', nodes);
0165 three_dimid = netcdf.defDim(nc, 'three', 3);
0166 time_dimid = netcdf.defDim(nc, 'time', netcdf.getConstant('NC_UNLIMITED'));
0167 siglay_dimid = netcdf.defDim(nc, 'siglay', nsiglay);
0168 siglev_dimid = netcdf.defDim(nc, 'siglev', nsiglev);
0169 datestrlen_dimid = netcdf.defDim(nc, 'DateStrLen', 26);
0170
0171
0172 if ftbverbose
0173 fprintf('define variables\n')
0174 end
0175 time_varid = netcdf.defVar(nc, 'time', 'NC_FLOAT', time_dimid);
0176 netcdf.putAtt(nc, time_varid, 'long_name', 'time');
0177 netcdf.putAtt(nc, time_varid, 'units', 'days since 1858-11-17 00:00:00');
0178 netcdf.putAtt(nc, time_varid, 'format', 'modified julian day (MJD)');
0179 netcdf.putAtt(nc, time_varid, 'time_zone', 'UTC');
0180
0181 itime_varid = netcdf.defVar(nc, 'Itime', 'NC_INT', ...
0182 time_dimid);
0183 netcdf.putAtt(nc, itime_varid, 'units', 'days since 1858-11-17 00:00:00');
0184 netcdf.putAtt(nc, itime_varid, 'format', 'modified julian day (MJD)');
0185 netcdf.putAtt(nc, itime_varid, 'time_zone', 'UTC');
0186
0187 itime2_varid = netcdf.defVar(nc, 'Itime2', 'NC_INT', ...
0188 time_dimid);
0189 netcdf.putAtt(nc, itime2_varid, 'units', 'msec since 00:00:00');
0190 netcdf.putAtt(nc, itime2_varid, 'time_zone', 'UTC');
0191
0192 Times_varid = netcdf.defVar(nc, 'Times' ,'NC_CHAR', ...
0193 [datestrlen_dimid, time_dimid]);
0194 netcdf.putAtt(nc, Times_varid, 'time_zone', 'UTC');
0195
0196 x_varid = netcdf.defVar(nc, 'x', 'NC_FLOAT', ...
0197 node_dimid);
0198 netcdf.putAtt(nc, x_varid, 'units', 'meters');
0199 netcdf.putAtt(nc, x_varid, 'long_name', 'nodal x-coordinate');
0200
0201 y_varid = netcdf.defVar(nc, 'y', 'NC_FLOAT', ...
0202 node_dimid);
0203 netcdf.putAtt(nc, y_varid, 'units', 'meters');
0204 netcdf.putAtt(nc, y_varid, 'long_name', 'nodal y-coordinate');
0205
0206 xc_varid = netcdf.defVar(nc, 'xc', 'NC_FLOAT', ...
0207 elem_dimid);
0208 netcdf.putAtt(nc, xc_varid, 'units', 'meters');
0209 netcdf.putAtt(nc, xc_varid, 'long_name', 'zonal x-coordinate');
0210
0211 yc_varid = netcdf.defVar(nc, 'yc', 'NC_FLOAT', ...
0212 elem_dimid);
0213 netcdf.putAtt(nc, yc_varid, 'units', 'meters');
0214 netcdf.putAtt(nc, yc_varid, 'long_name', 'zonal y-coordinate');
0215
0216 lon_varid = netcdf.defVar(nc, 'lon', 'NC_FLOAT', ...
0217 node_dimid);
0218 netcdf.putAtt(nc, lon_varid, 'units', 'degrees_east');
0219 netcdf.putAtt(nc, lon_varid, 'standard_name', 'longitude');
0220 netcdf.putAtt(nc, lon_varid, 'long_name', 'nodal longitude');
0221
0222 lat_varid = netcdf.defVar(nc, 'lat', 'NC_FLOAT', ...
0223 node_dimid);
0224 netcdf.putAtt(nc, lat_varid, 'units', 'degrees_north');
0225 netcdf.putAtt(nc, lat_varid, 'standard_name', 'latitude');
0226 netcdf.putAtt(nc, lat_varid, 'long_name', 'nodal latitude');
0227
0228 lonc_varid = netcdf.defVar(nc, 'lonc', 'NC_FLOAT', ...
0229 elem_dimid);
0230 netcdf.putAtt(nc, lonc_varid, 'units', 'degrees_east');
0231 netcdf.putAtt(nc, lonc_varid, 'standard_name', 'longitude');
0232 netcdf.putAtt(nc, lonc_varid, 'long_name', 'zonal longitude');
0233
0234 latc_varid = netcdf.defVar(nc, 'latc', 'NC_FLOAT', ...
0235 elem_dimid);
0236 netcdf.putAtt(nc, latc_varid, 'units', 'degrees_north');
0237 netcdf.putAtt(nc, latc_varid, 'standard_name', 'latitude');
0238 netcdf.putAtt(nc, latc_varid, 'long_name', 'zonal latitude');
0239
0240 nv_varid = netcdf.defVar(nc, 'nv', 'NC_INT', ...
0241 [elem_dimid, three_dimid]);
0242 netcdf.putAtt(nc, xc_varid, 'units', 'meters');
0243 netcdf.putAtt(nc, xc_varid, 'long_name', 'zonal x-coordinate');
0244
0245 zeta_varid = netcdf.defVar(nc, 'zeta', 'NC_FLOAT', ...
0246 [node_dimid, time_dimid]);
0247 netcdf.putAtt(nc, zeta_varid, 'long_name', 'Water Surface Elevation');
0248 netcdf.putAtt(nc, zeta_varid, 'units', 'meters');
0249 netcdf.putAtt(nc, zeta_varid, 'positive', 'up');
0250 netcdf.putAtt(nc, zeta_varid, 'standard_name', ...
0251 'sea_surface_height_above_geoid');
0252 netcdf.putAtt(nc, zeta_varid, 'grid', 'Bathymetry_Mesh');
0253 netcdf.putAtt(nc, zeta_varid, 'coordinates', 'time lat lon');
0254 netcdf.putAtt(nc, zeta_varid, 'type', 'data');
0255 netcdf.putAtt(nc, zeta_varid, 'location', 'node');
0256
0257 ua_varid = netcdf.defVar(nc, 'ua', 'NC_FLOAT', ...
0258 [elem_dimid, time_dimid]);
0259 netcdf.putAtt(nc, ua_varid, 'long_name', 'Vertically Averaged x-velocity');
0260 netcdf.putAtt(nc, ua_varid, 'units', 'meters s-1');
0261 netcdf.putAtt(nc, ua_varid, 'grid', 'fvcom_grid');
0262 netcdf.putAtt(nc, ua_varid, 'type', 'data');
0263
0264 va_varid = netcdf.defVar(nc, 'va', 'NC_FLOAT', ...
0265 [elem_dimid, time_dimid]);
0266 netcdf.putAtt(nc, va_varid, 'long_name', 'Vertically Averaged y-velocity');
0267 netcdf.putAtt(nc, va_varid, 'units', 'meters s-1');
0268 netcdf.putAtt(nc, va_varid, 'grid', 'fvcom_grid');
0269 netcdf.putAtt(nc, va_varid, 'type', 'data');
0270
0271 u_varid = netcdf.defVar(nc, 'u', 'NC_FLOAT', ...
0272 [elem_dimid, siglay_dimid, time_dimid]);
0273 netcdf.putAtt(nc, u_varid, 'long_name', 'Eastward Water Velocity');
0274 netcdf.putAtt(nc, u_varid, 'units', 'meters s-1');
0275 netcdf.putAtt(nc, u_varid, 'standard_name', 'eastward_sea_water_velocity');
0276 netcdf.putAtt(nc, u_varid, 'grid', 'fvcom_grid');
0277 netcdf.putAtt(nc, u_varid, 'coordinates', 'time siglay latc lonc');
0278 netcdf.putAtt(nc, u_varid, 'type', 'data');
0279 netcdf.putAtt(nc, u_varid, 'location', 'face');
0280
0281 v_varid = netcdf.defVar(nc, 'v', 'NC_FLOAT', ...
0282 [elem_dimid, siglay_dimid, time_dimid]);
0283 netcdf.putAtt(nc, v_varid, 'long_name', 'Northward Water Velocity');
0284 netcdf.putAtt(nc, v_varid, 'units', 'meters s-1');
0285 netcdf.putAtt(nc, v_varid, 'standard_name', ...
0286 'Northward_sea_water_velocity');
0287 netcdf.putAtt(nc, v_varid, 'grid', 'fvcom_grid');
0288 netcdf.putAtt(nc, v_varid, 'coordinates', 'time siglay latc lonc');
0289 netcdf.putAtt(nc, v_varid, 'type', 'data');
0290 netcdf.putAtt(nc, v_varid, 'location', 'face');
0291
0292 temp_varid = netcdf.defVar(nc, 'temp', 'NC_FLOAT', ...
0293 [node_dimid, siglay_dimid, time_dimid]);
0294 netcdf.putAtt(nc, temp_varid, 'long_name', 'Temperature');
0295 netcdf.putAtt(nc, temp_varid, 'standard_name', 'sea_water_temperature');
0296 netcdf.putAtt(nc, temp_varid, 'units', 'degrees Celcius');
0297 netcdf.putAtt(nc, temp_varid, 'grid', 'fvcom_grid');
0298 netcdf.putAtt(nc, temp_varid, 'coordinates', 'time siglay lat lon');
0299 netcdf.putAtt(nc, temp_varid, 'type', 'data');
0300 netcdf.putAtt(nc, temp_varid, 'location', 'node');
0301
0302 salinity_varid = netcdf.defVar(nc, 'salinity', 'NC_FLOAT', ...
0303 [node_dimid, siglay_dimid, time_dimid]);
0304 netcdf.putAtt(nc, salinity_varid, 'long_name', 'Salinity');
0305 netcdf.putAtt(nc, salinity_varid, 'standard_name', 'sea_water_salinity');
0306 netcdf.putAtt(nc, salinity_varid, 'units', '1e-3');
0307 netcdf.putAtt(nc, salinity_varid, 'grid', 'fvcom_grid');
0308 netcdf.putAtt(nc, salinity_varid, 'coordinates', 'time siglay lat lon');
0309 netcdf.putAtt(nc, salinity_varid, 'type', 'data');
0310 netcdf.putAtt(nc, salinity_varid, 'location', 'node');
0311
0312 hyw_varid = netcdf.defVar(nc, 'hyw', 'NC_FLOAT', ...
0313 [node_dimid, siglev_dimid, time_dimid]);
0314 netcdf.putAtt(nc, hyw_varid, 'long_name', ...
0315 'hydro static vertical velocity');
0316 netcdf.putAtt(nc, hyw_varid, 'units', 'meters s-1');
0317 netcdf.putAtt(nc, hyw_varid, 'grid', 'fvcom_grid');
0318 netcdf.putAtt(nc, hyw_varid, 'type', 'data');
0319 netcdf.putAtt(nc, hyw_varid, 'coordinates', 'time siglay lat lon');
0320
0321 siglay_varid = netcdf.defVar(nc, 'siglay', 'NC_FLOAT', ...
0322 [node_dimid, siglay_dimid]);
0323 netcdf.putAtt(nc, siglay_varid, 'long_name', 'Sigma Layers');
0324 netcdf.putAtt(nc, siglay_varid, 'standard_name', 'ocean_sigma/general_coordinate');
0325 netcdf.putAtt(nc, siglay_varid, 'positive', 'up');
0326 netcdf.putAtt(nc, siglay_varid, 'valid_min', -1);
0327 netcdf.putAtt(nc, siglay_varid, 'valid_max', 0);
0328 netcdf.putAtt(nc, siglay_varid, 'formula_terms', 'sigma: siglay eta: zeta depth: h');
0329
0330 siglayc_varid = netcdf.defVar(nc, 'siglay_center', 'NC_FLOAT', ...
0331 [elem_dimid, siglay_dimid]);
0332 netcdf.putAtt(nc, siglayc_varid, 'long_name', 'Sigma Layers');
0333 netcdf.putAtt(nc, siglayc_varid, 'standard_name', 'ocean_sigma/general_coordinate');
0334 netcdf.putAtt(nc, siglayc_varid, 'positive', 'up');
0335 netcdf.putAtt(nc, siglayc_varid, 'valid_min', -1);
0336 netcdf.putAtt(nc, siglayc_varid, 'valid_max', 0);
0337 netcdf.putAtt(nc, siglayc_varid, 'formula_terms', 'sigma: siglay_center eta: zeta_center depth: h_center');
0338
0339 siglev_varid = netcdf.defVar(nc, 'siglev', 'NC_FLOAT', ...
0340 [node_dimid, siglev_dimid]);
0341 netcdf.putAtt(nc, siglev_varid, 'long_name', 'Sigma Levels');
0342 netcdf.putAtt(nc, siglev_varid, 'standard_name', 'ocean_sigma/general_coordinate');
0343 netcdf.putAtt(nc, siglev_varid, 'positive', 'up');
0344 netcdf.putAtt(nc, siglev_varid, 'valid_min', -1);
0345 netcdf.putAtt(nc, siglev_varid, 'valid_max', 0);
0346 netcdf.putAtt(nc, siglev_varid, 'formula_terms', 'sigma:siglev eta: zeta depth: h');
0347
0348 siglevc_varid = netcdf.defVar(nc, 'siglev_center', 'NC_FLOAT', ...
0349 [elem_dimid, siglev_dimid]);
0350 netcdf.putAtt(nc, siglevc_varid, 'long_name', 'Sigma Layers');
0351 netcdf.putAtt(nc, siglevc_varid, 'standard_name', 'ocean_sigma/general_coordinate');
0352 netcdf.putAtt(nc, siglevc_varid, 'positive', 'up');
0353 netcdf.putAtt(nc, siglevc_varid, 'valid_min', -1);
0354 netcdf.putAtt(nc, siglevc_varid, 'valid_max', 0);
0355 netcdf.putAtt(nc, siglevc_varid, 'formula_terms', 'sigma: siglev_center eta: zeta_center depth: h_center');
0356
0357 h_varid = netcdf.defVar(nc, 'h', 'NC_FLOAT', ...
0358 node_dimid);
0359 netcdf.putAtt(nc, h_varid, 'long_name', 'Bathymetry');
0360 netcdf.putAtt(nc, h_varid, 'standard_name', 'sea_floor_depth_below_geoid');
0361 netcdf.putAtt(nc, h_varid, 'units', 'm');
0362 netcdf.putAtt(nc, h_varid, 'positive', 'down');
0363 netcdf.putAtt(nc, h_varid, 'grid', 'Bathymetry_mesh');
0364 netcdf.putAtt(nc, h_varid, 'coordinates', 'x y');
0365 netcdf.putAtt(nc, h_varid, 'type', 'data');
0366
0367 hc_varid = netcdf.defVar(nc, 'h_center', 'NC_FLOAT', ...
0368 elem_dimid);
0369 netcdf.putAtt(nc, hc_varid, 'long_name', 'Bathymetry');
0370 netcdf.putAtt(nc, hc_varid, 'standard_name', 'sea_floor_depth_below_geoid');
0371 netcdf.putAtt(nc, hc_varid, 'units', 'm');
0372 netcdf.putAtt(nc, hc_varid, 'positive', 'down');
0373 netcdf.putAtt(nc, hc_varid, 'grid', 'grid1 grid3');
0374 netcdf.putAtt(nc, hc_varid, 'coordinates', 'latc lonc');
0375 netcdf.putAtt(nc, hc_varid, 'grid_location', 'center');
0376
0377 if nesttype > 2
0378 cweights_varid = netcdf.defVar(nc, 'weight_cell', 'NC_FLOAT', ...
0379 [elem_dimid, time_dimid]);
0380 netcdf.putAtt(nc, cweights_varid, 'long_name', ...
0381 'Weights for elements in relaxation zone');
0382 netcdf.putAtt(nc, cweights_varid, 'units', 'no units');
0383 netcdf.putAtt(nc, cweights_varid, 'grid', 'fvcom_grid');
0384 netcdf.putAtt(nc, cweights_varid, 'type', 'data');
0385
0386 nweights_varid = netcdf.defVar(nc, 'weight_node', 'NC_FLOAT', ...
0387 [node_dimid, time_dimid]);
0388 netcdf.putAtt(nc, nweights_varid, 'long_name', ...
0389 'Weights for nodes in relaxation zone');
0390 netcdf.putAtt(nc, nweights_varid, 'units', 'no units');
0391 netcdf.putAtt(nc, nweights_varid, 'grid', 'fvcom_grid');
0392 netcdf.putAtt(nc, nweights_varid, 'type', 'data');
0393 end
0394
0395
0396 netcdf.defVarDeflate(nc, zeta_varid, true, true, 7);
0397 netcdf.defVarDeflate(nc, u_varid, true, true, 7);
0398 netcdf.defVarDeflate(nc, v_varid, true, true, 7);
0399 netcdf.defVarDeflate(nc, temp_varid, true, true, 7);
0400 netcdf.defVarDeflate(nc, salinity_varid, true, true, 7);
0401 netcdf.defVarDeflate(nc, hyw_varid, true, true, 7);
0402
0403
0404 netcdf.endDef(nc);
0405
0406
0407 nStringOut = char();
0408 [nYr, nMon, nDay, nHour, nMin, nSec] = mjulian2greg(nest.time);
0409 for i = 1:ntimes
0410 if strcmp(sprintf('%02i', nSec), '60')
0411
0412
0413
0414
0415 if mod(nMin(i) + 1, 60) == 0
0416
0417 nHour(i) = mod(nHour(i) + 1, 24);
0418 end
0419 nMin(i) = mod(nMin(i) + 1, 60);
0420 nSec(i) = 0;
0421 end
0422 nDate = [nYr(i), nMon(i), nDay(i), nHour(i), nMin(i), nSec(i)];
0423 nStringOut = [nStringOut, sprintf('%-026s', datestr(datenum(nDate), 'yyyy-mm-dd HH:MM:SS.FFF'))];
0424 end
0425 if ftbverbose
0426 fprintf('write time data\n')
0427 end
0428 netcdf.putVar(nc, itime_varid, 0, numel(nest.time), floor(nest.time));
0429 netcdf.putVar(nc, itime2_varid, 0, numel(nest.time), ...
0430 mod(nest.time, 1)*24*3600*1000);
0431 netcdf.putVar(nc, Times_varid, nStringOut);
0432 netcdf.putVar(nc, time_varid, nest.time);
0433
0434
0435 if ftbverbose
0436 fprintf('write grid data\n')
0437 end
0438 netcdf.putVar(nc, nv_varid, nest.nv);
0439 netcdf.putVar(nc, x_varid, nest.x);
0440 netcdf.putVar(nc, y_varid, nest.y);
0441 netcdf.putVar(nc, xc_varid, nest.xc);
0442 netcdf.putVar(nc, yc_varid, nest.yc);
0443 netcdf.putVar(nc, lon_varid, nest.lon);
0444 netcdf.putVar(nc, lat_varid, nest.lat);
0445 netcdf.putVar(nc, lonc_varid, nest.lonc);
0446 netcdf.putVar(nc, latc_varid, nest.latc);
0447
0448
0449 if ftbverbose
0450 fprintf('write time varying data\n')
0451 end
0452 netcdf.putVar(nc, zeta_varid, nest.zeta);
0453 netcdf.putVar(nc, ua_varid, nest.ua);
0454 netcdf.putVar(nc, va_varid, nest.va);
0455 netcdf.putVar(nc, u_varid, nest.u);
0456 netcdf.putVar(nc, v_varid, nest.v);
0457 netcdf.putVar(nc, temp_varid, nest.temp);
0458 netcdf.putVar(nc, salinity_varid, nest.salinity);
0459 netcdf.putVar(nc, hyw_varid, nest.hyw);
0460 netcdf.putVar(nc, siglay_varid, nest.siglay);
0461 netcdf.putVar(nc, siglayc_varid, nest.siglayc);
0462 netcdf.putVar(nc, siglev_varid, nest.siglev);
0463 netcdf.putVar(nc, siglevc_varid, nest.siglevc);
0464 netcdf.putVar(nc, h_varid, nest.h);
0465 netcdf.putVar(nc, hc_varid, nest.hc);
0466 if nesttype > 2
0467 netcdf.putVar(nc, cweights_varid, nest.weight_cell);
0468 netcdf.putVar(nc, nweights_varid, nest.weight_node);
0469 end
0470
0471
0472 netcdf.close(nc)
0473
0474 if ftbverbose
0475 fprintf('end : %s\n', subname)
0476 end