sdfr 200001.1.1__py3-none-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sdfr/SDF.py ADDED
@@ -0,0 +1,644 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # Copyright 2022 University of Warwick, University of York
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ import ctypes as ct
19
+ import numpy as np
20
+ from enum import IntEnum
21
+ from .loadlib import sdf_lib
22
+
23
+ #try:
24
+ # import xarray as xr
25
+ #
26
+ # got_xarray = True
27
+ #except ImportError:
28
+ # print("WARNING: xarray not installed. Generating plain numpy arrays.")
29
+ # got_xarray = False
30
+
31
+
32
+ # Enum representation using ct
33
+ class SdfBlockType(IntEnum):
34
+ SDF_BLOCKTYPE_SCRUBBED = -1
35
+ SDF_BLOCKTYPE_NULL = 0
36
+ SDF_BLOCKTYPE_PLAIN_MESH = 1
37
+ SDF_BLOCKTYPE_POINT_MESH = 2
38
+ SDF_BLOCKTYPE_PLAIN_VARIABLE = 3
39
+ SDF_BLOCKTYPE_POINT_VARIABLE = 4
40
+ SDF_BLOCKTYPE_CONSTANT = 5
41
+ SDF_BLOCKTYPE_ARRAY = 6
42
+ SDF_BLOCKTYPE_RUN_INFO = 7
43
+ SDF_BLOCKTYPE_SOURCE = 8
44
+ SDF_BLOCKTYPE_STITCHED_TENSOR = 9
45
+ SDF_BLOCKTYPE_STITCHED_MATERIAL = 10
46
+ SDF_BLOCKTYPE_STITCHED_MATVAR = 11
47
+ SDF_BLOCKTYPE_STITCHED_SPECIES = 12
48
+ SDF_BLOCKTYPE_SPECIES = 13
49
+ SDF_BLOCKTYPE_PLAIN_DERIVED = 14
50
+ SDF_BLOCKTYPE_POINT_DERIVED = 15
51
+ SDF_BLOCKTYPE_CONTIGUOUS_TENSOR = 16
52
+ SDF_BLOCKTYPE_CONTIGUOUS_MATERIAL = 17
53
+ SDF_BLOCKTYPE_CONTIGUOUS_MATVAR = 18
54
+ SDF_BLOCKTYPE_CONTIGUOUS_SPECIES = 19
55
+ SDF_BLOCKTYPE_CPU_SPLIT = 20
56
+ SDF_BLOCKTYPE_STITCHED_OBSTACLE_GROUP = 21
57
+ SDF_BLOCKTYPE_UNSTRUCTURED_MESH = 22
58
+ SDF_BLOCKTYPE_STITCHED = 23
59
+ SDF_BLOCKTYPE_CONTIGUOUS = 24
60
+ SDF_BLOCKTYPE_LAGRANGIAN_MESH = 25
61
+ SDF_BLOCKTYPE_STATION = 26
62
+ SDF_BLOCKTYPE_STATION_DERIVED = 27
63
+ SDF_BLOCKTYPE_DATABLOCK = 28
64
+ SDF_BLOCKTYPE_NAMEVALUE = 29
65
+
66
+ class SdfGeometry(IntEnum):
67
+ SDF_GEOMETRY_NULL = 0
68
+ SDF_GEOMETRY_CARTESIAN = 1
69
+ SDF_GEOMETRY_CYLINDRICAL = 2
70
+ SDF_GEOMETRY_SPHERICAL = 3
71
+
72
+ class SdfStagger(IntEnum):
73
+ SDF_STAGGER_CELL_CENTRE = 0
74
+ SDF_STAGGER_FACE_X = 1
75
+ SDF_STAGGER_FACE_Y = 2
76
+ SDF_STAGGER_FACE_Z = 3
77
+ SDF_STAGGER_EDGE_X = 4
78
+ SDF_STAGGER_EDGE_Y = 5
79
+ SDF_STAGGER_EDGE_Z = 6
80
+ SDF_STAGGER_VERTEX = 7
81
+
82
+ class SdfDataType(IntEnum):
83
+ SDF_DATATYPE_NULL = 0
84
+ SDF_DATATYPE_INTEGER4 = 1
85
+ SDF_DATATYPE_INTEGER8 = 2
86
+ SDF_DATATYPE_REAL4 = 3
87
+ SDF_DATATYPE_REAL8 = 4
88
+ SDF_DATATYPE_REAL16 = 5
89
+ SDF_DATATYPE_CHARACTER = 6
90
+ SDF_DATATYPE_LOGICAL = 7
91
+ SDF_DATATYPE_OTHER = 8
92
+
93
+ _np_datatypes = [0, np.int32, np.int64, np.float32, np.float64, \
94
+ np.longdouble, np.byte, np.int32, bool, 0]
95
+ _ct_datatypes = [0, ct.c_int32, ct.c_int64, ct.c_float, ct.c_double, \
96
+ ct.c_longdouble, ct.c_char, ct.c_bool, 0]
97
+
98
+ # Constants
99
+ SDF_READ = 1
100
+ SDF_WRITE = 2
101
+ SDF_MAXDIMS = 4
102
+
103
+ class SdfBlock(ct.Structure):
104
+ pass # Forward declaration for self-referencing structure
105
+
106
+ class SdfFile(ct.Structure):
107
+ pass # Forward declaration for function pointer compatibility
108
+
109
+ SdfBlock._fields_ = [
110
+ ("extents", ct.POINTER(ct.c_double)),
111
+ ("dim_mults", ct.POINTER(ct.c_double)),
112
+ ("station_x", ct.POINTER(ct.c_double)),
113
+ ("station_y", ct.POINTER(ct.c_double)),
114
+ ("station_z", ct.POINTER(ct.c_double)),
115
+ ("mult", ct.c_double),
116
+ ("time", ct.c_double),
117
+ ("time_increment", ct.c_double),
118
+ ("dims", ct.c_int64 * SDF_MAXDIMS),
119
+ ("local_dims", ct.c_int64 * SDF_MAXDIMS),
120
+ ("block_start", ct.c_int64),
121
+ ("next_block_location", ct.c_int64),
122
+ ("data_location", ct.c_int64),
123
+ ("inline_block_start", ct.c_int64),
124
+ ("inline_next_block_location", ct.c_int64),
125
+ ("summary_block_start", ct.c_int64),
126
+ ("summary_next_block_location", ct.c_int64),
127
+ ("nelements", ct.c_int64),
128
+ ("nelements_local", ct.c_int64),
129
+ ("data_length", ct.c_int64),
130
+ ("nelements_blocks", ct.POINTER(ct.c_int64)),
131
+ ("data_length_blocks", ct.POINTER(ct.c_int64)),
132
+ ("array_starts", ct.POINTER(ct.c_int64)),
133
+ ("array_ends", ct.POINTER(ct.c_int64)),
134
+ ("array_strides", ct.POINTER(ct.c_int64)),
135
+ ("global_array_starts", ct.POINTER(ct.c_int64)),
136
+ ("global_array_ends", ct.POINTER(ct.c_int64)),
137
+ ("global_array_strides", ct.POINTER(ct.c_int64)),
138
+ ("ndims", ct.c_int32),
139
+ ("geometry", ct.c_int32),
140
+ ("datatype", ct.c_int32),
141
+ ("blocktype", ct.c_int32),
142
+ ("info_length", ct.c_int32),
143
+ ("type_size", ct.c_int32),
144
+ ("stagger", ct.c_int32),
145
+ ("datatype_out", ct.c_int32),
146
+ ("type_size_out", ct.c_int32),
147
+ ("nstations", ct.c_int32),
148
+ ("nvariables", ct.c_int32),
149
+ ("step", ct.c_int32),
150
+ ("step_increment", ct.c_int32),
151
+ ("dims_in", ct.POINTER(ct.c_int32)),
152
+ ("station_nvars", ct.POINTER(ct.c_int32)),
153
+ ("variable_types", ct.POINTER(ct.c_int32)),
154
+ ("station_index", ct.POINTER(ct.c_int32)),
155
+ ("station_move", ct.POINTER(ct.c_int32)),
156
+ ("nm", ct.c_int),
157
+ ("n_ids", ct.c_int),
158
+ ("opt", ct.c_int),
159
+ ("ng", ct.c_int),
160
+ ("nfaces", ct.c_int),
161
+ ("ngrids", ct.c_int),
162
+ ("offset", ct.c_int),
163
+ ("ngb", ct.c_int * 6),
164
+ ("const_value", ct.c_char * 16),
165
+ ("id", ct.c_char_p),
166
+ ("units", ct.c_char_p),
167
+ ("mesh_id", ct.c_char_p),
168
+ ("material_id", ct.c_char_p),
169
+ ("vfm_id", ct.c_char_p),
170
+ ("obstacle_id", ct.c_char_p),
171
+ ("station_id", ct.c_char_p),
172
+ ("name", ct.c_char_p),
173
+ ("material_name", ct.c_char_p),
174
+ ("must_read", ct.c_char_p),
175
+ ("dim_labels", ct.POINTER(ct.c_char_p)),
176
+ ("dim_units", ct.POINTER(ct.c_char_p)),
177
+ ("station_ids", ct.POINTER(ct.c_char_p)),
178
+ ("variable_ids", ct.POINTER(ct.c_char_p)),
179
+ ("station_names", ct.POINTER(ct.c_char_p)),
180
+ ("material_names", ct.POINTER(ct.c_char_p)),
181
+ ("node_list", ct.POINTER(ct.c_int)),
182
+ ("boundary_cells", ct.POINTER(ct.c_int)),
183
+ ("grids", ct.POINTER(ct.c_void_p)),
184
+ ("data", ct.c_void_p),
185
+ ("done_header", ct.c_bool),
186
+ ("done_info", ct.c_bool),
187
+ ("done_data", ct.c_bool),
188
+ ("dont_allocate", ct.c_bool),
189
+ ("dont_display", ct.c_bool),
190
+ ("dont_own_data", ct.c_bool),
191
+ ("use_mult", ct.c_bool),
192
+ ("next_block_modified", ct.c_bool),
193
+ ("rewrite_metadata", ct.c_bool),
194
+ ("in_file", ct.c_bool),
195
+ ("ng_any", ct.c_bool),
196
+ ("no_internal_ghost", ct.c_bool),
197
+ ("next", ct.POINTER(SdfBlock)),
198
+ ("prev", ct.POINTER(SdfBlock)),
199
+ ("subblock", ct.POINTER(SdfBlock)),
200
+ ("subblock2", ct.POINTER(SdfBlock)),
201
+ ("populate_data", ct.CFUNCTYPE(ct.POINTER(SdfBlock), ct.POINTER(SdfFile), ct.POINTER(SdfBlock))),
202
+ ("cpu_split", ct.c_int * SDF_MAXDIMS),
203
+ ("starts", ct.c_int * SDF_MAXDIMS),
204
+ ("proc_min", ct.c_int * 3),
205
+ ("proc_max", ct.c_int * 3),
206
+ ("ndim_labels", ct.c_int),
207
+ ("ndim_units", ct.c_int),
208
+ ("nstation_ids", ct.c_int),
209
+ ("nvariable_ids", ct.c_int),
210
+ ("nstation_names", ct.c_int),
211
+ ("nmaterial_names", ct.c_int),
212
+ ("option", ct.c_int),
213
+ ("mimetype", ct.c_char_p),
214
+ ("checksum_type", ct.c_char_p),
215
+ ("checksum", ct.c_char_p),
216
+ ("mmap", ct.c_char_p),
217
+ ("mmap_len", ct.c_int64),
218
+ ("derived", ct.c_bool),
219
+ ]
220
+
221
+ SdfFile._fields_ = [
222
+ ("dbg_count", ct.c_int64),
223
+ ("sdf_lib_version", ct.c_int32),
224
+ ("sdf_lib_revision", ct.c_int32),
225
+ ("sdf_extension_version", ct.c_int32),
226
+ ("sdf_extension_revision", ct.c_int32),
227
+ ("file_version", ct.c_int32),
228
+ ("file_revision", ct.c_int32),
229
+ ("dbg", ct.c_char_p),
230
+ ("dbg_buf", ct.c_char_p),
231
+ ("extension_names", ct.POINTER(ct.c_char_p)),
232
+ ("time", ct.c_double),
233
+ ("first_block_location", ct.c_int64),
234
+ ("summary_location", ct.c_int64),
235
+ ("start_location", ct.c_int64),
236
+ ("soi", ct.c_int64),
237
+ ("sof", ct.c_int64),
238
+ ("current_location", ct.c_int64),
239
+ ("jobid1", ct.c_int32),
240
+ ("jobid2", ct.c_int32),
241
+ ("endianness", ct.c_int32),
242
+ ("summary_size", ct.c_int32),
243
+ ("block_header_length", ct.c_int32),
244
+ ("string_length", ct.c_int32),
245
+ ("id_length", ct.c_int32),
246
+ ("code_io_version", ct.c_int32),
247
+ ("step", ct.c_int32),
248
+ ("nblocks", ct.c_int32),
249
+ ("nblocks_file", ct.c_int32),
250
+ ("error_code", ct.c_int32),
251
+ ("rank", ct.c_int),
252
+ ("ncpus", ct.c_int),
253
+ ("ndomains", ct.c_int),
254
+ ("rank_master", ct.c_int),
255
+ ("indent", ct.c_int),
256
+ ("print", ct.c_int),
257
+ ("buffer", ct.c_char_p),
258
+ ("filename", ct.c_char_p),
259
+ ("done_header", ct.c_bool),
260
+ ("restart_flag", ct.c_bool),
261
+ ("other_domains", ct.c_bool),
262
+ ("use_float", ct.c_bool),
263
+ ("use_summary", ct.c_bool),
264
+ ("use_random", ct.c_bool),
265
+ ("station_file", ct.c_bool),
266
+ ("swap", ct.c_bool),
267
+ ("inline_metadata_read", ct.c_bool),
268
+ ("summary_metadata_read", ct.c_bool),
269
+ ("inline_metadata_invalid", ct.c_bool),
270
+ ("summary_metadata_invalid", ct.c_bool),
271
+ ("tmp_flag", ct.c_bool),
272
+ ("metadata_modified", ct.c_bool),
273
+ ("can_truncate", ct.c_bool),
274
+ ("first_block_modified", ct.c_bool),
275
+ ("code_name", ct.c_char_p),
276
+ ("error_message", ct.c_char_p),
277
+ ("blocklist", ct.POINTER(SdfBlock)),
278
+ ("tail", ct.POINTER(SdfBlock)),
279
+ ("current_block", ct.POINTER(SdfBlock)),
280
+ ("last_block_in_file", ct.POINTER(SdfBlock)),
281
+ ("mmap", ct.c_char_p),
282
+ ("ext_data", ct.c_void_p),
283
+ ("stack_handle", ct.c_void_p),
284
+ ("array_count", ct.c_int),
285
+ ("fd", ct.c_int),
286
+ ("purge_duplicated_ids", ct.c_int),
287
+ ("internal_ghost_cells", ct.c_int),
288
+ ("ignore_nblocks", ct.c_int)
289
+ ]
290
+
291
+ class RunInfo(ct.Structure):
292
+ _fields_ = [
293
+ ("defines", ct.c_int64),
294
+ ("version", ct.c_int32),
295
+ ("revision", ct.c_int32),
296
+ ("compile_date", ct.c_int32),
297
+ ("run_date", ct.c_int32),
298
+ ("io_date", ct.c_int32),
299
+ ("minor_rev", ct.c_int32),
300
+ ("commit_id", ct.c_char_p),
301
+ ("sha1sum", ct.c_char_p),
302
+ ("compile_machine", ct.c_char_p),
303
+ ("compile_flags", ct.c_char_p),
304
+ ]
305
+
306
+
307
+ class BlockList:
308
+ """Contains all the blocks"""
309
+ def __init__(self, filename, convert=False, derived=True):
310
+ clib = sdf_lib
311
+ self._clib = clib
312
+ clib.sdf_open.restype = ct.POINTER(SdfFile)
313
+ #clib.sdf_open.restype = ct.c_void_p
314
+ clib.sdf_open.argtypes = [ct.c_char_p, ct.c_int, ct.c_int, ct.c_int]
315
+ clib.sdf_stack_init.argtypes = [ct.c_void_p]
316
+ #clib.sdf_read_blocklist.argtypes = [ct.POINTER(SdfFile)]
317
+ clib.sdf_read_blocklist.argtypes = [ct.c_void_p]
318
+ clib.sdf_read_blocklist_all.argtypes = [ct.c_void_p]
319
+ clib.sdf_helper_read_data.argtypes = [ct.c_void_p, ct.POINTER(SdfBlock)]
320
+ clib.sdf_free_block_data.argtypes = [ct.c_void_p, ct.POINTER(SdfBlock)]
321
+
322
+ h = clib.sdf_open(filename.encode("utf-8"), 0, 1, 0)
323
+ if h is None or not bool(h):
324
+ raise Exception(f"Failed to open file: '{filename}'")
325
+
326
+ if convert:
327
+ h.contents.use_float = True
328
+
329
+ h._clib = clib
330
+ self._handle = h
331
+ clib.sdf_stack_init(h)
332
+ if derived:
333
+ clib.sdf_read_blocklist_all(h)
334
+ else:
335
+ clib.sdf_read_blocklist(h)
336
+
337
+
338
+ block = h.contents.blocklist
339
+ meshes = []
340
+ mesh_vars = []
341
+ for n in range(h.contents.nblocks):
342
+ block = block.contents
343
+ block._handle = h
344
+ blocktype = block.blocktype
345
+ name = get_member_name(block.name)
346
+ if blocktype == SdfBlockType.SDF_BLOCKTYPE_RUN_INFO:
347
+ self.Run_info = get_run_info(block)
348
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONSTANT:
349
+ self.__dict__[name] = BlockConstant(block)
350
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_PLAIN_VARIABLE:
351
+ self.__dict__[name] = BlockPlainVariable(block)
352
+ mesh_vars.append(self.__dict__[name])
353
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_POINT_VARIABLE:
354
+ self.__dict__[name] = BlockPointVariable(block)
355
+ mesh_vars.append(self.__dict__[name])
356
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_PLAIN_MESH:
357
+ self.__dict__[name] = BlockPlainMesh(block)
358
+ meshes.append(self.__dict__[name])
359
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_POINT_MESH:
360
+ self.__dict__[name] = BlockPointMesh(block)
361
+ meshes.append(self.__dict__[name])
362
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_NAMEVALUE:
363
+ self.__dict__[name] = BlockNameValue(block)
364
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_ARRAY:
365
+ self.__dict__[name] = BlockArray(block)
366
+ #else:
367
+ # print(name,SdfBlockType(blocktype).name)
368
+ block = block.next
369
+
370
+ for var in mesh_vars:
371
+ gid = var.grid_id
372
+ for mesh in meshes:
373
+ if mesh.id == gid:
374
+ var._grid = mesh
375
+ break
376
+
377
+ def __del__(self):
378
+ self._clib.sdf_stack_destroy.argtypes = [ct.c_void_p]
379
+ self._clib.sdf_close.argtypes = [ct.c_void_p]
380
+ self._clib.sdf_stack_destroy(self._handle)
381
+ self._clib.sdf_close(self._handle)
382
+
383
+
384
+ class Block:
385
+ """SDF block type
386
+ Contains the data and metadata for a single
387
+ block from an SDF file.
388
+ """
389
+ def __init__(self, block):
390
+ self._handle = block._handle
391
+ self._id = block.id.decode()
392
+ self._name = block.name.decode()
393
+ self._datatype = _np_datatypes[block.datatype_out]
394
+ self._data_length = block.data_length
395
+ self._dims = tuple(block.dims[:block.ndims])
396
+ self._contents = block
397
+ self._owndata = True
398
+
399
+ def __del__(self):
400
+ if not self._owndata and self._data is not None:
401
+ clib = self._handle._clib
402
+ clib.sdf_free_block_data(self._handle, self._contents)
403
+
404
+ def _numpy_from_buffer(self, data, blen):
405
+ buffer_from_memory = ct.pythonapi.PyMemoryView_FromMemory
406
+ buffer_from_memory.restype = ct.py_object
407
+ dtype = self._datatype
408
+ if dtype == np.byte:
409
+ dtype = np.dtype('|S1')
410
+ totype = _ct_datatypes[self._contents.datatype]
411
+ cast = ct.cast(data, ct.POINTER(totype))
412
+ buf = buffer_from_memory(cast, blen)
413
+ self._owndata = False
414
+ return np.frombuffer(buf, dtype)
415
+
416
+ @property
417
+ def data(self):
418
+ """Block data contents"""
419
+ return self._data
420
+
421
+ @property
422
+ def datatype(self):
423
+ """Data type"""
424
+ return self._datatype
425
+
426
+ @property
427
+ def data_length(self):
428
+ """Data size"""
429
+ return self._data_length
430
+
431
+ @property
432
+ def dims(self):
433
+ """Data dimensions"""
434
+ return self._dims
435
+
436
+ @property
437
+ def id(self):
438
+ """Block id"""
439
+ return self._id
440
+
441
+ @property
442
+ def name(self):
443
+ """Block name"""
444
+ return self._name
445
+
446
+
447
+
448
+ class BlockConstant(Block):
449
+ """Constant block class"""
450
+ def __init__(self, block):
451
+ super().__init__(block)
452
+ offset = getattr(SdfBlock, 'const_value').offset
453
+ self._datatype = _np_datatypes[block.datatype]
454
+ totype = _ct_datatypes[block.datatype]
455
+ self._data = totype.from_buffer(block, offset).value
456
+
457
+
458
+ class BlockPlainVariable(Block):
459
+ def __init__(self, block):
460
+ super().__init__(block)
461
+ self._data = None
462
+
463
+ @property
464
+ def data(self):
465
+ """Block data contents"""
466
+ if self._data is None:
467
+ clib = self._handle._clib
468
+ clib.sdf_helper_read_data(self._handle, self._contents)
469
+ blen = np.dtype(self._datatype).itemsize
470
+ for d in self.dims:
471
+ blen *= d
472
+ array = self._numpy_from_buffer(self._contents.data, blen)
473
+ self._data = array.reshape(self.dims, order='F')
474
+ return self._data
475
+
476
+ @property
477
+ def grid(self):
478
+ """Associated mesh"""
479
+ return self._grid
480
+
481
+ @property
482
+ def grid_id(self):
483
+ """Associated mesh id"""
484
+ return self._contents.mesh_id.decode()
485
+
486
+ @property
487
+ def mult(self):
488
+ """Multiplication factor"""
489
+ return self._contents.mult
490
+
491
+ @property
492
+ def stagger(self):
493
+ """Grid stagger"""
494
+ return SdfStagger(self._contents.stagger)
495
+
496
+ @property
497
+ def units(self):
498
+ """Units of variable"""
499
+ return self._contents.units.decode()
500
+
501
+
502
+ class BlockPlainMesh(Block):
503
+ def __init__(self, block):
504
+ super().__init__(block)
505
+ self._data = None
506
+ self._units = tuple([block.dim_units[i].decode() for i in range(block.ndims)])
507
+ self._labels = tuple([block.dim_labels[i].decode() for i in range(block.ndims)])
508
+ self._mult = None
509
+ if bool(block.dim_mults):
510
+ self._mult = tuple(block.dim_mults[:block.ndims])
511
+ self._extents = tuple(block.extents[:2*block.ndims])
512
+
513
+ @property
514
+ def data(self):
515
+ """Block data contents"""
516
+ if self._data is None:
517
+ clib = self._handle._clib
518
+ clib.sdf_helper_read_data(self._handle, self._contents)
519
+ grids = []
520
+ for i, d in enumerate(self.dims):
521
+ blen = np.dtype(self._datatype).itemsize * d
522
+ array = self._numpy_from_buffer(self._contents.grids[i], blen)
523
+ grids.append(array)
524
+ self._data = tuple(grids)
525
+ return self._data
526
+
527
+ @property
528
+ def extents(self):
529
+ """Axis extents"""
530
+ return self._extents
531
+
532
+ @property
533
+ def geometry(self):
534
+ """Domain geometry"""
535
+ return SdfGeometry(self._contents.geometry)
536
+
537
+ @property
538
+ def labels(self):
539
+ """Axis labels"""
540
+ return self._labels
541
+
542
+ @property
543
+ def mult(self):
544
+ """Multiplication factor"""
545
+ return self._mult
546
+
547
+ @property
548
+ def units(self):
549
+ """Units of variable"""
550
+ return self._units
551
+
552
+
553
+ class BlockPointMesh(BlockPlainMesh):
554
+ def __init__(self, block):
555
+ super().__init__(block)
556
+
557
+ @property
558
+ def species_id(self):
559
+ """Species ID"""
560
+ return self._contents.material_id.decode()
561
+
562
+
563
+ class BlockPointVariable(BlockPlainVariable):
564
+ def __init__(self, block):
565
+ super().__init__(block)
566
+
567
+ @property
568
+ def species_id(self):
569
+ """Species ID"""
570
+ return self._contents.material_id.decode()
571
+
572
+
573
+ class BlockNameValue(Block):
574
+ def __init__(self, block):
575
+ super().__init__(block)
576
+ self._dims = (block.ndims,)
577
+ vals = {}
578
+ for n in range(block.ndims):
579
+ val = None
580
+ if block.datatype == SdfDataType.SDF_DATATYPE_CHARACTER:
581
+ p = ct.cast(block.data, ct.POINTER(ct.c_char_p))
582
+ val = p[n].decode()
583
+ else:
584
+ dt = _ct_datatypes[block.datatype]
585
+ val = ct.cast(block.data, ct.POINTER(dt))[n]
586
+ nid = get_member_name(block.material_names[n])
587
+ vals[nid] = val
588
+ self.__dict__[nid] = val
589
+ self._data = vals
590
+
591
+
592
+ class BlockArray(Block):
593
+ def __init__(self, block):
594
+ super().__init__(block)
595
+ self._data = None
596
+
597
+ @property
598
+ def data(self):
599
+ """Block data contents"""
600
+ if self._data is None:
601
+ clib = self._handle._clib
602
+ clib.sdf_helper_read_data(self._handle, self._contents)
603
+ blen = np.dtype(self._datatype).itemsize
604
+ for d in self.dims:
605
+ blen *= d
606
+ array = self._numpy_from_buffer(self._contents.data, blen)
607
+ self._data = array.reshape(self.dims, order='F')
608
+ return self._data
609
+
610
+
611
+ def get_run_info(block):
612
+ from datetime import datetime
613
+ r = ct.cast(block.data, ct.POINTER(RunInfo)).contents
614
+ ri = {}
615
+ ri['version'] = f"{r.version}.{r.revision}.{r.minor_rev}"
616
+ ri['commit_id'] = r.commit_id.decode()
617
+ ri['sha1sum'] = r.sha1sum.decode()
618
+ ri['compile_machine'] = r.compile_machine.decode()
619
+ ri['compile_flags'] = r.compile_flags.decode()
620
+ ri['compile_date'] = datetime.utcfromtimestamp(r.compile_date).strftime('%c')
621
+ ri['run_date'] = datetime.utcfromtimestamp(r.run_date).strftime('%c')
622
+ ri['io_data'] = datetime.utcfromtimestamp(r.io_date).strftime('%c')
623
+ return ri
624
+
625
+ def get_member_name(name):
626
+ sname = name.decode()
627
+ return ''.join([i if ((i >= "a" and i <= "z") or (i >= "A" and i <= "Z") \
628
+ or (i >= "0" and i <= "9")) else "_" \
629
+ for i in sname])
630
+
631
+ def read(filename, convert=False, derived=True):
632
+ """Reads the SDF data and returns a dictionary of NumPy arrays.
633
+
634
+ Parameters
635
+ ----------
636
+ filename : string
637
+ The name of the SDF file to open.
638
+ convert : bool, optional
639
+ Convert double precision data to single when reading file.
640
+ derived : bool, optional
641
+ Include derived variables in the data structure.
642
+ """
643
+
644
+ return BlockList(filename, convert, derived)
sdfr/__init__.py ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # Copyright 2022 University of Warwick, University of York
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ _module_name = "sdfr"
19
+
20
+ from .SDF import read
21
+ from .sdf_helper import *
22
+ from .loadlib import (
23
+ __library_commit_date__,
24
+ __library_commit_id__,
25
+ #__build_date__,
26
+ )
27
+
28
+ from importlib.metadata import version, PackageNotFoundError
29
+
30
+ try:
31
+ __version__ = version(_module_name)
32
+ except PackageNotFoundError:
33
+ __version__ = "2.6.12"
34
+
35
+ __all__ = [
36
+ "SDF",
37
+ "__library_commit_date__",
38
+ "__library_commit_id__",
39
+ "__version__",
40
+ #"__build_date__",
41
+ ]
sdfr/_commit_info.py ADDED
@@ -0,0 +1,2 @@
1
+ __commit_id__ = "43a6d14fadc2191a4ad9cd2029a5c3bf9e5fddbf"
2
+ __commit_date__ = "Mon Feb 17 14:29:41 2025 +0000"