1 |
!*********************************************************************** |
2 |
! $Header: /usr/data/cvsroot/fletcher/MOM_3/MOM_3/ocmip2/write_nc_phys.F,v 1.1.1.1 2003/05/01 21:25:53 fletcher Exp $ |
3 |
!*********************************************************************** |
4 |
! NAME: WRITE_NC_phys |
5 |
! |
6 |
! INPUT: |
7 |
! group = group code (ex: IPSL) |
8 |
! production = production (model and version ex: OPA 8.1) |
9 |
! |
10 |
! secs_per_month = number of seconds in each model month |
11 |
! |
12 |
! imt_trx = tracer Zonal grid dimension |
13 |
! jmt_trx = tracer Meridional grid dimension |
14 |
! kmt_trx = tracer Depth grid dimension |
15 |
! |
16 |
! PT = monthly potential temperature [C] |
17 |
! SAL = monthly salinity [psu] |
18 |
! TFLX = monthly net surface heat flux [W/m^2] |
19 |
! H2OFLX = monthly net surface freshwater flux [m/y] |
20 |
! |
21 |
! kmt_UV = Horizontal Velocity Depth grid dimension |
22 |
! |
23 |
! imt_Eul_U = Eulerian Zonal Velocity Zonal grid dimension |
24 |
! jmt_Eul_U = Eulerian Zonal Velocity Meridional grid dimension |
25 |
! Eul_U = monthly Eulerian Zonal Velocity [m/s] |
26 |
! WS_x = monthly Zonal Wind Stress [N/m^2] |
27 |
! |
28 |
! imt_Eul_V = Eulerian Meridional Velocity Zonal grid dimension |
29 |
! jmt_Eul_V = Eulerian Meridional Velocity Meridional grid dimension |
30 |
! Eul_V = monthly Eulerian Meridional Velocity [m/s] |
31 |
! WS_y = monthly Meridional Wind Stress [N/m^2] |
32 |
! |
33 |
! has_eddy = logical flag, true if model has eddy induced velocities |
34 |
! |
35 |
! imt_Eddy_U = Eddy Induced Zonal Velocity Zonal grid dimension |
36 |
! jmt_Eddy_U = Eddy Induced Zonal Velocity Meridional grid dimension |
37 |
! Eddy_U = monthly Eddy Induced Zonal Velocity [m/s] |
38 |
! |
39 |
! imt_Eddy_V = Eddy Induced Meridional Velocity Zonal grid dimension |
40 |
! jmt_Eddy_V = Eddy Induced Meridional Velocity Meridional grid dimension |
41 |
! Eddy_V = monthly Eddy Induced Meridional Velocity [m/s] |
42 |
! |
43 |
! OUTPUT FILE: |
44 |
! A netcdf file (clobbed if exists) with |
45 |
! the filename group_phys.nc |
46 |
! |
47 |
!*********************************************************************** |
48 |
|
49 |
SUBROUTINE WRITE_NC_phys( |
50 |
& group, production, |
51 |
& secs_per_month, |
52 |
& imt_trx, jmt_trx, kmt_trx, |
53 |
& PT, SAL, TFLX, H2OFLX, |
54 |
& kmt_UV, |
55 |
& imt_Eul_U, jmt_Eul_U, Eul_U, WS_x, |
56 |
& imt_Eul_V, jmt_Eul_V, Eul_V, WS_y, |
57 |
& has_eddy, |
58 |
& imt_Eddy_U, jmt_Eddy_U, Eddy_U, |
59 |
& imt_Eddy_V, jmt_Eddy_V, Eddy_V) |
60 |
|
61 |
IMPLICIT NONE |
62 |
#include "netcdf.inc" |
63 |
|
64 |
! Arguments |
65 |
CHARACTER*(*) group |
66 |
CHARACTER*(*) production |
67 |
REAL secs_per_month(12) |
68 |
INTEGER imt_trx, jmt_trx, kmt_trx |
69 |
|
70 |
REAL PT(imt_trx, jmt_trx, kmt_trx, 12) |
71 |
REAL SAL(imt_trx, jmt_trx, kmt_trx, 12) |
72 |
REAL TFLX(imt_trx, jmt_trx, 12) |
73 |
REAL H2OFLX(imt_trx, jmt_trx, 12) |
74 |
|
75 |
INTEGER kmt_UV |
76 |
|
77 |
INTEGER imt_Eul_U, jmt_Eul_U |
78 |
REAL Eul_U(imt_Eul_U, jmt_Eul_U, kmt_UV, 12) |
79 |
REAL WS_x(imt_Eul_U, jmt_Eul_U, 12) |
80 |
|
81 |
INTEGER imt_Eul_V, jmt_Eul_V |
82 |
REAL Eul_V(imt_Eul_V, jmt_Eul_V, kmt_UV, 12) |
83 |
REAL WS_y(imt_Eul_V, jmt_Eul_V, 12) |
84 |
|
85 |
LOGICAL has_eddy |
86 |
|
87 |
INTEGER imt_Eddy_U, jmt_Eddy_U |
88 |
REAL Eddy_U(imt_Eddy_U, jmt_Eddy_U, kmt_UV, 12) |
89 |
|
90 |
INTEGER imt_Eddy_V, jmt_Eddy_V |
91 |
REAL Eddy_V(imt_Eddy_V, jmt_Eddy_V, kmt_UV, 12) |
92 |
|
93 |
! Constants |
94 |
REAL msv |
95 |
PARAMETER (msv = -1.E+34) |
96 |
|
97 |
! Local variables |
98 |
CHARACTER*256 filename, tempname |
99 |
INTEGER NC_ID |
100 |
INTEGER STATUS |
101 |
INTEGER TWO_DIM |
102 |
INTEGER time_DIM |
103 |
INTEGER lon_trx_DIM, lat_trx_DIM, depth_trx_DIM |
104 |
INTEGER depth_UV_DIM |
105 |
INTEGER lon_Eul_U_DIM, lat_Eul_U_DIM |
106 |
INTEGER lon_Eul_V_DIM, lat_Eul_V_DIM |
107 |
INTEGER lon_Eddy_U_DIM, lat_Eddy_U_DIM |
108 |
INTEGER lon_Eddy_V_DIM, lat_Eddy_V_DIM |
109 |
INTEGER DIMIDS(4) |
110 |
INTEGER time_ID, bounds_time_ID |
111 |
INTEGER PT_ID, SAL_ID, TFLX_ID, H2OFLX_ID |
112 |
INTEGER Eul_U_ID, WS_x_ID |
113 |
INTEGER Eul_V_ID, WS_y_ID |
114 |
INTEGER Eddy_U_ID |
115 |
INTEGER Eddy_V_ID |
116 |
|
117 |
INTEGER I |
118 |
REAL TIME(12), bounds_TIME(12,2) |
119 |
|
120 |
!*********************************************************************** |
121 |
! Build the NetCDF filename |
122 |
!*********************************************************************** |
123 |
filename = group//'_phys.nc' |
124 |
|
125 |
!*********************************************************************** |
126 |
! Open the NetCDF file |
127 |
!*********************************************************************** |
128 |
STATUS = NF_CREATE(filename, NF_CLOBBER, NC_ID) |
129 |
IF (STATUS .NE. NF_NOERR) THEN |
130 |
PRINT *, 'NetCDF error opening ', filename |
131 |
PRINT *, NF_STRERROR(STATUS) |
132 |
STOP 'Stopped' |
133 |
ENDIF |
134 |
|
135 |
!*********************************************************************** |
136 |
! Define dimensions |
137 |
!*********************************************************************** |
138 |
CALL DEF_DIM(NC_ID, 'two', 2, TWO_DIM) |
139 |
|
140 |
CALL DEF_DIM(NC_ID, 'time', 12, time_DIM) |
141 |
|
142 |
CALL DEF_DIM(NC_ID, 'x_trx', imt_trx, lon_trx_DIM) |
143 |
CALL DEF_DIM(NC_ID, 'y_trx', jmt_trx, lat_trx_DIM) |
144 |
CALL DEF_DIM(NC_ID, 'z_trx', kmt_trx, depth_trx_DIM) |
145 |
|
146 |
CALL DEF_DIM(NC_ID, 'z_UV', kmt_UV, depth_UV_DIM) |
147 |
|
148 |
CALL DEF_DIM(NC_ID, 'x_Eul_U', imt_Eul_U, lon_Eul_U_DIM) |
149 |
CALL DEF_DIM(NC_ID, 'y_Eul_U', jmt_Eul_U, lat_Eul_U_DIM) |
150 |
|
151 |
CALL DEF_DIM(NC_ID, 'x_Eul_V', imt_Eul_V, lon_Eul_V_DIM) |
152 |
CALL DEF_DIM(NC_ID, 'y_Eul_V', jmt_Eul_V, lat_Eul_V_DIM) |
153 |
|
154 |
IF (has_eddy) THEN |
155 |
CALL DEF_DIM(NC_ID, 'x_Eddy_U', imt_Eddy_U, lon_Eddy_U_DIM) |
156 |
CALL DEF_DIM(NC_ID, 'y_Eddy_U', jmt_Eddy_U, lat_Eddy_U_DIM) |
157 |
|
158 |
CALL DEF_DIM(NC_ID, 'x_Eddy_V', imt_Eddy_V, lon_Eddy_V_DIM) |
159 |
CALL DEF_DIM(NC_ID, 'y_Eddy_V', jmt_Eddy_V, lat_Eddy_V_DIM) |
160 |
ENDIF ! IF (has_eddy) |
161 |
|
162 |
!*********************************************************************** |
163 |
! Define variables & attributes |
164 |
!*********************************************************************** |
165 |
|
166 |
DIMIDS(1) = time_DIM |
167 |
CALL DEF_REAL(NC_ID, 'time', time_ID, 1, DIMIDS) |
168 |
CALL ADD_ATT_TEXT(NC_ID, time_ID, 'long_name', 'Time') |
169 |
CALL ADD_ATT_TEXT(NC_ID, time_ID, 'units', |
170 |
& 'seconds since 0001-01-01 00:00:00') |
171 |
CALL ADD_ATT_TEXT(NC_ID, time_ID, 'bounds', 'bounds_time') |
172 |
|
173 |
DIMIDS(1) = time_DIM |
174 |
DIMIDS(2) = TWO_DIM |
175 |
CALL DEF_REAL(NC_ID, 'bounds_time', bounds_time_ID, 2, DIMIDS) |
176 |
|
177 |
DIMIDS(1) = lon_trx_DIM |
178 |
DIMIDS(2) = lat_trx_DIM |
179 |
DIMIDS(3) = depth_trx_DIM |
180 |
DIMIDS(4) = time_DIM |
181 |
|
182 |
CALL DEF_REAL(NC_ID, 'PT', PT_ID, 4, DIMIDS) |
183 |
CALL ADD_ATT_TEXT(NC_ID, PT_ID, 'long_name', |
184 |
& 'Potential Temperature') |
185 |
CALL ADD_ATT_TEXT(NC_ID, PT_ID, 'units', 'C') |
186 |
CALL ADD_ATT_TEXT(NC_ID, PT_ID, 'coordinates', |
187 |
& 'lon lat depth time') |
188 |
CALL ADD_ATT_REAL(NC_ID, PT_ID, 'missing_value', msv) |
189 |
|
190 |
CALL DEF_REAL(NC_ID, 'SAL', SAL_ID, 4, DIMIDS) |
191 |
CALL ADD_ATT_TEXT(NC_ID, SAL_ID, 'long_name', 'Salinity') |
192 |
CALL ADD_ATT_TEXT(NC_ID, SAL_ID, 'units', 'psu') |
193 |
CALL ADD_ATT_TEXT(NC_ID, SAL_ID, 'coordinates', |
194 |
& 'lon lat depth time') |
195 |
CALL ADD_ATT_REAL(NC_ID, SAL_ID, 'missing_value', msv) |
196 |
|
197 |
DIMIDS(1) = lon_trx_DIM |
198 |
DIMIDS(2) = lat_trx_DIM |
199 |
DIMIDS(3) = time_DIM |
200 |
|
201 |
CALL DEF_REAL(NC_ID, 'TFLX', TFLX_ID, 3, DIMIDS) |
202 |
CALL ADD_ATT_TEXT(NC_ID, TFLX_ID, 'long_name', |
203 |
& 'Net Surface Heat Flux') |
204 |
CALL ADD_ATT_TEXT(NC_ID, TFLX_ID, 'units', 'W/m^2') |
205 |
CALL ADD_ATT_TEXT(NC_ID, TFLX_ID, 'coordinates', |
206 |
& 'lon lat time') |
207 |
CALL ADD_ATT_REAL(NC_ID, TFLX_ID, 'missing_value', msv) |
208 |
|
209 |
CALL DEF_REAL(NC_ID, 'H2OFLX', H2OFLX_ID, 3, DIMIDS) |
210 |
CALL ADD_ATT_TEXT(NC_ID, H2OFLX_ID, 'long_name', |
211 |
& 'Net Surface Freshwater Flux') |
212 |
CALL ADD_ATT_TEXT(NC_ID, H2OFLX_ID, 'units', 'm/y') |
213 |
CALL ADD_ATT_TEXT(NC_ID, H2OFLX_ID, 'coordinates', |
214 |
& 'lon lat time') |
215 |
CALL ADD_ATT_REAL(NC_ID, H2OFLX_ID, 'missing_value', msv) |
216 |
|
217 |
DIMIDS(1) = lon_Eul_U_DIM |
218 |
DIMIDS(2) = lat_Eul_U_DIM |
219 |
DIMIDS(3) = depth_UV_DIM |
220 |
DIMIDS(4) = time_DIM |
221 |
|
222 |
CALL DEF_REAL(NC_ID, 'Eul_U', Eul_U_ID, 4, DIMIDS) |
223 |
CALL ADD_ATT_TEXT(NC_ID, Eul_U_ID, 'long_name', |
224 |
& 'Eulerian Zonal Velocity') |
225 |
CALL ADD_ATT_TEXT(NC_ID, Eul_U_ID, 'units', 'm/s') |
226 |
CALL ADD_ATT_TEXT(NC_ID, Eul_U_ID, 'coordinates', |
227 |
& 'lon_Eul_U lat_Eul_U depth_UV time') |
228 |
CALL ADD_ATT_TEXT(NC_ID, Eul_U_ID, 'vector_angle', |
229 |
& 'vector_angle_Eul_U') |
230 |
CALL ADD_ATT_REAL(NC_ID, Eul_U_ID, 'missing_value', msv) |
231 |
|
232 |
DIMIDS(1) = lon_Eul_U_DIM |
233 |
DIMIDS(2) = lat_Eul_U_DIM |
234 |
DIMIDS(3) = time_DIM |
235 |
|
236 |
CALL DEF_REAL(NC_ID, 'WS_x', WS_x_ID, 3, DIMIDS) |
237 |
CALL ADD_ATT_TEXT(NC_ID, WS_x_ID, 'long_name', |
238 |
& 'Zonal Wind Stress') |
239 |
CALL ADD_ATT_TEXT(NC_ID, WS_x_ID, 'units', 'N/m^2') |
240 |
CALL ADD_ATT_TEXT(NC_ID, WS_x_ID, 'coordinates', |
241 |
& 'lon_Eul_U lat_Eul_U time') |
242 |
CALL ADD_ATT_TEXT(NC_ID, WS_x_ID, 'vector_angle', |
243 |
& 'vector_angle_Eul_U') |
244 |
CALL ADD_ATT_REAL(NC_ID, WS_x_ID, 'missing_value', msv) |
245 |
|
246 |
DIMIDS(1) = lon_Eul_V_DIM |
247 |
DIMIDS(2) = lat_Eul_V_DIM |
248 |
DIMIDS(3) = depth_UV_DIM |
249 |
DIMIDS(4) = time_DIM |
250 |
|
251 |
CALL DEF_REAL(NC_ID, 'Eul_V', Eul_V_ID, 4, DIMIDS) |
252 |
CALL ADD_ATT_TEXT(NC_ID, Eul_V_ID, 'long_name', |
253 |
& 'Eulerian Meridional Velocity') |
254 |
CALL ADD_ATT_TEXT(NC_ID, Eul_V_ID, 'units', 'm/s') |
255 |
CALL ADD_ATT_TEXT(NC_ID, Eul_V_ID, 'coordinates', |
256 |
& 'lon_Eul_V lat_Eul_V depth_UV time') |
257 |
CALL ADD_ATT_TEXT(NC_ID, Eul_V_ID, 'vector_angle', |
258 |
& 'vector_angle_Eul_V') |
259 |
CALL ADD_ATT_REAL(NC_ID, Eul_V_ID, 'missing_value', msv) |
260 |
|
261 |
DIMIDS(1) = lon_Eul_V_DIM |
262 |
DIMIDS(2) = lat_Eul_V_DIM |
263 |
DIMIDS(3) = time_DIM |
264 |
|
265 |
CALL DEF_REAL(NC_ID, 'WS_y', WS_y_ID, 3, DIMIDS) |
266 |
CALL ADD_ATT_TEXT(NC_ID, WS_y_ID, 'long_name', |
267 |
& 'Meridional Wind Stress') |
268 |
CALL ADD_ATT_TEXT(NC_ID, WS_y_ID, 'units', 'N/m^2') |
269 |
CALL ADD_ATT_TEXT(NC_ID, WS_y_ID, 'coordinates', |
270 |
& 'lon_Eul_V lat_Eul_V time') |
271 |
CALL ADD_ATT_TEXT(NC_ID, WS_y_ID, 'vector_angle', |
272 |
& 'vector_angle_Eul_V') |
273 |
CALL ADD_ATT_REAL(NC_ID, WS_y_ID, 'missing_value', msv) |
274 |
|
275 |
IF (has_eddy) THEN |
276 |
|
277 |
DIMIDS(1) = lon_Eddy_U_DIM |
278 |
DIMIDS(2) = lat_Eddy_U_DIM |
279 |
DIMIDS(3) = depth_UV_DIM |
280 |
DIMIDS(4) = time_DIM |
281 |
|
282 |
CALL DEF_REAL(NC_ID, 'Eddy_U', Eddy_U_ID, 4, DIMIDS) |
283 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_U_ID, 'long_name', |
284 |
& 'Eddy Induced Zonal Velocity') |
285 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_U_ID, 'units', 'm/s') |
286 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_U_ID, 'coordinates', |
287 |
& 'lon_Eddy_U lat_Eddy_U depth_UV time') |
288 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_U_ID, 'vector_angle', |
289 |
& 'vector_angle_Eddy_U') |
290 |
CALL ADD_ATT_REAL(NC_ID, Eddy_U_ID, 'missing_value', msv) |
291 |
|
292 |
DIMIDS(1) = lon_Eddy_V_DIM |
293 |
DIMIDS(2) = lat_Eddy_V_DIM |
294 |
DIMIDS(3) = depth_UV_DIM |
295 |
DIMIDS(4) = time_DIM |
296 |
|
297 |
CALL DEF_REAL(NC_ID, 'Eddy_V', Eddy_V_ID, 4, DIMIDS) |
298 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_V_ID, 'long_name', |
299 |
& 'Eddy Induced Meridional Velocity') |
300 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_V_ID, 'units', 'm/s') |
301 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_V_ID, 'coordinates', |
302 |
& 'lon_Eddy_V lat_Eddy_V depth_UV time') |
303 |
CALL ADD_ATT_TEXT(NC_ID, Eddy_V_ID, 'vector_angle', |
304 |
& 'vector_angle_Eddy_V') |
305 |
CALL ADD_ATT_REAL(NC_ID, Eddy_V_ID, 'missing_value', msv) |
306 |
|
307 |
ENDIF ! IF (has_eddy) |
308 |
|
309 |
!*********************************************************************** |
310 |
! Define global attributes |
311 |
!*********************************************************************** |
312 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'output_routine', |
313 |
& '$RCSfile: write_nc_phys.F,v $, $Revision: 1.1.1.1 $') |
314 |
|
315 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'file_name', filename) |
316 |
|
317 |
tempname = group//'_grid.nc' |
318 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL,'trx_associate_file',tempname) |
319 |
|
320 |
tempname = group//'_vel_grid.nc' |
321 |
CALL ADD_ATT_TEXT(NC_ID,NF_GLOBAL,'vel_associate_file',tempname) |
322 |
|
323 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'project', 'OCMIP') |
324 |
|
325 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'institution', group) |
326 |
|
327 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'production', production) |
328 |
|
329 |
IF (has_eddy) THEN |
330 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'has_eddy', 'TRUE') |
331 |
ELSE |
332 |
CALL ADD_ATT_TEXT(NC_ID, NF_GLOBAL, 'has_eddy', 'FALSE') |
333 |
ENDIF |
334 |
|
335 |
!*********************************************************************** |
336 |
! End of define mode |
337 |
!*********************************************************************** |
338 |
STATUS = NF_ENDDEF(NC_ID) |
339 |
IF (STATUS .NE. NF_NOERR) THEN |
340 |
PRINT *, 'NetCDF error ending define mode' |
341 |
PRINT *, NF_STRERROR(STATUS) |
342 |
STOP 'Stopped' |
343 |
ENDIF |
344 |
|
345 |
!*********************************************************************** |
346 |
! Write data to file |
347 |
!*********************************************************************** |
348 |
DO I = 1, 12 |
349 |
IF (I .EQ. 1) THEN |
350 |
bounds_TIME(I,1) = 0.0 |
351 |
ELSE |
352 |
bounds_TIME(I,1) = bounds_TIME(I-1,2) |
353 |
ENDIF |
354 |
TIME(I) = bounds_TIME(I,1) + 0.5 * secs_per_month(i) |
355 |
bounds_TIME(I,2) = bounds_TIME(I,1) + secs_per_month(i) |
356 |
ENDDO |
357 |
|
358 |
CALL PUT_REAL(NC_ID, time_ID, TIME, 'time') |
359 |
CALL PUT_REAL(NC_ID, bounds_time_ID, bounds_TIME, 'bounds_TIME') |
360 |
|
361 |
CALL PUT_REAL(NC_ID, PT_ID, PT, 'PT') |
362 |
CALL PUT_REAL(NC_ID, SAL_ID, SAL, 'SAL') |
363 |
|
364 |
CALL PUT_REAL(NC_ID, TFLX_ID, TFLX, 'TFLX') |
365 |
CALL PUT_REAL(NC_ID, H2OFLX_ID, H2OFLX, 'H2OFLX') |
366 |
|
367 |
CALL PUT_REAL(NC_ID, Eul_U_ID, Eul_U, 'Eul_U') |
368 |
CALL PUT_REAL(NC_ID, WS_x_ID, WS_x, 'WS_x') |
369 |
|
370 |
CALL PUT_REAL(NC_ID, Eul_V_ID, Eul_V, 'Eul_V') |
371 |
CALL PUT_REAL(NC_ID, WS_y_ID, WS_y, 'WS_y') |
372 |
|
373 |
IF (has_eddy) THEN |
374 |
CALL PUT_REAL(NC_ID, Eddy_U_ID, Eddy_U, 'Eddy_U') |
375 |
CALL PUT_REAL(NC_ID, Eddy_V_ID, Eddy_V, 'Eddy_V') |
376 |
ENDIF ! IF (has_eddy) |
377 |
|
378 |
!*********************************************************************** |
379 |
! Close the NetCDF file |
380 |
!*********************************************************************** |
381 |
|
382 |
STATUS = NF_CLOSE(NC_ID) |
383 |
IF (STATUS .NE. NF_NOERR) THEN |
384 |
PRINT *, 'NetCDF error closing ', filename |
385 |
PRINT *, NF_STRERROR(STATUS) |
386 |
STOP 'Stopped' |
387 |
ENDIF |
388 |
|
389 |
END |