10 integer,
parameter :: dp = kind(0.0d0)
11 integer,
parameter :: line_len = 200
12 integer,
parameter :: db_type = db_pdb
15 public :: silo_create_file
16 public :: silo_open_file
17 public :: silo_close_file
18 public :: silo_set_time_varying
19 public :: silo_add_grid
20 public :: silo_add_var
21 public :: silo_set_mmesh_grid
22 public :: silo_set_mmesh_var
26 subroutine silo_create_file(filename, dbix)
27 character(len=*),
intent(in) :: filename
28 integer,
intent(out) :: dbix
30 character(len=line_len) :: fileinfo
32 fileinfo =
"A silo file" 33 ierr = dbcreate(trim(filename), len_trim(filename), db_clobber, &
34 db_local, fileinfo, len_trim(fileinfo), db_type, dbix)
36 print *,
"Error creating file ", trim(filename)
39 end subroutine silo_create_file
41 subroutine silo_open_file(filename, dbix)
42 character(len=*),
intent(in) :: filename
45 ierr = dbopen(trim(filename), len_trim(filename), db_type, &
48 print *,
"Error opening file ", trim(filename)
51 end subroutine silo_open_file
53 subroutine silo_close_file(dbix)
54 integer,
intent(in) :: dbix
59 print *,
"Error closing file with index", dbix
62 end subroutine silo_close_file
64 subroutine silo_mkdir(dbix, dirname)
65 character(len=*),
intent(in) :: dirname
66 integer,
intent(in) :: dbix
67 integer :: ierr, iostat
69 ierr = dbmkdir(dbix, trim(dirname), len_trim(dirname), iostat)
71 print *,
"Error creating directory ", dirname
74 end subroutine silo_mkdir
78 subroutine silo_set_time_varying(dbix)
79 integer,
intent(in) :: dbix
81 integer,
parameter :: int_bool(1) = 1
82 integer,
parameter :: dims(1) = 1
83 character(len=*),
parameter :: name1 =
"/ConnectivityIsTimeVarying" 84 character(len=*),
parameter :: name2 =
"/MetadataIsTimeVarying" 87 integer function dbwrite(dbid, varname, lvarname, var, dims, &
89 use,
intrinsic :: iso_c_binding
90 integer(c_int) :: dbid, var(*), lvarname, dims(*), ndims, datatype
91 character(kind=c_char) :: varname(*)
95 ierr = dbwrite(dbix, name1, len(name1), int_bool, dims, 1, db_int);
96 if (ierr /= 0) print *,
"Error writing ", trim(name1)
97 ierr = dbwrite(dbix, name2, len(name2), int_bool, dims, 1, db_int);
98 if (ierr /= 0) print *,
"Error writing ", trim(name2)
99 end subroutine silo_set_time_varying
101 subroutine silo_add_grid(dbix, gridname, n_dim, N_r, r_min, dr, &
102 lo_offset, hi_offset)
103 character(len=*),
intent(in) :: gridname
104 integer,
intent(in) :: dbix, n_dim, N_r(:)
105 integer,
intent(in) :: lo_offset(n_dim), hi_offset(n_dim)
106 real(dp),
intent(in) :: r_min(:), dr(:)
107 real(dp),
allocatable :: x_coords(:), y_coords(:), z_coords(:)
108 integer :: i, ierr, iostat, dboptix
111 function dbputqm(dbid, name, lname, xname, lxname, yname, &
112 lyname, zname, lzname, x, y, z, dims, ndims, &
113 datatype, coordtype, optlist_id, status)
114 use,
intrinsic :: iso_c_binding
115 integer(c_int) :: dbid, lname, lxname, lyname, lzname, dims(*), ndims
116 integer(c_int) :: datatype, coordtype, optlist_id, status, dbputqm
117 real(c_double) :: x(*), y(*), z(*)
118 character(kind=c_char) :: name(*), xname(*), yname(*), zname(*)
121 integer (c_int) function dbaddiopt(optlist_id, option, ivalue)
122 use,
intrinsic :: iso_c_binding
123 integer(c_int),
intent(in) :: optlist_id, option, ivalue(*)
124 end function dbaddiopt
127 if (n_dim < 1 .or. n_dim > 3)
then 128 print *,
"Cannot add grid for which n_dim < 1 or n_dim > 3" 132 allocate(x_coords(n_r(1)))
134 x_coords(i) = r_min(1) + (i-1) * dr(1)
138 allocate(y_coords(n_r(2)))
140 y_coords(i) = r_min(2) + (i-1) * dr(2)
143 allocate(y_coords(0))
147 allocate(z_coords(n_r(3)))
149 z_coords(i) = r_min(3) + (i-1) * dr(3)
152 allocate(z_coords(0))
156 ierr = dbmkoptlist(20, dboptix)
157 if (ierr /= 0) print *, &
158 "Error creating options list in SILO_add_grid ", dboptix
161 ierr = dbaddiopt(dboptix, dbopt_nspace, [n_dim])
162 if (ierr /= 0) print *, &
163 "Error dbaddiopt in SILO_add_grid: DBOPT_NSPACE", ierr
165 ierr = dbaddiopt(dboptix, dbopt_lo_offset, lo_offset)
166 if (ierr /= 0) print *, &
167 "Error dbaddiopt in SILO_add_grid: DBOPT_LO_OFFSET", ierr
169 ierr = dbaddiopt(dboptix, dbopt_hi_offset, hi_offset)
170 if (ierr /= 0) print *, &
171 "Error dbaddiopt in SILO_add_grid: DBOPT_HI_OFFSET", ierr
174 ierr = dbputqm(dbix, trim(gridname), len_trim(gridname), &
175 'x', 1,
'y', 1,
'z', 1, x_coords, y_coords, z_coords, &
176 n_r, n_dim, db_double, db_collinear, dboptix, iostat)
177 if (ierr /= 0) print *, &
178 "Error dbputqm is SILO_add_grid", ierr
180 ierr = dbfreeoptlist(dboptix)
181 if (ierr /= 0) print *, &
182 "Error dbfreeoptlist is SILO_add_grid", ierr
183 end subroutine silo_add_grid
185 subroutine silo_add_var(dbix, dataname, gridname, &
187 character(len=*),
intent(in) :: gridname, dataname
188 real(dp),
intent(in) :: d_packed(:)
189 integer,
intent(in) :: dbix, d_shape(:)
191 integer :: dboptix, ierr, iostat
195 function dbputqv1(dbid, name, lname, meshname, lmeshname, &
196 var, dims, ndims, mixvar, mixlen, datatype, &
197 centering, optlist_id, status)
198 use,
intrinsic :: iso_c_binding
199 integer(c_int) :: dbid, lname, lmeshname, dims(*), ndims, mixlen
200 integer(c_int) :: centering, optlist_id, status, datatype, dbputqv1
201 real(c_double) :: var(*), mixvar(*)
202 character(kind=c_char) :: name(*), meshname(*)
203 end function dbputqv1
206 if (
size(d_packed) /= product(d_shape))
then 207 error stop
"Error: d_packed does not correspond to d_shape" 210 if (
size(d_shape) < 1 .or.
size(d_shape) > 3)
then 211 error stop
"Error: size(d_shape) < 1 or size(d_shape) > 3" 214 ierr = dbmkoptlist(10, dboptix)
216 error stop
"Error creating options list in SILO_add_var" 219 ierr = dbaddiopt(dboptix, dbopt_hide_from_gui, 1)
222 ierr = dbputqv1(dbix, trim(dataname), len_trim(dataname), &
223 trim(gridname), len_trim(gridname), d_packed, d_shape, &
224 size(d_shape), dummy, 0, db_double, db_zonecent, dboptix, iostat)
226 print *,
"Error dbputqv1 in SILO_add_var", ierr
230 ierr = dbfreeoptlist(dboptix)
231 end subroutine silo_add_var
233 subroutine silo_set_mmesh_grid(dbix, mmname, gridnames, n_cycle, time)
234 character(len=*),
intent(in) :: mmname, gridnames(:)
235 integer,
intent(in) :: dbix
236 integer,
intent(in),
optional :: n_cycle
237 real(dp),
intent(in),
optional :: time
239 integer :: i, ierr,length
240 integer :: dboptix, iostat, old_str_len
241 integer :: n_grids, name_len, total_len
242 integer,
allocatable :: m_types(:), name_lengths(:)
243 character(len=:),
allocatable :: mnames
246 function dbputmmesh(dbid, name, lname, nmesh, meshnames, lmeshnames, &
247 meshtypes, optlist_id, status)
248 use,
intrinsic :: iso_c_binding
249 integer(c_int) :: dbputmmesh, lmeshnames(*)
250 integer(c_int) :: dbid, lname, nmesh, meshtypes(*), optlist_id, status
251 character(kind=c_char) :: name(*), meshnames(*)
252 end function dbputmmesh
255 n_grids =
size(gridnames)
256 if (n_grids < 1)
then 257 error stop
"SILO_set_mmesh_grid: error too few grids (<1)" 260 name_len = len(gridnames(1))
261 total_len = name_len * n_grids
262 allocate(
character(total_len) :: mnames)
263 allocate(name_lengths(n_grids))
264 allocate(m_types(n_grids))
267 mnames((i-1)*name_len+1:i*name_len) = trim(gridnames(i)) // char(0)
270 old_str_len = dbset2dstrlen(name_len)
271 m_types = db_quad_rect
272 name_lengths = name_len
274 ierr = dbmkoptlist(10, dboptix)
276 if (
present(n_cycle))
then 277 ierr = dbaddiopt(dboptix, dbopt_cycle, n_cycle)
280 if (
present(time))
then 281 ierr = dbaddiopt(dboptix, dbopt_dtime, time)
284 ierr = dbputmmesh(dbix, trim(mmname), len_trim(mmname), n_grids, &
285 mnames(1:total_len), name_lengths, m_types, dboptix, iostat)
287 error stop
"Error calling dbputmmesh" 290 ierr = dbfreeoptlist(dboptix)
291 length = dbset2dstrlen(old_str_len)
292 end subroutine silo_set_mmesh_grid
294 subroutine silo_set_mmesh_var(dbix, mvname, mmname, datanames, n_cycle, time)
295 character(len=*),
intent(in) :: mvname, mmname, datanames(:)
296 integer,
intent(in) :: dbix
297 integer,
intent(in),
optional :: n_cycle
298 real(dp),
intent(in),
optional :: time
301 integer :: i, ierr, dboptix, iostat,length
302 integer :: old_str_len, n_grids, name_len, total_len
303 integer,
allocatable :: m_types(:), name_lengths(:)
304 character(:),
allocatable :: dnames
307 function dbputmvar(dbid, name, lname, nlevels, meshnames, &
308 lmnames, meshtypes, optlist_id, status)
309 use,
intrinsic :: iso_c_binding
310 integer(c_int) :: dbputmvar, lmnames(*)
311 integer(c_int) :: dbid, lname, nlevels, meshtypes(*)
312 integer(c_int) :: optlist_id, status
313 character(kind=c_char) :: name(*), meshnames(*)
314 end function dbputmvar
317 n_grids =
size(datanames)
318 if (n_grids < 1)
then 319 error stop
"SILO_set_mmesh_var: error too few grids (<1)" 322 name_len = len(datanames(1))
323 total_len = name_len * n_grids
324 allocate(
character(total_len) :: dnames)
325 allocate(name_lengths(n_grids))
326 allocate(m_types(n_grids))
329 dnames((i-1)*name_len+1:i*name_len) = trim(datanames(i)) // char(0)
331 old_str_len = dbset2dstrlen(name_len)
333 name_lengths = name_len
335 ierr = dbmkoptlist(10, dboptix)
337 error stop
"Error creating options list in SILO_set_mmesh_var" 340 if (
present(n_cycle))
then 341 ierr = dbaddiopt(dboptix, dbopt_cycle, n_cycle)
344 if (
present(time))
then 345 ierr = dbaddiopt(dboptix, dbopt_dtime, time)
348 ierr = dbaddcopt(dboptix, dbopt_mmesh_name, &
349 trim(mmname), len_trim(mmname))
350 if (ierr /= 0) print *, &
351 "Error dbaddiopt is SILO_set_mmesh_var: DBOPT_MMESH_NAME", ierr
353 ierr = dbputmvar(dbix, trim(mvname), len_trim(mvname), n_grids, &
354 dnames(1:total_len), name_lengths, m_types, dboptix, iostat)
356 error stop
"Error calling dbputmvar" 359 ierr = dbfreeoptlist(dboptix)
360 length = dbset2dstrlen(old_str_len)
361 end subroutine silo_set_mmesh_var
This module contains wrapper functions to simplify writing Silo files.