Routine creates a new NetCDF file. It also sets up structures that describe this file and variables that will later be written to this file. Type for describing a variable, typically a tracer.
93 integer,
intent(out) :: unit
95 character(len=*),
intent(in) :: filename
96 type(vardesc),
intent(in) :: vars(:)
97 integer,
intent(in) :: novars
98 type(fieldtype),
intent(inout) :: fields(:)
99 integer,
optional,
intent(in) :: threading
100 real,
optional,
intent(in) :: timeunit
102 type(ocean_grid_type),
optional,
intent(in) :: G
105 type(dyn_horgrid_type),
optional,
intent(in) :: dG
108 type(verticalGrid_type),
optional,
intent(in) :: GV
111 integer(kind=8),
optional,
intent(in) :: checksums(:,:)
113 logical :: use_lath, use_lonh, use_latq, use_lonq, use_time
114 logical :: use_layer, use_int, use_periodic
115 logical :: one_file, domain_set
116 type(axistype) :: axis_lath, axis_latq, axis_lonh, axis_lonq
117 type(axistype) :: axis_layer, axis_int, axis_time, axis_periodic
118 type(axistype) :: axes(4)
119 type(MOM_domain_type),
pointer :: Domain => null()
120 type(domain1d) :: x_domain, y_domain
121 integer :: numaxes, pack, thread, k
122 integer :: isg, ieg, jsg, jeg, IsgB, IegB, JsgB, JegB
123 integer :: var_periods, num_periods=0
124 real,
dimension(:),
allocatable :: period_val
125 real,
pointer,
dimension(:) :: &
126 gridLatT => null(), &
127 gridlatb => null(), &
128 gridlont => null(), gridlonb => null()
129 character(len=40) :: time_units, x_axis_units, y_axis_units
130 character(len=8) :: t_grid, t_grid_read
132 use_lath = .false. ; use_lonh = .false.
133 use_latq = .false. ; use_lonq = .false.
134 use_time = .false. ; use_periodic = .false.
135 use_layer = .false. ; use_int = .false.
138 if (
PRESENT(threading)) thread = threading
142 domain_set = .true. ; domain => g%Domain
143 gridlatt => g%gridLatT ; gridlatb => g%gridLatB
144 gridlont => g%gridLonT ; gridlonb => g%gridLonB
145 x_axis_units = g%x_axis_units ; y_axis_units = g%y_axis_units
146 isg = g%isg ; ieg = g%ieg ; jsg = g%jsg ; jeg = g%jeg
147 isgb = g%IsgB ; iegb = g%IegB ; jsgb = g%JsgB ; jegb = g%JegB
148 elseif (
present(dg))
then
149 domain_set = .true. ; domain => dg%Domain
150 gridlatt => dg%gridLatT ; gridlatb => dg%gridLatB
151 gridlont => dg%gridLonT ; gridlonb => dg%gridLonB
152 x_axis_units = dg%x_axis_units ; y_axis_units = dg%y_axis_units
153 isg = dg%isg ; ieg = dg%ieg ; jsg = dg%jsg ; jeg = dg%jeg
154 isgb = dg%IsgB ; iegb = dg%IegB ; jsgb = dg%JsgB ; jegb = dg%JegB
158 if (domain_set) one_file = (thread == single_file)
161 call open_file(unit, filename, mpp_overwr, mpp_netcdf, threading=thread)
163 call open_file(unit, filename, mpp_overwr, mpp_netcdf, domain=domain%mpp_domain)
168 select case (vars(k)%hor_grid)
169 case (
'h') ; use_lath = .true. ; use_lonh = .true.
170 case (
'q') ; use_latq = .true. ; use_lonq = .true.
171 case (
'u') ; use_lath = .true. ; use_lonq = .true.
172 case (
'v') ; use_latq = .true. ; use_lonh = .true.
173 case (
'T') ; use_lath = .true. ; use_lonh = .true.
174 case (
'Bu') ; use_latq = .true. ; use_lonq = .true.
175 case (
'Cu') ; use_lath = .true. ; use_lonq = .true.
176 case (
'Cv') ; use_latq = .true. ; use_lonh = .true.
179 call mom_error(warning,
"MOM_io create_file: "//trim(vars(k)%name)//&
180 " has unrecognized hor_grid "//trim(vars(k)%hor_grid))
182 select case (vars(k)%z_grid)
183 case (
'L') ; use_layer = .true.
184 case (
'i') ; use_int = .true.
187 call mom_error(fatal,
"MOM_io create_file: "//trim(vars(k)%name)//&
188 " has unrecognized z_grid "//trim(vars(k)%z_grid))
190 t_grid = adjustl(vars(k)%t_grid)
191 select case (t_grid(1:1))
192 case (
's',
'a',
'm') ; use_time = .true.
193 case (
'p') ; use_periodic = .true.
194 if (len_trim(t_grid(2:8)) <= 0)
call mom_error(fatal, &
195 "MOM_io create_file: No periodic axis length was specified in "//&
196 trim(vars(k)%t_grid) //
" in the periodic axes of variable "//&
197 trim(vars(k)%name)//
" in file "//trim(filename))
198 var_periods = -9999999
199 t_grid_read = adjustl(t_grid(2:8))
200 read(t_grid_read,*) var_periods
201 if (var_periods == -9999999)
call mom_error(fatal, &
202 "MOM_io create_file: Failed to read the number of periods from "//&
203 trim(vars(k)%t_grid) //
" in the periodic axes of variable "//&
204 trim(vars(k)%name)//
" in file "//trim(filename))
205 if (var_periods < 1)
call mom_error(fatal,
"MOM_io create_file: "//&
206 "variable "//trim(vars(k)%name)//
" in file "//trim(filename)//&
207 " uses a periodic time axis, and must have a positive "//&
208 "value for the number of periods in "//vars(k)%t_grid )
209 if ((num_periods > 0) .and. (var_periods /= num_periods)) &
210 call mom_error(fatal,
"MOM_io create_file: "//&
211 "Only one value of the number of periods can be used in the "//&
212 "create_file call for file "//trim(filename)//
". The second is "//&
213 "variable "//trim(vars(k)%name)//
" with t_grid "//vars(k)%t_grid )
215 num_periods = var_periods
218 call mom_error(warning,
"MOM_io create_file: "//trim(vars(k)%name)//&
219 " has unrecognized t_grid "//trim(vars(k)%t_grid))
223 if ((use_lath .or. use_lonh .or. use_latq .or. use_lonq))
then
224 if (.not.domain_set)
call mom_error(fatal,
"create_file: "//&
225 "An ocean_grid_type or dyn_horgrid_type is required to create a file with a horizontal coordinate.")
227 call mpp_get_domain_components(domain%mpp_domain, x_domain, y_domain)
229 if ((use_layer .or. use_int) .and. .not.
present(gv))
call mom_error(fatal, &
230 "create_file: A vertical grid type is required to create a file with a vertical coordinate.")
236 call mpp_write_meta(unit, axis_lath, name=
"lath", units=y_axis_units, longname=
"Latitude", &
237 cartesian=
'Y', domain = y_domain, data=gridlatt(jsg:jeg))
240 call mpp_write_meta(unit, axis_lonh, name=
"lonh", units=x_axis_units, longname=
"Longitude", &
241 cartesian=
'X', domain = x_domain, data=gridlont(isg:ieg))
244 call mpp_write_meta(unit, axis_latq, name=
"latq", units=y_axis_units, longname=
"Latitude", &
245 cartesian=
'Y', domain = y_domain, data=gridlatb(jsgb:jegb))
248 call mpp_write_meta(unit, axis_lonq, name=
"lonq", units=x_axis_units, longname=
"Longitude", &
249 cartesian=
'X', domain = x_domain, data=gridlonb(isgb:iegb))
252 call mpp_write_meta(unit, axis_layer, name=
"Layer", units=trim(gv%zAxisUnits), &
253 longname=
"Layer "//trim(gv%zAxisLongName), cartesian=
'Z', &
254 sense=1, data=gv%sLayer(1:gv%ke))
257 call mpp_write_meta(unit, axis_int, name=
"Interface", units=trim(gv%zAxisUnits), &
258 longname=
"Interface "//trim(gv%zAxisLongName), cartesian=
'Z', &
259 sense=1, data=gv%sInterface(1:gv%ke+1))
261 if (use_time)
then ;
if (
present(timeunit))
then
263 if (timeunit < 0.0)
then
265 elseif ((timeunit >= 0.99) .and. (timeunit < 1.01))
then
266 time_units =
"seconds"
267 elseif ((timeunit >= 3599.0) .and. (timeunit < 3601.0))
then
269 elseif ((timeunit >= 86399.0) .and. (timeunit < 86401.0))
then
271 elseif ((timeunit >= 3.0e7) .and. (timeunit < 3.2e7))
then
274 write(time_units,
'(es8.2," s")') timeunit
277 call mpp_write_meta(unit, axis_time, name=
"Time", units=time_units, longname=
"Time", cartesian=
'T')
279 call mpp_write_meta(unit, axis_time, name=
"Time", units=
"days", longname=
"Time",cartesian=
'T')
282 if (use_periodic)
then
283 if (num_periods <= 1)
call mom_error(fatal,
"MOM_io create_file: "//&
284 "num_periods for file "//trim(filename)//
" must be at least 1.")
286 allocate(period_val(num_periods))
287 do k=1,num_periods ; period_val(k) = real(k) ;
enddo
288 call mpp_write_meta(unit, axis_periodic, name=
"Period", units=
"nondimensional", &
289 longname=
"Periods for cyclical varaiables", cartesian=
't', data=period_val)
290 deallocate(period_val)
295 select case (vars(k)%hor_grid)
296 case (
'h') ; numaxes = 2 ; axes(1) = axis_lonh ; axes(2) = axis_lath
297 case (
'q') ; numaxes = 2 ; axes(1) = axis_lonq ; axes(2) = axis_latq
298 case (
'u') ; numaxes = 2 ; axes(1) = axis_lonq ; axes(2) = axis_lath
299 case (
'v') ; numaxes = 2 ; axes(1) = axis_lonh ; axes(2) = axis_latq
300 case (
'T') ; numaxes = 2 ; axes(1) = axis_lonh ; axes(2) = axis_lath
301 case (
'Bu') ; numaxes = 2 ; axes(1) = axis_lonq ; axes(2) = axis_latq
302 case (
'Cu') ; numaxes = 2 ; axes(1) = axis_lonq ; axes(2) = axis_lath
303 case (
'Cv') ; numaxes = 2 ; axes(1) = axis_lonh ; axes(2) = axis_latq
306 call mom_error(warning,
"MOM_io create_file: "//trim(vars(k)%name)//&
307 " has unrecognized hor_grid "//trim(vars(k)%hor_grid))
309 select case (vars(k)%z_grid)
310 case (
'L') ; numaxes = numaxes+1 ; axes(numaxes) = axis_layer
311 case (
'i') ; numaxes = numaxes+1 ; axes(numaxes) = axis_int
314 call mom_error(fatal,
"MOM_io create_file: "//trim(vars(k)%name)//&
315 " has unrecognized z_grid "//trim(vars(k)%z_grid))
317 t_grid = adjustl(vars(k)%t_grid)
318 select case (t_grid(1:1))
319 case (
's',
'a',
'm') ; numaxes = numaxes+1 ; axes(numaxes) = axis_time
320 case (
'p') ; numaxes = numaxes+1 ; axes(numaxes) = axis_periodic
323 call mom_error(warning,
"MOM_io create_file: "//trim(vars(k)%name)//&
324 " has unrecognized t_grid "//trim(vars(k)%t_grid))
328 if (
present(checksums))
then
329 call mpp_write_meta(unit, fields(k), axes(1:numaxes), vars(k)%name, vars(k)%units, &
330 vars(k)%longname, pack = pack, checksum=checksums(k,:))
332 call mpp_write_meta(unit, fields(k), axes(1:numaxes), vars(k)%name, vars(k)%units, &
333 vars(k)%longname, pack = pack)
337 if (use_lath)
call write_field(unit, axis_lath)
338 if (use_latq)
call write_field(unit, axis_latq)
339 if (use_lonh)
call write_field(unit, axis_lonh)
340 if (use_lonq)
call write_field(unit, axis_lonq)
341 if (use_layer)
call write_field(unit, axis_layer)
342 if (use_int)
call write_field(unit, axis_int)
343 if (use_periodic)
call write_field(unit, axis_periodic)