25 module drifters_io_mod
30 use netcdf_nf_interfaces
31 use netcdf4_nf_interfaces
36 public :: drifters_io_type, drifters_io_new, drifters_io_del, drifters_io_set_time_units
37 public :: drifters_io_set_position_names, drifters_io_set_position_units, drifters_io_set_field_names
38 public :: drifters_io_set_field_units, drifters_io_write
41 integer,
parameter,
private :: MAX_STR_LEN = 128
43 #include<file_version.h>
45 real :: drfts_eps_t = 10.*epsilon(1.)
55 integer :: nc_positions, nc_fields, nc_ids, nc_time, nc_index_time
57 end type drifters_io_type
63 subroutine drifters_io_new(self, filename, nd, nf, ermesg)
64 type(drifters_io_type) :: self
65 character(len=*),
intent(in) :: filename
66 integer,
intent(in) :: nd
67 integer,
intent(in) :: nf
68 character(len=*),
intent(out) :: ermesg
70 integer ier, nc_it_id, nc_nd, nc_nf
71 integer :: size1(1), size2(2)
76 ier = nf_create(filename, nf_clobber, self%ncid)
77 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_create ('//filename//
') '//nf_strerror(ier)
80 ier = nf_put_att_text(self%ncid, nf_global,
'version', len_trim(version), trim(version))
84 ier = nf_def_dim(self%ncid,
'np', nf_unlimited, nc_it_id)
85 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_dim (it_id) '//nf_strerror(ier)
87 ier = nf_def_dim(self%ncid,
'nf', nf, nc_nf)
88 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_dim (nf) '//nf_strerror(ier)
90 ier = nf_def_dim(self%ncid,
'nd', nd, nc_nd)
91 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_dim (nd) '//nf_strerror(ier)
95 ier = nf_def_var(self%ncid,
'index_time', nf_int, 1, size1, self%nc_index_time)
96 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (index_time)'//nf_strerror(ier)
98 ier = nf_def_var(self%ncid,
'time', nf_double, 1, size1, self%nc_time)
99 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (time)'//nf_strerror(ier)
101 ier = nf_def_var(self%ncid,
'ids', nf_int, 1, size1, self%nc_ids)
102 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (ids)'//nf_strerror(ier)
104 size2 = (/nc_nd, nc_it_id/)
105 ier = nf_def_var(self%ncid,
'positions', nf_double, 2, size2, self%nc_positions)
106 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (positions)'//nf_strerror(ier)
108 size2 = (/nc_nf, nc_it_id/)
109 ier = nf_def_var(self%ncid,
'fields', nf_double, 2, size2, self%nc_fields)
110 if(ier/=nf_noerr) ermesg =
'drifters_io_new::nf_def_var (fields)'//nf_strerror(ier)
112 self%time = -huge(1.)
116 end subroutine drifters_io_new
119 subroutine drifters_io_del(self, ermesg)
120 type(drifters_io_type) :: self
121 character(len=*),
intent(out) :: ermesg
127 ier = nf_close(self%ncid)
128 if(ier/=nf_noerr) ermesg =
'drifters_io_del::nf_close '//nf_strerror(ier)
130 end subroutine drifters_io_del
133 subroutine drifters_io_set_time_units(self, name, ermesg)
134 type(drifters_io_type) :: self
135 character(len=*),
intent(in) :: name
136 character(len=*),
intent(out) :: ermesg
141 ier = nf_put_att_text(self%ncid, nf_global, &
142 &
'time_units', len_trim(name), trim(name))
144 & ermesg =
'drifters_io_set_time_units::failed to add time_units attribute ' &
147 end subroutine drifters_io_set_time_units
150 subroutine drifters_io_set_position_names(self, names, ermesg)
151 type(drifters_io_type) :: self
152 character(len=*),
intent(in) :: names(:)
153 character(len=*),
intent(out) :: ermesg
156 character(len=128) :: attname
162 write(attname,
'(i6)' ) i
163 attname =
'name_'//adjustl(attname)
164 ier = nf_put_att_text(self%ncid, self%nc_positions, &
165 & trim(attname), len_trim(names(i)), trim(names(i)))
167 & ermesg =
'drifters_io_set_position_names::failed to add name attribute to positions '//nf_strerror(ier)
170 end subroutine drifters_io_set_position_names
173 subroutine drifters_io_set_position_units(self, names, ermesg)
174 type(drifters_io_type) :: self
175 character(len=*),
intent(in) :: names(:)
176 character(len=*),
intent(out) :: ermesg
179 character(len=128) :: attname
185 write(attname,
'(i6)' ) i
186 attname =
'unit_'//adjustl(attname)
187 ier = nf_put_att_text(self%ncid, self%nc_positions, &
188 & trim(attname), len_trim(names(i)), trim(names(i)))
190 & ermesg =
'drifters_io_set_position_names::failed to add unit attribute to positions '//nf_strerror(ier)
193 end subroutine drifters_io_set_position_units
196 subroutine drifters_io_set_field_names(self, names, ermesg)
197 type(drifters_io_type) :: self
198 character(len=*),
intent(in) :: names(:)
199 character(len=*),
intent(out) :: ermesg
202 character(len=128) :: attname
208 write(attname,
'(i6)' ) i
209 attname =
'name_'//adjustl(attname)
210 ier = nf_put_att_text(self%ncid, self%nc_fields, &
211 & trim(attname), len_trim(names(i)), trim(names(i)))
213 & ermesg =
'drifters_io_set_field_names::failed to add name attribute to fields '//nf_strerror(ier)
216 end subroutine drifters_io_set_field_names
219 subroutine drifters_io_set_field_units(self, names, ermesg)
220 type(drifters_io_type) :: self
221 character(len=*),
intent(in) :: names(:)
222 character(len=*),
intent(out) :: ermesg
225 character(len=128) :: attname
231 write(attname,
'(i6)' ) i
232 attname =
'unit_'//adjustl(attname)
233 ier = nf_put_att_text(self%ncid, self%nc_fields, &
234 & trim(attname), len_trim(names(i)), trim(names(i)))
236 & ermesg =
'drifters_io_set_field_units::failed to add unit attribute to fields '//nf_strerror(ier)
239 end subroutine drifters_io_set_field_units
242 subroutine drifters_io_write(self, time, np, nd, nf, ids, positions, fields, ermesg)
243 type(drifters_io_type) :: self
244 real,
intent(in) :: time
245 integer,
intent(in) :: np
246 integer,
intent(in) :: nd
247 integer,
intent(in) :: nf
248 integer,
intent(in) :: ids(np)
249 real,
intent(in) :: positions(nd,np)
250 real,
intent(in) :: fields(nf,np)
251 character(len=*),
intent(out) :: ermesg
254 integer :: start1(1), len1(1), start2(2), len2(2)
255 integer :: it_indices(np)
256 real :: time_array(np)
260 if(.not. self%enddef)
then
261 ier = nf_enddef(self%ncid)
262 if(ier/=nf_noerr)
then
263 ermesg =
'drifters_io_write::nf_enddef failure. No data will be written. '//nf_strerror(ier)
269 if(abs(time - self%time) > drfts_eps_t)
then
270 self%it = self%it + 1
274 start1(1) = self%it_id
277 it_indices = (/(self%it,i=1,np)/)
278 ier = nf_put_vara_int( self%ncid, self%nc_index_time, start1, len1, it_indices )
280 & ermesg =
'drifters_io_write::failed to write index_time: ' //nf_strerror(ier)
282 time_array = (/(time,i=1,np)/)
283 ier = nf90_put_var( self%ncid, self%nc_time, time_array, start1, len1 )
285 & ermesg =
'drifters_io_write::failed to write time: ' //nf_strerror(ier)
287 ier = nf_put_vara_int(self%ncid, self%nc_ids, start1, len1, ids)
289 & ermesg =
'drifters_io_write::failed to write ids: '//nf_strerror(ier)
292 start2(2) = self%it_id
297 ier = nf90_put_var(self%ncid, self%nc_positions, positions, start2, len2)
299 & ermesg =
'drifters_io_write::failed to write positions: '//nf_strerror(ier)
304 ier = nf90_put_var(self%ncid, self%nc_fields, fields, start2, len2)
306 & ermesg =
'drifters_io_write::failed to write fields: '//nf_strerror(ier)
308 self%it_id = self%it_id + np
310 end subroutine drifters_io_write
312 end module drifters_io_mod