25 module drifters_input_mod
30 public :: drifters_input_type, drifters_input_new, drifters_input_del, drifters_input_save,
assignment(=)
33 integer,
parameter,
private :: MAX_STR_LEN = 128
35 #include<file_version.h>
36 character,
parameter,
private :: SEPARATOR =
' '
44 type drifters_input_type
47 character(len=MAX_STR_LEN),
allocatable :: position_names(:)
48 character(len=MAX_STR_LEN),
allocatable :: position_units(:)
49 character(len=MAX_STR_LEN),
allocatable :: field_names(:)
50 character(len=MAX_STR_LEN),
allocatable :: field_units(:)
51 character(len=MAX_STR_LEN),
allocatable :: velocity_names(:)
52 real ,
allocatable :: positions(:,:)
53 integer ,
allocatable :: ids(:)
54 character(len=MAX_STR_LEN) :: time_units
55 character(len=MAX_STR_LEN) :: title
56 character(len=MAX_STR_LEN) :: version
57 end type drifters_input_type
61 interface assignment(=)
62 module procedure drifters_input_copy_new
72 subroutine drifters_input_new(self, filename, ermesg)
75 use netcdf_nf_interfaces
76 type(drifters_input_type) :: self
77 character(len=*),
intent(in) :: filename
78 character(len=*),
intent(out):: ermesg
81 integer :: ier, ncid, nd, nf, np, ipos, j, id, i, isz
82 character(len=MAX_STR_LEN) :: attribute
86 ier = nf_open(filename, nf_nowrite, ncid)
87 if(ier/=nf_noerr)
then
88 ermesg =
'drifters_input: ERROR could not open netcdf file '//filename
93 ier = nf_put_att_text(ncid, nf_global,
'version', len(version), version)
95 ier = nf_inq_dimid(ncid,
'nd', id)
96 if(ier/=nf_noerr)
then
97 ermesg =
'drifters_input: ERROR could not find "nd" (number of dimensions)'
101 ier = nf_inq_dimlen(ncid, id, nd)
105 ier = nf_get_att_text(ncid, nf_global,
'field_names', attribute)
106 isz = min(len(attribute), len(trim(attribute))+1)
107 attribute(isz:isz) =
' '
111 if(attribute(i:i)==separator)
then
116 ier = nf_inq_dimid(ncid,
'np', id)
117 if(ier/=nf_noerr)
then
118 ermesg =
'drifters_input: ERROR could not find "np" (number of particles)'
122 ier = nf_inq_dimlen(ncid, id, np)
124 allocate(self%position_names(nd))
125 allocate(self%position_units(nd))
126 allocate(self%field_names(nf))
127 allocate(self%field_units(nf))
128 allocate(self%velocity_names(nd))
129 allocate(self%ids(np))
130 allocate(self%positions(nd, np))
132 ier = nf_inq_varid(ncid,
'ids', id)
133 if(ier/=nf_noerr)
then
134 ermesg =
'drifters_input: ERROR could not find "ids"'
138 ier = nf_get_var_int(ncid, id, self%ids)
140 ier = nf_inq_varid(ncid,
'positions', id)
141 if(ier/=nf_noerr)
then
142 ermesg =
'drifters_input: ERROR could not find "positions"'
146 ier = nf90_get_var(ncid, id, self%positions)
149 ier = nf_get_att_text(ncid, nf_global,
'version', attribute)
150 self%version = trim(attribute)
153 ier = nf_get_att_text(ncid, nf_global,
'time_units', attribute)
154 self%time_units = trim(attribute)
157 ier = nf_get_att_text(ncid, nf_global,
'title', attribute)
158 self%title = trim(attribute)
161 ier = nf_get_att_text(ncid, id,
'names', attribute)
162 isz = min(len(attribute), len(trim(attribute))+1)
163 attribute(isz:isz) =
' '
167 if(attribute(i:i)==separator)
then
168 self%position_names(j) = trim(adjustl(attribute(ipos:i-1)))
176 ier = nf_get_att_text(ncid, id,
'units', attribute)
177 isz = min(len(attribute), len(trim(attribute))+1)
178 attribute(isz:isz) =
' '
182 if(attribute(i:i)==separator)
then
183 self%position_units(j) = trim(adjustl(attribute(ipos:i-1)))
191 ier = nf_get_att_text(ncid, nf_global,
'field_names', attribute)
192 isz = min(len(attribute), len(trim(attribute))+1)
193 attribute(isz:isz) =
' '
197 if(attribute(i:i)==separator)
then
198 self%field_names(j) = trim(adjustl(attribute(ipos:i-1)))
206 ier = nf_get_att_text(ncid, nf_global,
'field_units', attribute)
207 isz = min(len(attribute), len(trim(attribute))+1)
208 attribute(isz:isz) =
' '
212 if(attribute(i:i)==separator)
then
213 self%field_units(j) = trim(adjustl(attribute(ipos:i-1)))
221 ier = nf_get_att_text(ncid, nf_global,
'velocity_names', attribute)
222 isz = min(len(attribute), len(trim(attribute))+1)
223 attribute(isz:isz) =
' '
227 if(attribute(i:i)==separator)
then
228 self%velocity_names(j) = trim(adjustl(attribute(ipos:i-1)))
235 end subroutine drifters_input_new
238 subroutine drifters_input_del(self, ermesg)
239 type(drifters_input_type) :: self
240 character(len=*),
intent(out):: ermesg
246 deallocate(self%position_names, stat=iflag)
247 deallocate(self%position_units, stat=iflag)
248 deallocate(self%field_names, stat=iflag)
249 deallocate(self%field_units, stat=iflag)
250 deallocate(self%velocity_names, stat=iflag)
251 deallocate(self%ids, stat=iflag)
252 deallocate(self%positions, stat=iflag)
254 end subroutine drifters_input_del
257 subroutine drifters_input_copy_new(new_instance, old_instance)
259 type(drifters_input_type),
intent(inout) :: new_instance
260 type(drifters_input_type),
intent(in) :: old_instance
262 allocate(new_instance%position_names(
size(old_instance%position_names) ))
263 allocate(new_instance%position_units(
size(old_instance%position_units) ))
264 allocate(new_instance%field_names(
size(old_instance%field_names) ))
265 allocate(new_instance%field_units(
size(old_instance%field_units) ))
266 allocate(new_instance%velocity_names(
size(old_instance%velocity_names) ))
267 new_instance%position_names = old_instance%position_names
268 new_instance%position_units = old_instance%position_units
269 new_instance%field_names = old_instance%field_names
270 new_instance%field_units = old_instance%field_units
271 new_instance%velocity_names = old_instance%velocity_names
272 new_instance%time_units = old_instance%time_units
273 new_instance%title = old_instance%title
274 new_instance%version = old_instance%version
275 allocate(new_instance%positions(
size(old_instance%positions,1),
size(old_instance%positions,2) ))
276 new_instance%positions = old_instance%positions
277 allocate(new_instance%ids(
size(old_instance%ids)))
278 new_instance%ids = old_instance%ids
280 end subroutine drifters_input_copy_new
284 subroutine drifters_input_save(self, filename, geolon, geolat, ermesg)
288 use netcdf_nf_interfaces
289 type(drifters_input_type) :: self
290 character(len=*),
intent(in ):: filename
291 real,
intent(in),
optional :: geolon(:), geolat(:)
292 character(len=*),
intent(out):: ermesg
295 integer ncid, nc_nd, nc_np, ier, nd, np, nf, nc_pos, nc_ids, i, j, n
296 integer nc_lon, nc_lat
297 character(len=MAX_STR_LEN) :: att
302 ier = nf_create(filename, nf_clobber, ncid)
303 if(ier/=nf_noerr)
then
304 ermesg =
'drifters_input: ERROR cannot create '//filename
308 nd =
size(self%positions, 1)
309 np =
size(self%positions, 2)
310 nf =
size(self%field_names)
313 ier = nf_def_dim(ncid,
'nd', nd, nc_nd)
314 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating dim "nd" '//nf_strerror(ier)
316 ier = nf_def_dim(ncid,
'np', np, nc_np)
317 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating dim "np" '//nf_strerror(ier)
320 ier = nf_put_att_text(ncid, nf_global,
'title', len_trim(self%title), self%title)
321 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "title" ' &
324 ier = nf_put_att_text(ncid, nf_global,
'time_units', len_trim(self%time_units), self%time_units)
325 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "time_units" ' &
331 n = len_trim(self%field_units(i))
332 att(j:j+n+1) = trim(self%field_units(i)) //
' '
335 ier = nf_put_att_text(ncid, nf_global,
'field_units', len_trim(att), &
337 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "field_units" ' &
343 n = len_trim(self%field_names(i))
344 att(j:j+n+1) = trim(self%field_names(i)) //
' '
347 ier = nf_put_att_text(ncid, nf_global,
'field_names', len_trim(att), &
349 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "field_names" ' &
355 n = len_trim(self%velocity_names(i))
356 att(j:j+n+1) = trim(self%velocity_names(i)) //
' '
359 ier = nf_put_att_text(ncid, nf_global,
'velocity_names', len_trim(att), &
361 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "velocity_names" ' &
365 ier = nf_def_var(ncid,
'positions', nf_double, 2, (/nc_nd, nc_np/), nc_pos)
366 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "positions" '//nf_strerror(ier)
368 ier = nf_def_var(ncid,
'ids', nf_int, 1, (/nc_np/), nc_ids)
369 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "ids" '//nf_strerror(ier)
372 if(
present(geolon))
then
373 ier = nf_def_var(ncid,
'longitude', nf_double, 1, (/nc_np/), nc_lon)
374 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "longitude" ' &
377 ier = nf_put_att_text(ncid, nc_lon,
'units', len(trim(att)), trim(att))
378 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "units" to "longitude" ' &
381 if(
present(geolat))
then
382 ier = nf_def_var(ncid,
'latitude', nf_double, 1, (/nc_np/), nc_lat)
383 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "latitude" ' &
385 att =
'degrees_north'
386 ier = nf_put_att_text(ncid, nc_lat,
'units', len(trim(att)), trim(att))
387 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "units" to "latitude" ' &
396 n = len_trim(self%position_units(i))
397 att(j:j+n+1) = trim(self%position_units(i)) //
' '
400 ier = nf_put_att_text(ncid, nc_pos,
'units', len_trim(att), &
402 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "units" to "positions" ' &
408 n = len_trim(self%position_names(i))
409 att(j:j+n+1) = trim(self%position_names(i)) //
' '
412 ier = nf_put_att_text(ncid, nc_pos,
'names', len_trim(att), &
414 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "names" to "positions" ' &
418 ier = nf_enddef(ncid)
419 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not end define mode ' &
423 ier = nf90_put_var(ncid, nc_pos, self%positions)
424 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "positions" ' &
427 ier = nf90_put_var(ncid, nc_ids, self%ids)
428 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "ids" ' &
431 if(
present(geolon))
then
432 ier = nf90_put_var(ncid, nc_lon, geolon)
433 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "geolon" ' &
436 if(
present(geolat))
then
437 ier = nf90_put_var(ncid, nc_lat, geolat)
438 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "geolat" ' &
444 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not close file ' &
447 end subroutine drifters_input_save
449 end module drifters_input_mod