nfw.F90 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. !
  2. ! File: nfw.f90
  3. !
  4. ! Author: Pavel Sakov, CSIRO Marine Research
  5. !
  6. ! Created: 17 March 2005
  7. !
  8. ! Purpose: Contains wrappers to netcdf functions, mainly for easier
  9. ! error handling.
  10. !
  11. ! Description:
  12. !
  13. ! Each subroutine in nfw.f90 is a simple wrapper of a similar
  14. ! function in the NetCDF Fortran interface. The rules of use are
  15. ! pretty simple: for a given NetCDF Fortran function, replace
  16. ! prefix "nf_" by "nfw_" and add the NetCDF file name as the
  17. ! first argument.
  18. !
  19. ! Here is the current list of subroutines in nfw_mod:
  20. !
  21. ! nfw_create(fname, mode, ncid)
  22. ! nfw_open(fname, mode, ncid)
  23. ! nfw_enddef(fname, ncid)
  24. ! nfw_close(fname, ncid)
  25. ! nfw_inq_unlimdim(fname, ncid, unlimdimid)
  26. ! nfw_inq_dimid(fname, ncid, name, dimid)
  27. ! nfw_inq_dimlen(fname, ncid, dimid, length)
  28. ! nfw_def_dim(fname, ncid, name, length, dimid)
  29. ! nfw_def_var(fname, ncid, name, type, ndims, dimids, varid)
  30. ! nfw_inq_varid(fname, ncid, name, varid)
  31. ! nfw_inq_varname(fname, ncid, varid, name)
  32. ! nfw_inq_varndims(fname, ncid, varid, ndims)
  33. ! nfw_inq_vardimid(fname, ncid, varid, dimids)
  34. ! nfw_rename_var(fname, ncid, oldname, newname)
  35. ! nfw_put_var_int(fname, ncid, varid, v)
  36. ! nfw_put_var_double(fname, ncid, varid, v)
  37. ! nfw_put_var_real(fname, ncid, varid, v)
  38. ! nfw_get_var_int(fname, ncid, varid, v)
  39. ! nfw_get_var_double(fname, ncid, varid, v)
  40. ! nfw_put_vara_int(fname, ncid, varid, start, length, v)
  41. ! nfw_put_vara_double(fname, ncid, varid, start, length, v)
  42. ! nfw_get_vara_int(fname, ncid, varid, start, length, v)
  43. ! nfw_get_vara_double(fname, ncid, varid, start, length, v)
  44. ! nfw_get_att_int(fname, ncid, varid, attname, v)
  45. ! nfw_get_att_real(fname, ncid, varid, attname, v)
  46. ! nfw_get_att_double(fname, ncid, varid, attname, v)
  47. ! nfw_put_att_text(fname, ncid, varid, attname, length, text)
  48. ! nfw_put_att_int(fname, ncid, varid, attname, type, length, v)
  49. ! nfw_put_att_real(fname, ncid, varid, attname, type, length, v)
  50. ! nfw_put_att_double(fname, ncid, varid, attname, type, length, v)
  51. !
  52. ! Derived procedures:
  53. !
  54. ! nfw_get_var_double_firstrecord(fname, ncid, varid, v)
  55. ! nfw_var_exists(ncid, name)
  56. ! nfw_dim_exists(ncid, name)
  57. ! Modifications:
  58. !
  59. ! 29/04/2008 PS: added nfw_rename_var(fname, ncid, oldname, newname)
  60. ! 21/10/2009 PS: added nfw_var_exists(ncid, name)
  61. ! 22/10/2009 PS: added nfw_put_att_double(fname, ncid, varid, attname, type,
  62. ! length, v)
  63. ! 06/11/2009 PS: added nfw_dim_exists(ncid, name)
  64. ! nfw_put_att_real(fname, ncid, varid, attname, type, length, v)
  65. ! nfw_get_att_real(fname, ncid, varid, attname, v)
  66. module nfw_mod
  67. implicit none
  68. include 'netcdf.inc'
  69. character(*), private, parameter :: nfw_version = "0.03"
  70. integer, private, parameter :: logunit = 6
  71. character(*), private, parameter :: errprefix = "nfw: error: "
  72. private quit1, quit2, quit3
  73. contains
  74. #if defined(F90_NOFLUSH)
  75. subroutine flush(dummy)
  76. integer, intent(in) :: dummy
  77. end subroutine flush
  78. #endif
  79. ! Common exit point -- for the sake of debugging
  80. subroutine quit
  81. stop
  82. end subroutine quit
  83. subroutine quit1(fname, procname, status)
  84. character*(*), intent(in) :: fname
  85. character*(*), intent(in) :: procname
  86. integer, intent(in) :: status
  87. write(logunit, *)
  88. write(logunit, *) errprefix, '"', trim(fname), '": ', procname, '(): ',&
  89. nf_strerror(status)
  90. call flush(logunit)
  91. call quit
  92. end subroutine quit1
  93. subroutine quit2(fname, procname, name, status)
  94. character*(*), intent(in) :: fname
  95. character*(*), intent(in) :: procname
  96. character*(*), intent(in) :: name
  97. integer, intent(in) :: status
  98. write(logunit, *)
  99. write(logunit, *) errprefix, '"', trim(fname), '": ', procname, '(): "',&
  100. trim(name), '": ', nf_strerror(status)
  101. call flush(logunit)
  102. call quit
  103. end subroutine quit2
  104. subroutine quit3(fname, procname, name1, name2, status)
  105. character*(*), intent(in) :: fname
  106. character*(*), intent(in) :: procname
  107. character*(*), intent(in) :: name1
  108. character*(*), intent(in) :: name2
  109. integer, intent(in) :: status
  110. write(logunit, *)
  111. write(logunit, *) errprefix, '"', trim(fname), '": ', procname, '(): "',&
  112. trim(name1), '": "', trim(name2), '": ', nf_strerror(status)
  113. call flush(logunit)
  114. call quit
  115. end subroutine quit3
  116. subroutine nfw_create(fname, mode, ncid)
  117. character*(*), intent(in) :: fname
  118. integer, intent(in) :: mode
  119. integer, intent(out) :: ncid
  120. integer :: status
  121. status = nf_create(trim(fname), mode, ncid)
  122. if (status /= 0) call quit1(fname, 'nf_create', status)
  123. end subroutine nfw_create
  124. subroutine nfw_open(fname, mode, ncid)
  125. character*(*), intent(in) :: fname
  126. integer, intent(in) :: mode
  127. integer, intent(out) :: ncid
  128. integer :: status
  129. status = nf_open(trim(fname), mode, ncid)
  130. if (status /= 0) call quit1(fname, 'nf_open', status)
  131. end subroutine nfw_open
  132. subroutine nfw_enddef(fname, ncid)
  133. character*(*), intent(in) :: fname
  134. integer, intent(in) :: ncid
  135. integer :: status
  136. status = nf_enddef(ncid)
  137. if (status /= 0) call quit1(fname, 'nf_enddef', status)
  138. end subroutine nfw_enddef
  139. subroutine nfw_redef(fname, ncid)
  140. character*(*), intent(in) :: fname
  141. integer, intent(in) :: ncid
  142. integer :: status
  143. status = nf_redef(ncid)
  144. if (status /= 0) call quit1(fname, 'nf_redef', status)
  145. end subroutine nfw_redef
  146. subroutine nfw_close(fname, ncid)
  147. character*(*), intent(in) :: fname
  148. integer, intent(in) :: ncid
  149. integer :: status
  150. status = nf_close(ncid)
  151. if (status /= 0) call quit1(fname, 'nf_close', status)
  152. end subroutine nfw_close
  153. subroutine nfw_inq_unlimdim(fname, ncid, unlimdimid)
  154. character*(*), intent(in) :: fname
  155. integer, intent(in) :: ncid
  156. integer, intent(out) :: unlimdimid
  157. integer :: status
  158. status = nf_inq_unlimdim(ncid, unlimdimid)
  159. if (status /= 0) call quit1(fname, 'nf_inq_unlimdimid', status)
  160. end subroutine nfw_inq_unlimdim
  161. subroutine nfw_inq_dimid(fname, ncid, name, dimid)
  162. character*(*), intent(in) :: fname
  163. integer, intent(in) :: ncid
  164. character*(*), intent(in) :: name
  165. integer, intent(out) :: dimid
  166. integer :: status
  167. status = nf_inq_dimid(ncid, trim(name), dimid)
  168. if (status /= 0) call quit2(fname, 'nf_inq_dimid', name, status)
  169. end subroutine nfw_inq_dimid
  170. subroutine nfw_inq_dimlen(fname, ncid, dimid, length)
  171. character*(*), intent(in) :: fname
  172. integer, intent(in) :: ncid
  173. integer, intent(in) :: dimid
  174. integer, intent(out) :: length
  175. integer :: status
  176. status = nf_inq_dimlen(ncid, dimid, length)
  177. if (status /= 0) call quit1(fname, 'nf_inq_dimlen', status)
  178. end subroutine nfw_inq_dimlen
  179. subroutine nfw_def_dim(fname, ncid, name, length, dimid)
  180. character*(*), intent(in) :: fname
  181. integer, intent(in) :: ncid
  182. character*(*), intent(in) :: name
  183. integer, intent(in) :: length
  184. integer, intent(out) :: dimid
  185. integer :: status
  186. status = nf_def_dim(ncid, name, length, dimid)
  187. if (status /= 0) call quit2(fname, 'nf_def_dim', name, status)
  188. end subroutine nfw_def_dim
  189. subroutine nfw_def_var(fname, ncid, name, type, ndims, dimids, varid)
  190. character*(*), intent(in) :: fname
  191. integer, intent(in) :: ncid
  192. character*(*), intent(in) :: name
  193. integer, intent(in) :: type
  194. integer, intent(in) :: ndims
  195. integer, intent(in) :: dimids(*)
  196. integer, intent(out) :: varid
  197. integer :: status
  198. status = nf_def_var(ncid, name, type, ndims, dimids, varid)
  199. if (status /= 0) call quit2(fname, 'nf_def_var', name, status)
  200. end subroutine nfw_def_var
  201. subroutine nfw_inq_varid(fname, ncid, name, varid)
  202. character*(*), intent(in) :: fname
  203. integer, intent(in) :: ncid
  204. character*(*), intent(in) :: name
  205. integer, intent(out) :: varid
  206. integer :: status
  207. status = nf_inq_varid(ncid, trim(name), varid)
  208. if (status /= 0) call quit2(fname, 'nf_inq_varid', name, status)
  209. end subroutine nfw_inq_varid
  210. subroutine nfw_inq_varname(fname, ncid, varid, name)
  211. character*(*), intent(in) :: fname
  212. integer, intent(in) :: ncid
  213. integer, intent(in) :: varid
  214. character*(*), intent(out) :: name
  215. integer :: status
  216. status = nf_inq_varname(ncid, varid, name)
  217. if (status /= 0) call quit1(fname, 'nf_inq_varname', status)
  218. end subroutine nfw_inq_varname
  219. subroutine nfw_inq_varndims(fname, ncid, varid, ndims)
  220. character*(*), intent(in) :: fname
  221. integer, intent(in) :: ncid
  222. integer, intent(in) :: varid
  223. integer, intent(out) :: ndims
  224. character*(NF_MAX_NAME) :: name
  225. integer :: status
  226. status = nf_inq_varndims(ncid, varid, ndims)
  227. if (status /= 0) then
  228. call nfw_inq_varname(fname, ncid, varid, name)
  229. call quit2(fname, 'nf_inq_varndims', name, status)
  230. end if
  231. end subroutine nfw_inq_varndims
  232. subroutine nfw_inq_vardimid(fname, ncid, varid, dimids)
  233. character*(*), intent(in) :: fname
  234. integer, intent(in) :: ncid
  235. integer, intent(in) :: varid
  236. integer, intent(out) :: dimids(*)
  237. character*(NF_MAX_NAME) :: name
  238. integer :: status
  239. status = nf_inq_vardimid(ncid, varid, dimids)
  240. if (status /= 0) then
  241. call nfw_inq_varname(fname, ncid, varid, name)
  242. call quit2(fname, 'nf_inq_vardimid', name, status)
  243. end if
  244. end subroutine nfw_inq_vardimid
  245. subroutine nfw_rename_var(fname, ncid, oldname, newname)
  246. character*(*), intent(in) :: fname
  247. integer, intent(in) :: ncid
  248. character*(*), intent(in) :: oldname
  249. character*(*), intent(in) :: newname
  250. integer :: varid
  251. integer :: status
  252. call nfw_inq_varid(fname, ncid, oldname, varid)
  253. status = nf_rename_var(ncid, varid, newname)
  254. if (status /= 0) then
  255. call quit2(fname, 'nf_rename_var', oldname, status)
  256. end if
  257. end subroutine nfw_rename_var
  258. subroutine nfw_put_var_int(fname, ncid, varid, v)
  259. character*(*), intent(in) :: fname
  260. integer, intent(in) :: ncid
  261. integer, intent(in) :: varid
  262. integer, intent(in) :: v(*)
  263. character*(NF_MAX_NAME) :: name
  264. integer :: status
  265. status = nf_put_var_int(ncid, varid, v)
  266. if (status /= 0) then
  267. call nfw_inq_varname(fname, ncid, varid, name)
  268. call quit2(fname, 'nf_put_var_double', name, status)
  269. end if
  270. end subroutine nfw_put_var_int
  271. subroutine nfw_put_var_double(fname, ncid, varid, v)
  272. character*(*), intent(in) :: fname
  273. integer, intent(in) :: ncid
  274. integer, intent(in) :: varid
  275. real(8), intent(in) :: v(*)
  276. character*(NF_MAX_NAME) :: name
  277. integer :: status
  278. status = nf_put_var_double(ncid, varid, v)
  279. if (status /= 0) then
  280. call nfw_inq_varname(fname, ncid, varid, name)
  281. call quit2(fname, 'nf_put_var_double', name, status)
  282. end if
  283. end subroutine nfw_put_var_double
  284. subroutine nfw_put_var_real(fname, ncid, varid, v)
  285. character*(*), intent(in) :: fname
  286. integer, intent(in) :: ncid
  287. integer, intent(in) :: varid
  288. real(4), intent(in) :: v(*)
  289. character*(NF_MAX_NAME) :: name
  290. integer :: status
  291. status = nf_put_var_real(ncid, varid, v)
  292. if (status /= 0) then
  293. call nfw_inq_varname(fname, ncid, varid, name)
  294. call quit2(fname, 'nf_put_var_real', name, status)
  295. end if
  296. end subroutine nfw_put_var_real
  297. subroutine nfw_get_var_int(fname, ncid, varid, v)
  298. character*(*), intent(in) :: fname
  299. integer, intent(in) :: ncid
  300. integer, intent(in) :: varid
  301. integer, intent(out) :: v(*)
  302. character*(NF_MAX_NAME) :: name
  303. integer :: status
  304. status = nf_get_var_int(ncid, varid, v)
  305. if (status /= 0) then
  306. call nfw_inq_varname(fname, ncid, varid, name)
  307. call quit2(fname, 'nf_get_var_int', name, status)
  308. end if
  309. end subroutine nfw_get_var_int
  310. subroutine nfw_get_var_double(fname, ncid, varid, v)
  311. character*(*), intent(in) :: fname
  312. integer, intent(in) :: ncid
  313. integer, intent(in) :: varid
  314. real(8), intent(out) :: v(*)
  315. character*(NF_MAX_NAME) :: name
  316. integer :: status
  317. status = nf_get_var_double(ncid, varid, v)
  318. if (status /= 0) then
  319. call nfw_inq_varname(fname, ncid, varid, name)
  320. call quit2(fname, 'nf_get_var_double', name, status)
  321. end if
  322. end subroutine nfw_get_var_double
  323. subroutine nfw_get_var_text(fname, ncid, varid, v)
  324. character*(*), intent(in) :: fname
  325. integer, intent(in) :: ncid
  326. integer, intent(in) :: varid
  327. character, intent(out) :: v(*)
  328. character*(NF_MAX_NAME) :: name
  329. integer :: status
  330. status = nf_get_var_text(ncid, varid, v)
  331. if (status /= 0) then
  332. call nfw_inq_varname(fname, ncid, varid, name)
  333. call quit2(fname, 'nf_get_var_int', name, status)
  334. end if
  335. end subroutine nfw_get_var_text
  336. subroutine nfw_put_vara_int(fname, ncid, varid, start, length, v)
  337. character*(*), intent(in) :: fname
  338. integer, intent(in) :: ncid
  339. integer, intent(in) :: varid
  340. integer, intent(in) :: start(*)
  341. integer, intent(in) :: length(*)
  342. integer, intent(in) :: v(*)
  343. character*(NF_MAX_NAME) :: name
  344. integer :: status
  345. status = nf_put_vara_int(ncid, varid, start, length, v)
  346. if (status /= 0) then
  347. call nfw_inq_varname(fname, ncid, varid, name)
  348. call quit2(fname, 'nf_put_vara_int', name, status)
  349. end if
  350. end subroutine nfw_put_vara_int
  351. subroutine nfw_put_vara_double(fname, ncid, varid, start, length, v)
  352. character*(*), intent(in) :: fname
  353. integer, intent(in) :: ncid
  354. integer, intent(in) :: varid
  355. integer, intent(in) :: start(*)
  356. integer, intent(in) :: length(*)
  357. real(8), intent(in) :: v(*)
  358. character*(NF_MAX_NAME) :: name
  359. integer :: status
  360. status = nf_put_vara_double(ncid, varid, start, length, v)
  361. if (status /= 0) then
  362. call nfw_inq_varname(fname, ncid, varid, name)
  363. call quit2(fname, 'nf_put_vara_double', name, status)
  364. end if
  365. end subroutine nfw_put_vara_double
  366. subroutine nfw_get_vara_int(fname, ncid, varid, start, length, v)
  367. character*(*), intent(in) :: fname
  368. integer, intent(in) :: ncid
  369. integer, intent(in) :: varid
  370. integer, intent(in) :: start(*)
  371. integer, intent(in) :: length(*)
  372. integer, intent(out) :: v(*)
  373. character*(NF_MAX_NAME) :: name
  374. integer :: status
  375. status = nf_get_vara_int(ncid, varid, start, length, v)
  376. if (status /= 0) then
  377. call nfw_inq_varname(fname, ncid, varid, name)
  378. call quit2(fname, 'nf_get_vara_int', name, status)
  379. end if
  380. end subroutine nfw_get_vara_int
  381. subroutine nfw_get_vara_double(fname, ncid, varid, start, length, v)
  382. character*(*), intent(in) :: fname
  383. integer, intent(in) :: ncid
  384. integer, intent(in) :: varid
  385. integer, intent(in) :: start(*)
  386. integer, intent(in) :: length(*)
  387. real(8), intent(out) :: v(*)
  388. character*(NF_MAX_NAME) :: name
  389. integer :: status
  390. status = nf_get_vara_double(ncid, varid, start, length, v)
  391. if (status /= 0) then
  392. call nfw_inq_varname(fname, ncid, varid, name)
  393. call quit2(fname, 'nf_get_vara_double', name, status)
  394. end if
  395. end subroutine nfw_get_vara_double
  396. subroutine nfw_get_att_int(fname, ncid, varid, attname, v)
  397. character*(*), intent(in) :: fname
  398. integer, intent(in) :: ncid
  399. integer, intent(in) :: varid
  400. character*(*), intent(in) :: attname
  401. integer, intent(out) :: v(*)
  402. character*(NF_MAX_NAME) :: varname
  403. integer :: status
  404. status = nf_get_att_int(ncid, varid, attname, v)
  405. if (status /= 0) then
  406. if (varid /= nf_global) then
  407. call nfw_inq_varname(fname, ncid, varid, varname)
  408. else
  409. varname = 'NF_GLOBAL'
  410. end if
  411. call quit3(fname, 'nf_get_att_int', varname, attname, status)
  412. end if
  413. end subroutine nfw_get_att_int
  414. subroutine nfw_get_att_real(fname, ncid, varid, attname, v)
  415. character*(*), intent(in) :: fname
  416. integer, intent(in) :: ncid
  417. integer, intent(in) :: varid
  418. character*(*), intent(in) :: attname
  419. real(4), intent(out) :: v(*)
  420. character*(NF_MAX_NAME) :: varname
  421. integer :: status
  422. status = nf_get_att_real(ncid, varid, attname, v)
  423. if (status /= 0) then
  424. if (varid /= nf_global) then
  425. call nfw_inq_varname(fname, ncid, varid, varname)
  426. else
  427. varname = 'NF_GLOBAL'
  428. end if
  429. call quit3(fname, 'nf_get_att_real', varname, attname, status)
  430. end if
  431. end subroutine nfw_get_att_real
  432. subroutine nfw_get_att_double(fname, ncid, varid, attname, v)
  433. character*(*), intent(in) :: fname
  434. integer, intent(in) :: ncid
  435. integer, intent(in) :: varid
  436. character*(*), intent(in) :: attname
  437. real(8), intent(out) :: v(*)
  438. character*(NF_MAX_NAME) :: varname
  439. integer :: status
  440. status = nf_get_att_double(ncid, varid, attname, v)
  441. if (status /= 0) then
  442. if (varid /= nf_global) then
  443. call nfw_inq_varname(fname, ncid, varid, varname)
  444. else
  445. varname = 'NF_GLOBAL'
  446. end if
  447. call quit3(fname, 'nf_get_att_double', varname, attname, status)
  448. end if
  449. end subroutine nfw_get_att_double
  450. subroutine nfw_put_att_text(fname, ncid, varid, attname, length, text)
  451. character*(*), intent(in) :: fname
  452. integer, intent(in) :: ncid
  453. integer, intent(in) :: varid
  454. character*(*), intent(in) :: attname
  455. integer, intent(in) :: length
  456. character*(*), intent(in) :: text
  457. integer :: status
  458. character*(NF_MAX_NAME) :: varname
  459. status = nf_put_att_text(ncid, varid, attname, length, trim(text))
  460. if (status /= 0) then
  461. if (varid /= nf_global) then
  462. call nfw_inq_varname(fname, ncid, varid, varname)
  463. else
  464. varname = 'NF_GLOBAL'
  465. end if
  466. call quit3(fname, 'nf_put_att_text', varname, attname, status)
  467. end if
  468. end subroutine nfw_put_att_text
  469. subroutine nfw_put_att_int(fname, ncid, varid, attname, type, length, v)
  470. character*(*), intent(in) :: fname
  471. integer, intent(in) :: ncid
  472. integer, intent(in) :: varid
  473. character*(*), intent(in) :: attname
  474. integer, intent(in) :: type
  475. integer, intent(in) :: length
  476. integer, intent(in) :: v(*)
  477. integer :: status
  478. character*(NF_MAX_NAME) :: varname
  479. status = nf_put_att_int(ncid, varid, attname, type, length, v)
  480. if (status /= 0) then
  481. if (varid /= nf_global) then
  482. call nfw_inq_varname(fname, ncid, varid, varname)
  483. else
  484. varname = 'NF_GLOBAL'
  485. end if
  486. call quit3(fname, 'nf_put_att_int', varname, attname, status)
  487. end if
  488. end subroutine nfw_put_att_int
  489. subroutine nfw_put_att_real(fname, ncid, varid, attname, type, length, v)
  490. character*(*), intent(in) :: fname
  491. integer, intent(in) :: ncid
  492. integer, intent(in) :: varid
  493. character*(*), intent(in) :: attname
  494. integer, intent(in) :: type
  495. integer, intent(in) :: length
  496. real(4), intent(in) :: v(*)
  497. integer :: status
  498. character*(NF_MAX_NAME) :: varname
  499. status = nf_put_att_real(ncid, varid, attname, type, length, v)
  500. if (status /= 0) then
  501. if (varid /= nf_global) then
  502. call nfw_inq_varname(fname, ncid, varid, varname)
  503. else
  504. varname = 'NF_GLOBAL'
  505. end if
  506. call quit3(fname, 'nf_put_att_real', varname, attname, status)
  507. end if
  508. end subroutine nfw_put_att_real
  509. subroutine nfw_put_att_double(fname, ncid, varid, attname, type, length, v)
  510. character*(*), intent(in) :: fname
  511. integer, intent(in) :: ncid
  512. integer, intent(in) :: varid
  513. character*(*), intent(in) :: attname
  514. integer, intent(in) :: type
  515. integer, intent(in) :: length
  516. real(8), intent(in) :: v(*)
  517. integer :: status
  518. character*(NF_MAX_NAME) :: varname
  519. status = nf_put_att_double(ncid, varid, attname, type, length, v)
  520. if (status /= 0) then
  521. if (varid /= nf_global) then
  522. call nfw_inq_varname(fname, ncid, varid, varname)
  523. else
  524. varname = 'NF_GLOBAL'
  525. end if
  526. call quit3(fname, 'nf_put_att_double', varname, attname, status)
  527. end if
  528. end subroutine nfw_put_att_double
  529. ! Derived subroutines
  530. ! Reads the first record only
  531. subroutine nfw_get_var_double_firstrecord(fname, ncid, varid, v)
  532. character*(*), intent(in) :: fname
  533. integer, intent(in) :: ncid
  534. integer, intent(in) :: varid
  535. real(8), intent(out) :: v(*)
  536. integer :: ndims
  537. integer :: unlimdimid
  538. integer :: dimids(NF_MAX_VAR_DIMS)
  539. integer :: dimlen(NF_MAX_VAR_DIMS)
  540. integer :: dstart(NF_MAX_VAR_DIMS)
  541. integer :: i
  542. character*(NF_MAX_NAME) :: name
  543. integer :: status
  544. call nfw_inq_varndims(fname, ncid, varid, ndims)
  545. call nfw_inq_vardimid(fname, ncid, varid, dimids)
  546. call nfw_inq_unlimdim(fname, ncid, unlimdimid)
  547. do i = 1, ndims
  548. call nfw_inq_dimlen(fname, ncid, dimids(i), dimlen(i))
  549. dstart(i) = 1
  550. end do
  551. ! check size of v
  552. if (dimids(ndims) == unlimdimid) then
  553. dimlen(ndims) = 1 ! 1 record only
  554. end if
  555. status = nf_get_vara_double(ncid, varid, dstart, dimlen, v)
  556. if (status /= 0) then
  557. call nfw_inq_varname(fname, ncid, varid, name)
  558. call quit2(fname, 'nf_get_vara_double', name, status)
  559. end if
  560. end subroutine nfw_get_var_double_firstrecord
  561. logical function nfw_var_exists(ncid, name)
  562. integer, intent(in) :: ncid
  563. character*(*), intent(in) :: name
  564. integer :: varid
  565. integer :: status
  566. status = nf_inq_varid(ncid, trim(name), varid)
  567. nfw_var_exists = (status == 0)
  568. end function nfw_var_exists
  569. logical function nfw_dim_exists(ncid, name)
  570. integer, intent(in) :: ncid
  571. character*(*), intent(in) :: name
  572. integer :: dimid
  573. integer :: status
  574. status = nf_inq_dimid(ncid, trim(name), dimid)
  575. nfw_dim_exists = (status == 0)
  576. end function nfw_dim_exists
  577. end module nfw_mod