6 integer::netcdf_msglevel
= 0
10 ! from https://github.com/openwfm/wrf-fire/blob/master/standalone/wrf_netcdf.F
11 subroutine ncopen(filename
,mode
,ncid
)
12 !*** purpose: open netcdf file wrapper with an informative error message
15 character(len
=*), intent(in
):: filename
16 integer, intent(in
)::mode
17 integer, intent(out
):: ncid
19 call check(nf90_open(trim(filename
),mode
,ncid
),"Cannot open file "//trim(filename
))
20 print *,"Opened netcdf file ",trim(filename
)," as ",ncid
," mode ",mode
23 subroutine ncclose(ncid
)
24 !*** purpose: open netcdf file wrapper with informative error message
27 integer, intent(in
):: ncid
28 print *,"Closing netcdf file ",ncid
29 call check(nf90_close(ncid
),"Cannot close netcdf file ")
30 end subroutine ncclose
32 real function netcdf_read_att(ncid
,name
)
33 ! read real global scalar attribute
35 integer, intent(in
)::ncid
36 character(len
=*), intent(in
)::name
39 integer::xtype
,len
,attnum
40 character(len
=256)::msg
42 call check(nf90_inquire_attribute(ncid
, nf90_global
, trim(name
), xtype
, len
, attnum
),"nf90_inquire_attribute")
43 if(xtype
.ne
.nf90_float
.or
.len
.ne
.1)then
44 write(msg
,*)"netcdf_read_att can read only float scalar but ",trim(name
)," has xtype=",xtype
," len=",len
47 call check(nf90_get_att(ncid
,nf90_global
, trim(name
), value
),"nf90_get_att")
48 write(msg
,*)"netcdf_read_att returning ",trim(name
),"=",value
50 netcdf_read_att
= value
51 end function netcdf_read_att
53 integer function netcdf_read_int_wrf(ncid
,name
,istep
)
57 integer, intent(in
)::ncid
! open netcdf file
58 character(LEN
=*),intent(in
)::name
! variable name
59 integer, intent(in
)::istep
! index in unlimited dimension (timestep number)
61 integer::ia(1) ! variable to store
64 print *,"netcdf_read_int_wrf reading variable ",trim(name
)," time step ",istep
65 call check(nf90_inq_varid(ncid
, trim(name
), varid
), &
66 "netcdf_read_int_wrf/nf90_inq_varid:"//trim(name
))
67 call check(nf90_get_var(ncid
, varid
, ia
, start
= (/istep
/), count
= (/1/)), &
68 "netcdf_read_int_wrf/nf90_get_var:"//trim(name
))
69 print *,"netcdf_read_int_wrf:", trim(name
), " = ",ia
70 netcdf_read_int_wrf
= ia(1)
71 end function netcdf_read_int_wrf
73 subroutine netcdf_write_int(ncid
,ia
,varname
)
76 integer, intent(in
):: &
77 ncid
, & ! open netcdf file
78 ia
! variable to write
79 character(LEN
=*),intent(in
):: varname
82 character(len
=256)::msg
84 write(msg
,*)'netcdf_write_int: varname=',varname
,' value=',ia
86 call check(nf90_inq_varid(ncid
, trim(varname
), varid
), &
87 "netcdf_write_int/nf90_inq_varid:"//trim(varname
))
89 call check(nf90_put_var(ncid
, varid
, ival
), &
90 "netcdf_write_int/nf90_put_var:"//trim(varname
))
91 end subroutine netcdf_write_int
93 subroutine netcdf_write_array(ncid
,a
,name
)
97 integer, intent(in
)::ncid
! open netcdf file
98 real,intent(in
),dimension(:,:,:)::a
99 character(LEN
=*),intent(in
):: name
102 integer,dimension(4)::star
,cnts
103 integer::i
,j
,k
,varid
,ends(4),dims(4),n(3)
104 real,dimension(:,:,:,:),allocatable
::at
105 character(len
=256) msg
109 call netcdf_var_info(ncid
,name
,dims
,varid
,netcdf_msglevel
)
111 ends
= (/dims(1),dims(2),dims(3),1/)
112 ends
= min(ends
,dims
)
113 cnts
= ends
- star
+ 1
116 allocate(at(star(1):ends(1),star(2):ends(2),star(3):ends(3),1))
125 if(netcdf_msglevel
>=0) &
126 write(msg
,*)"writing ",trim(name
),n(1),star(1),ends(1),n(2),star(2),ends(2),n(3),star(3),ends(3)
130 call check(nf90_put_var(ncid
, varid
, at
, start
= star
, count
= cnts
),"nf90_put_var:"//trim(name
))
134 end subroutine netcdf_write_array
137 subroutine netcdf_write_2d(ncid
,a
,name
,iframe
)
140 ! write a 2d array to netcdf file
143 integer, intent(in
)::ncid
! open netcdf file
144 real,intent(in
),dimension(:,:)::a
145 character(LEN
=*),intent(in
):: name
146 integer, intent(in
)::iframe
! time frame to write in
149 integer,dimension(3)::star
,cnts
150 integer::i
,j
,k
,varid
,ends(3),dims(3),n(2)
151 character(len
=256) msg
155 call netcdf_var_info(ncid
,name
,dims
,varid
,netcdf_msglevel
)
156 write(msg
,*)"array ",trim(name
)," shape ",n
," NetCDF dimensions ",dims
159 if(dims(1).lt
.n(1).or
.dims(2).lt
.n(2))call crash("array shape too large")
160 star
= (/1,1,iframe
/)
161 ends
= (/n(1),n(2),iframe
/)
162 if(iframe
.gt
.dims(3))call crash('netcdf_write_2d: frame not in file')
163 cnts
= ends
- star
+ 1
165 write(msg
,*)"writing ",trim(name
)," from ",star
," to ",ends
169 call check(nf90_put_var(ncid
, varid
, a
, start
= star
, count
= cnts
),"nf90_put_var:"//trim(name
))
171 end subroutine netcdf_write_2d
173 integer function l2i(l
)
175 logical, intent(in
)::l
184 subroutine netcdf_var_info(ncid
,varname
,dims
,varid
,prints
)
187 integer, intent(in
)::ncid
188 character(len
=*)::varname
189 integer,intent(out
)::dims(:),varid
190 integer,intent(in
),optional
::prints
192 integer, parameter::mdims
= 256
193 integer:: xtype
, ndims
, natts
, dimids(mdims
),i
,j
,attnum
195 character(len
=nf90_max_name
):: name
196 integer:: values_int(mdims
)
197 real:: values_real(mdims
)
198 character(len
=mdims
):: values_char
199 character(LEN
=256):: filename
, msg
200 logical::verbose
=.true
.
202 if(present(prints
)) verbose
= prints
>0
204 call check(nf90_inq_varid(ncid
,trim(varname
),varid
),"nf90_inq_varid"//trim(varname
))
205 call check(nf90_inquire_variable(ncid
, varid
, name
, xtype
, ndims
, dimids
, natts
),"nf90_inquire_variable")
206 if(ndims
>mdims
)call crash("netcdf_var_info: increase mdims")
207 if(ndims
>size(dims
))call crash("netcdf_var_info: dims too short")
209 write(msg
,*)"variable ",trim(name
), " xtype",xtype
, "ndims",ndims
, "natts",natts
213 call check(nf90_inquire_dimension(ncid
, dimids(i
), name
, len
),"nf90_inquire_dimension")
216 write(msg
,*)"dimension ",i
,trim(name
)," length",len
220 if(.not
.verbose
)return
223 call check(nf90_inq_attname(ncid
, varid
, attnum
, name
),"nf90_inq_attname")
224 call check(nf90_inquire_attribute(ncid
, varid
, trim(name
), xtype
, len
, attnum
),"nf90_inquire_attribute")
225 if(len
>mdims
)call crash("netcdf_var_info: increase mdims")
226 !write(msg,*)"attribute ",i,trim(name),' type',xtype
230 call check(nf90_get_att(ncid
, varid
, trim(name
), values_char
),"nf90_get_att")
231 write(msg
,*)"attribute ",i
,trim(name
)," type ",xtype
," values",len
," : ",trim(values_char
)
232 case (nf90_int
,nf90_short
,nf90_ushort
,nf90_uint
,nf90_int64
,nf90_uint64
)
233 call check(nf90_get_att(ncid
, varid
, trim(name
), values_int
),"nf90_get_att")
234 write(msg
,*)"attribute ",i
,trim(name
)," type ",xtype
," values",len
," : ",(values_int(j
),j
=1,len
)
235 case (nf90_float
,nf90_double
)
236 call check(nf90_get_att(ncid
, varid
, trim(name
), values_real
),"nf90_get_att")
237 write(msg
,*)"attribute ",i
,trim(name
)," type ",xtype
," values",len
," : ",(values_real(j
),j
=1,len
)
239 write(msg
,*)'attribute type ',xtype
,' not supported'
243 end subroutine netcdf_var_info
245 subroutine check(ierr
,errmsg
)
247 integer, intent(in
)::ierr
248 character(len
=*), intent(in
)::errmsg
249 character(len
=256)msg
251 write(msg
,"(a,a,i6,1x,a)")trim(errmsg
)," error",ierr
,trim(nf90_strerror(ierr
))
252 call crash(trim(msg
))
256 end module module_netcdf