24 module drifters_io_mod
29 use netcdf_nf_interfaces
30 use netcdf4_nf_interfaces
35 public :: drifters_io_type, drifters_io_new, drifters_io_del, drifters_io_set_time_units
36 public :: drifters_io_set_position_names, drifters_io_set_position_units, drifters_io_set_field_names
37 public :: drifters_io_set_field_units, drifters_io_write
40 integer,
parameter,
private :: MAX_STR_LEN = 128
42 #include<file_version.h>
44 real :: drfts_eps_t = 10.*epsilon(1.)
54 integer :: nc_positions, nc_fields, nc_ids, nc_time, nc_index_time
56 end type drifters_io_type
62 subroutine drifters_io_new(self, filename, nd, nf, ermesg)
63 type(drifters_io_type) :: self
64 character(len=*),
intent(in) :: filename
65 integer,
intent(in) :: nd
66 integer,
intent(in) :: nf
67 character(len=*),
intent(out) :: ermesg
69 integer ier, nc_it_id, nc_nd, nc_nf
70 integer :: size1(1), size2(2)
75 ier = nf_create(filename, nf_clobber, self%ncid)
76 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_create ('//filename//
') '//nf_strerror(ier)
79 ier = nf_put_att_text(self%ncid, nf_global,
'version', len_trim(version), trim(version))
83 ier = nf_def_dim(self%ncid,
'np', nf_unlimited, nc_it_id)
84 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_dim (it_id) '//nf_strerror(ier)
86 ier = nf_def_dim(self%ncid,
'nf', nf, nc_nf)
87 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_dim (nf) '//nf_strerror(ier)
89 ier = nf_def_dim(self%ncid,
'nd', nd, nc_nd)
90 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_dim (nd) '//nf_strerror(ier)
94 ier = nf_def_var(self%ncid,
'index_time', nf_int, 1, size1, self%nc_index_time)
95 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (index_time)'//nf_strerror(ier)
97 ier = nf_def_var(self%ncid,
'time', nf_double, 1, size1, self%nc_time)
98 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (time)'//nf_strerror(ier)
100 ier = nf_def_var(self%ncid,
'ids', nf_int, 1, size1, self%nc_ids)
101 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (ids)'//nf_strerror(ier)
103 size2 = (/nc_nd, nc_it_id/)
104 ier = nf_def_var(self%ncid,
'positions', nf_double, 2, size2, self%nc_positions)
105 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (positions)'//nf_strerror(ier)
107 size2 = (/nc_nf, nc_it_id/)
108 ier = nf_def_var(self%ncid,
'fields', nf_double, 2, size2, self%nc_fields)
109 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (fields)'//nf_strerror(ier)
111 self%time = -huge(1.)
115 end subroutine drifters_io_new
118 subroutine drifters_io_del(self, ermesg)
119 type(drifters_io_type) :: self
120 character(len=*),
intent(out) :: ermesg
126 ier = nf_close(self%ncid)
127 if(ier/=nf_noerr) ermesg =
'drifters_io_del::nf_close '//nf_strerror(ier)
129 end subroutine drifters_io_del
132 subroutine drifters_io_set_time_units(self, name, ermesg)
133 type(drifters_io_type) :: self
134 character(len=*),
intent(in) :: name
135 character(len=*),
intent(out) :: ermesg
140 ier = nf_put_att_text(self%ncid, nf_global, &
141 &
'time_units', len_trim(name), trim(name))
143 & ermesg =
'drifters_io_set_time_units::failed to add time_units attribute ' &
146 end subroutine drifters_io_set_time_units
149 subroutine drifters_io_set_position_names(self, names, ermesg)
150 type(drifters_io_type) :: self
151 character(len=*),
intent(in) :: names(:)
152 character(len=*),
intent(out) :: ermesg
155 character(len=128) :: attname
161 write(attname,
'(i6)' ) i
162 attname =
'name_'//adjustl(attname)
163 ier = nf_put_att_text(self%ncid, self%nc_positions, &
164 & trim(attname), len_trim(names(i)), trim(names(i)))
166 & ermesg =
'drifters_io_set_position_names::failed to add name attribute to positions '//nf_strerror(ier)
169 end subroutine drifters_io_set_position_names
172 subroutine drifters_io_set_position_units(self, names, ermesg)
173 type(drifters_io_type) :: self
174 character(len=*),
intent(in) :: names(:)
175 character(len=*),
intent(out) :: ermesg
178 character(len=128) :: attname
184 write(attname,
'(i6)' ) i
185 attname =
'unit_'//adjustl(attname)
186 ier = nf_put_att_text(self%ncid, self%nc_positions, &
187 & trim(attname), len_trim(names(i)), trim(names(i)))
189 & ermesg =
'drifters_io_set_position_names::failed to add unit attribute to positions '//nf_strerror(ier)
192 end subroutine drifters_io_set_position_units
195 subroutine drifters_io_set_field_names(self, names, ermesg)
196 type(drifters_io_type) :: self
197 character(len=*),
intent(in) :: names(:)
198 character(len=*),
intent(out) :: ermesg
201 character(len=128) :: attname
207 write(attname,
'(i6)' ) i
208 attname =
'name_'//adjustl(attname)
209 ier = nf_put_att_text(self%ncid, self%nc_fields, &
210 & trim(attname), len_trim(names(i)), trim(names(i)))
212 & ermesg =
'drifters_io_set_field_names::failed to add name attribute to fields '//nf_strerror(ier)
215 end subroutine drifters_io_set_field_names
218 subroutine drifters_io_set_field_units(self, names, ermesg)
219 type(drifters_io_type) :: self
220 character(len=*),
intent(in) :: names(:)
221 character(len=*),
intent(out) :: ermesg
224 character(len=128) :: attname
230 write(attname,
'(i6)' ) i
231 attname =
'unit_'//adjustl(attname)
232 ier = nf_put_att_text(self%ncid, self%nc_fields, &
233 & trim(attname), len_trim(names(i)), trim(names(i)))
235 & ermesg =
'drifters_io_set_field_units::failed to add unit attribute to fields '//nf_strerror(ier)
238 end subroutine drifters_io_set_field_units
241 subroutine drifters_io_write(self, time, np, nd, nf, ids, positions, fields, ermesg)
242 type(drifters_io_type) :: self
243 real,
intent(in) :: time
244 integer,
intent(in) :: np
245 integer,
intent(in) :: nd
246 integer,
intent(in) :: nf
247 integer,
intent(in) :: ids(np)
248 real,
intent(in) :: positions(nd,np)
249 real,
intent(in) :: fields(nf,np)
250 character(len=*),
intent(out) :: ermesg
253 integer :: start1(1), len1(1), start2(2), len2(2)
254 integer :: it_indices(np)
255 real :: time_array(np)
259 if(.not. self%enddef)
then
260 ier = nf_enddef(self%ncid)
261 if(ier/=nf_noerr)
then
262 ermesg =
'drifters_io_write::nf_enddef failure. No data will be written. '//nf_strerror(ier)
268 if(abs(time - self%time) > drfts_eps_t)
then
269 self%it = self%it + 1
273 start1(1) = self%it_id
276 it_indices = (/(self%it,i=1,np)/)
277 ier = nf_put_vara_int( self%ncid, self%nc_index_time, start1, len1, it_indices )
279 & ermesg =
'drifters_io_write::failed to write index_time: ' //nf_strerror(ier)
281 time_array = (/(time,i=1,np)/)
282 ier = nf90_put_var( self%ncid, self%nc_time, time_array, start1, len1 )
284 & ermesg =
'drifters_io_write::failed to write time: ' //nf_strerror(ier)
286 ier = nf_put_vara_int(self%ncid, self%nc_ids, start1, len1, ids)
288 & ermesg =
'drifters_io_write::failed to write ids: '//nf_strerror(ier)
291 start2(2) = self%it_id
296 ier = nf90_put_var(self%ncid, self%nc_positions, positions, start2, len2)
298 & ermesg =
'drifters_io_write::failed to write positions: '//nf_strerror(ier)
303 ier = nf90_put_var(self%ncid, self%nc_fields, fields, start2, len2)
305 & ermesg =
'drifters_io_write::failed to write fields: '//nf_strerror(ier)
307 self%it_id = self%it_id + np
309 end subroutine drifters_io_write
311 end module drifters_io_mod