0001 function write_FVCOM_forcing(Mobj, fileprefix, data, infos, fver)
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 multi_out = false;
0056 if nargin < 4 || nargin > 5
0057 error('Incorrect number of arguments')
0058 elseif nargin == 5
0059 if strcmpi(fver, '3.1.0')
0060 multi_out = true;
0061 end
0062 end
0063
0064 subname = 'write_FVCOM_forcing';
0065
0066 global ftbverbose;
0067 if(ftbverbose)
0068 fprintf('\n')
0069 fprintf(['begin : ' subname '\n'])
0070 end
0071
0072 tri = Mobj.tri;
0073 nNodes = Mobj.nVerts;
0074 nElems = Mobj.nElems;
0075 ntimes = numel(data.time);
0076
0077 if strcmpi(Mobj.nativeCoords,'cartesian')
0078 x = Mobj.x;
0079 y = Mobj.y;
0080 else
0081 x = Mobj.lon;
0082 y = Mobj.lat;
0083 end
0084
0085
0086 xc = nodes2elems(x, Mobj);
0087 yc = nodes2elems(y, Mobj);
0088
0089
0090
0091
0092
0093 if multi_out
0094 suffixes = {'_wnd', '_hfx', '_evap', '_air_press'};
0095 else
0096 suffixes = {'_wnd'};
0097 end
0098
0099 for i=1:length(suffixes)
0100 nc = netcdf.create([fileprefix, suffixes{i}, '.nc'], 'clobber');
0101
0102
0103 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'title','FVCOM Forcing File')
0104 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'institution','Plymouth Marine Laboratory')
0105 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'source','FVCOM grid (unstructured) surface forcing')
0106 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'history',['File created on ', datestr(now, 'yyyy-mm-dd HH:MM:SS'), ' with write_FVCOM_forcing.m from the fvcom-toolbox (https://github.com/pwcazenave/fvcom-toolbox)'])
0107 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'references','http://fvcom.smast.umassd.edu, http://codfish.smast.umassd.edu')
0108 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'Conventions','CF-1.0')
0109
0110 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'CoordinateSystem',Mobj.nativeCoords)
0111 netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'CoordinateProjection','init=epsg:4326')
0112
0113
0114 nele_dimid=netcdf.defDim(nc,'nele',nElems);
0115 node_dimid=netcdf.defDim(nc,'node',nNodes);
0116 three_dimid=netcdf.defDim(nc,'three',3);
0117 time_dimid=netcdf.defDim(nc,'time',netcdf.getConstant('NC_UNLIMITED'));
0118 datestrlen_dimid=netcdf.defDim(nc,'DateStrLen',26);
0119
0120
0121 x_varid=netcdf.defVar(nc,'x','NC_FLOAT',node_dimid);
0122 netcdf.putAtt(nc,x_varid,'long_name','nodal x-coordinate');
0123 netcdf.putAtt(nc,x_varid,'units','meters');
0124
0125 y_varid=netcdf.defVar(nc,'y','NC_FLOAT',node_dimid);
0126 netcdf.putAtt(nc,y_varid,'long_name','nodal y-coordinate');
0127 netcdf.putAtt(nc,y_varid,'units','meters');
0128
0129 xc_varid=netcdf.defVar(nc,'xc','NC_FLOAT',nele_dimid);
0130 netcdf.putAtt(nc,xc_varid,'long_name','zonal x-coordinate');
0131 netcdf.putAtt(nc,xc_varid,'units','meters');
0132
0133 yc_varid=netcdf.defVar(nc,'yc','NC_FLOAT',nele_dimid);
0134 netcdf.putAtt(nc,yc_varid,'long_name','zonal y-coordinate');
0135 netcdf.putAtt(nc,yc_varid,'units','meters');
0136
0137 nv_varid=netcdf.defVar(nc,'nv','NC_INT',[nele_dimid, three_dimid]);
0138 netcdf.putAtt(nc,nv_varid,'long_name','nodes surrounding element');
0139
0140
0141 time_varid=netcdf.defVar(nc,'time','NC_FLOAT',time_dimid);
0142 netcdf.putAtt(nc,time_varid,'long_name','time');
0143 netcdf.putAtt(nc,time_varid,'units','days since 1858-11-17 00:00:00');
0144 netcdf.putAtt(nc,time_varid,'format','modified julian day (MJD)');
0145 netcdf.putAtt(nc,time_varid,'time_zone','UTC');
0146
0147 itime_varid=netcdf.defVar(nc,'Itime','NC_INT',time_dimid);
0148 netcdf.putAtt(nc,itime_varid,'units','days since 1858-11-17 00:00:00');
0149 netcdf.putAtt(nc,itime_varid,'format','modified julian day (MJD)');
0150 netcdf.putAtt(nc,itime_varid,'time_zone','UTC');
0151
0152 itime2_varid=netcdf.defVar(nc,'Itime2','NC_INT',time_dimid);
0153 netcdf.putAtt(nc,itime2_varid,'units','msec since 00:00:00');
0154 netcdf.putAtt(nc,itime2_varid,'time_zone','UTC');
0155
0156
0157
0158 fnames = fieldnames(data);
0159 used_varids = cell(0);
0160 used_fnames = cell(0);
0161 used_dims = cell(0);
0162
0163 for vv=1:length(fnames)
0164
0165
0166
0167 switch fnames{vv}
0168 case {'uwnd', 'u10'}
0169 if strcmpi(suffixes{i}, '_wnd') || ~multi_out
0170
0171
0172
0173 u10_varid=netcdf.defVar(nc,'U10','NC_FLOAT',[nele_dimid, time_dimid]);
0174 netcdf.putAtt(nc,u10_varid,'long_name','Eastward Wind Speed');
0175
0176 netcdf.putAtt(nc,u10_varid,'units','m/s');
0177 netcdf.putAtt(nc,u10_varid,'grid','fvcom_grid');
0178 netcdf.putAtt(nc,u10_varid,'coordinates','');
0179 netcdf.putAtt(nc,u10_varid,'type','data');
0180
0181 v10_varid=netcdf.defVar(nc,'V10','NC_FLOAT',[nele_dimid, time_dimid]);
0182 netcdf.putAtt(nc,v10_varid,'long_name','Northward Wind Speed');
0183
0184 netcdf.putAtt(nc,v10_varid,'units','m/s');
0185 netcdf.putAtt(nc,v10_varid,'grid','fvcom_grid');
0186 netcdf.putAtt(nc,v10_varid,'coordinates','');
0187 netcdf.putAtt(nc,v10_varid,'type','data');
0188
0189 uwind_varid=netcdf.defVar(nc,'uwind_speed','NC_FLOAT',[nele_dimid, time_dimid]);
0190 netcdf.putAtt(nc,uwind_varid,'long_name','Eastward Wind Speed');
0191 netcdf.putAtt(nc,uwind_varid,'standard_name','Wind Speed');
0192 netcdf.putAtt(nc,uwind_varid,'units','m/s');
0193 netcdf.putAtt(nc,uwind_varid,'grid','fvcom_grid');
0194 netcdf.putAtt(nc,uwind_varid,'type','data');
0195
0196 vwind_varid=netcdf.defVar(nc,'vwind_speed','NC_FLOAT',[nele_dimid, time_dimid]);
0197 netcdf.putAtt(nc,vwind_varid,'long_name','Northward Wind Speed');
0198 netcdf.putAtt(nc,vwind_varid,'standard_name','Wind Speed');
0199 netcdf.putAtt(nc,vwind_varid,'units','m/s');
0200 netcdf.putAtt(nc,vwind_varid,'grid','fvcom_grid');
0201 netcdf.putAtt(nc,vwind_varid,'type','data');
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 used_varids = [used_varids, {'u10_varid', 'v10_varid', 'uwind_varid', 'vwind_varid'}];
0235 used_fnames = [used_fnames, {'uwnd', 'vwnd', 'uwnd', 'vwnd'}];
0236 used_dims = [used_dims, {'nElems', 'nElems', 'nElems', 'nElems'}];
0237 end
0238
0239 case 'slp'
0240 if strcmpi(suffixes{i}, '_air_press') || ~multi_out
0241
0242 slp_varid=netcdf.defVar(nc,'air_pressure','NC_FLOAT',[node_dimid, time_dimid]);
0243 netcdf.putAtt(nc,slp_varid,'long_name','Surface air pressure');
0244 netcdf.putAtt(nc,slp_varid,'units','Pa');
0245 netcdf.putAtt(nc,slp_varid,'grid','fvcom_grid');
0246 netcdf.putAtt(nc,slp_varid,'coordinates','');
0247 netcdf.putAtt(nc,slp_varid,'type','data');
0248
0249 used_varids = [used_varids, 'slp_varid'];
0250 used_fnames = [used_fnames, fnames{vv}];
0251 used_dims = [used_dims, 'nNodes'];
0252 end
0253
0254 case 'P_E'
0255 if strcmpi(suffixes{i}, '_evap') || ~multi_out
0256
0257 pe_varid=netcdf.defVar(nc,'evap','NC_FLOAT',[node_dimid, time_dimid]);
0258 netcdf.putAtt(nc,pe_varid,'long_name','Evaporation');
0259 netcdf.putAtt(nc,pe_varid,'description','Evaporation, ocean lose water is negative');
0260 netcdf.putAtt(nc,pe_varid,'units','m s-1');
0261 netcdf.putAtt(nc,pe_varid,'grid','fvcom_grid');
0262 netcdf.putAtt(nc,pe_varid,'coordinates','');
0263 netcdf.putAtt(nc,pe_varid,'type','data');
0264
0265 used_varids = [used_varids, 'pe_varid'];
0266 used_fnames = [used_fnames, fnames{vv}];
0267 used_dims = [used_dims, 'nNodes'];
0268 end
0269
0270 case 'prate'
0271 if strcmpi(suffixes{i}, '_evap') || ~multi_out
0272
0273 prate_varid=netcdf.defVar(nc,'precip','NC_FLOAT',[node_dimid, time_dimid]);
0274 netcdf.putAtt(nc,prate_varid,'long_name','Precipitation');
0275 netcdf.putAtt(nc,prate_varid,'description','Precipitation, ocean lose water is negative');
0276 netcdf.putAtt(nc,prate_varid,'units','m s-1');
0277 netcdf.putAtt(nc,prate_varid,'grid','fvcom_grid');
0278 netcdf.putAtt(nc,prate_varid,'coordinates','');
0279 netcdf.putAtt(nc,prate_varid,'type','data');
0280
0281 used_varids = [used_varids, 'prate_varid'];
0282 used_fnames = [used_fnames, fnames{vv}];
0283 used_dims = [used_dims, 'nNodes'];
0284 end
0285
0286 case 'nswrs'
0287 if strcmpi(suffixes{i}, '_hfx') || ~multi_out
0288
0289 nswrs_varid=netcdf.defVar(nc,'short_wave','NC_FLOAT',[node_dimid, time_dimid]);
0290 netcdf.putAtt(nc,nswrs_varid,'long_name','Short Wave Radiation');
0291 netcdf.putAtt(nc,nswrs_varid,'units','W m-2');
0292 netcdf.putAtt(nc,nswrs_varid,'grid','fvcom_grid');
0293 netcdf.putAtt(nc,nswrs_varid,'coordinates','');
0294 netcdf.putAtt(nc,nswrs_varid,'type','data');
0295
0296 used_varids = [used_varids, 'nswrs_varid'];
0297 used_fnames = [used_fnames, fnames{vv}];
0298 used_dims = [used_dims, 'nNodes'];
0299 end
0300
0301 case {'shtfl', 'lhtfl', 'nlwrs'}
0302 try
0303
0304
0305
0306
0307 if strcmpi(suffixes{i}, '_hfx') || ~multi_out
0308
0309 nhf_varid=netcdf.defVar(nc,'net_heat_flux','NC_FLOAT',[node_dimid, time_dimid]);
0310 netcdf.putAtt(nc,nhf_varid,'long_name','Surface Net Heat Flux');
0311 netcdf.putAtt(nc,nhf_varid,'units','W m-2');
0312 netcdf.putAtt(nc,nhf_varid,'grid','fvcom_grid');
0313 netcdf.putAtt(nc,nhf_varid,'coordinates','');
0314 netcdf.putAtt(nc,nhf_varid,'type','data');
0315 end
0316 end
0317 if strcmpi(suffixes{i}, '_hfx') || ~multi_out
0318
0319
0320 used_varids = [used_varids, 'nhf_varid'];
0321 used_fnames = [used_fnames, fnames{vv}];
0322 used_dims = [used_dims, 'nNodes'];
0323 end
0324
0325 case {'time', 'lon', 'lat', 'x', 'y'}
0326 continue
0327
0328 otherwise
0329 if(ftbverbose)
0330 warning('Unknown or unused input data type: %s', fnames{vv})
0331 end
0332 end
0333 end
0334
0335
0336 netcdf.endDef(nc);
0337
0338
0339 netcdf.putVar(nc,nv_varid, tri');
0340 netcdf.putVar(nc,time_varid,0,ntimes,data.time);
0341 netcdf.putVar(nc,itime_varid,0,ntimes,floor(data.time));
0342 netcdf.putVar(nc,itime2_varid,0,ntimes,mod(data.time,1)*24*3600*1000);
0343 netcdf.putVar(nc,x_varid,x);
0344 netcdf.putVar(nc,y_varid,y);
0345 netcdf.putVar(nc,xc_varid,xc);
0346 netcdf.putVar(nc,yc_varid,yc);
0347
0348
0349
0350 hf_done = 0;
0351 for ff=1:length(used_fnames)
0352 if strcmpi(used_fnames{ff}, 'shtfl') || strcmpi(used_fnames{ff}, 'lhtfl') || strcmpi(used_fnames{ff}, 'nlwrs')
0353 hf_done = hf_done + 1;
0354 if hf_done == 3
0355
0356 hf = data.shtfl.node + data.lhtfl.node + data.nlwrs.node;
0357 netcdf.putVar(nc,nhf_varid,[0,0],[nNodes,ntimes],hf)
0358 end
0359 else
0360
0361
0362 if strcmpi(used_dims{ff}, 'nNodes')
0363 eval(['netcdf.putVar(nc,',used_varids{ff},',[0,0],[',used_dims{ff},',ntimes],data.',used_fnames{ff},'.node);'])
0364 else
0365 eval(['netcdf.putVar(nc,',used_varids{ff},',[0,0],[',used_dims{ff},',ntimes],data.',used_fnames{ff},'.data);'])
0366 end
0367 end
0368 end
0369 if hf_done ~= 3
0370 warning('Did not have all the required heat flux parameters. Need ''shtfl'', ''lhtfl'', ''nlwrs''')
0371 end
0372
0373
0374 netcdf.close(nc);
0375 end