fdsreader 1.2.8__tar.gz → 1.3.7__tar.gz

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.
Files changed (59) hide show
  1. {fdsreader-1.2.8 → fdsreader-1.3.7}/LICENSE +0 -0
  2. {fdsreader-1.2.8 → fdsreader-1.3.7}/MANIFEST.in +0 -0
  3. {fdsreader-1.2.8/fdsreader.egg-info → fdsreader-1.3.7}/PKG-INFO +2 -2
  4. {fdsreader-1.2.8 → fdsreader-1.3.7}/README.md +0 -0
  5. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/__init__.py +0 -0
  6. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/_version.py +1 -1
  7. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/bndf/ObstructionCollection.py +0 -0
  8. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/bndf/__init__.py +0 -0
  9. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/bndf/obstruction.py +7 -3
  10. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/bndf/utils.py +0 -0
  11. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/evac/EvacCollection.py +1 -0
  12. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/evac/__init__.py +0 -0
  13. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/evac/evacuation.py +1 -1
  14. fdsreader-1.3.7/fdsreader/export/__init__.py +3 -0
  15. fdsreader-1.3.7/fdsreader/export/obst_exporter.py +116 -0
  16. fdsreader-1.3.7/fdsreader/export/slcf_exporter.py +63 -0
  17. fdsreader-1.3.7/fdsreader/export/smoke3d_exporter.py +70 -0
  18. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/fds_classes/MeshCollection.py +0 -0
  19. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/fds_classes/__init__.py +0 -0
  20. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/fds_classes/mesh.py +21 -1
  21. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/fds_classes/surface.py +0 -0
  22. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/fds_classes/ventilation.py +0 -0
  23. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/geom/GeometryCollection.py +0 -0
  24. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/geom/__init__.py +0 -0
  25. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/geom/geometry.py +0 -0
  26. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/isof/IsosurfaceCollection.py +0 -0
  27. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/isof/__init__.py +0 -0
  28. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/isof/isosurface.py +0 -0
  29. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/part/ParticleCollection.py +0 -0
  30. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/part/__init__.py +0 -0
  31. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/part/particle.py +0 -0
  32. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/pl3d/Plot3DCollection.py +0 -0
  33. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/pl3d/__init__.py +0 -0
  34. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/pl3d/pl3d.py +6 -0
  35. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/settings.py +0 -0
  36. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/simulation.py +7 -7
  37. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/slcf/GeomSliceCollection.py +0 -0
  38. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/slcf/SliceCollection.py +1 -1
  39. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/slcf/__init__.py +0 -0
  40. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/slcf/geomslice.py +0 -0
  41. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/slcf/slice.py +67 -6
  42. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/smoke3d/Smoke3DCollection.py +1 -1
  43. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/smoke3d/__init__.py +0 -0
  44. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/smoke3d/smoke3d.py +4 -49
  45. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/utils/__init__.py +0 -0
  46. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/utils/data.py +0 -0
  47. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/utils/dimension.py +0 -0
  48. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/utils/extent.py +2 -2
  49. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/utils/fortran_data.py +0 -0
  50. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader/utils/misc.py +0 -0
  51. {fdsreader-1.2.8 → fdsreader-1.3.7/fdsreader.egg-info}/PKG-INFO +2 -2
  52. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader.egg-info/SOURCES.txt +4 -0
  53. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader.egg-info/dependency_links.txt +0 -0
  54. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader.egg-info/requires.txt +0 -0
  55. {fdsreader-1.2.8 → fdsreader-1.3.7}/fdsreader.egg-info/top_level.txt +0 -0
  56. fdsreader-1.3.7/requirements.txt +118 -0
  57. {fdsreader-1.2.8 → fdsreader-1.3.7}/setup.cfg +0 -0
  58. {fdsreader-1.2.8 → fdsreader-1.3.7}/setup.py +2 -2
  59. fdsreader-1.2.8/requirements.txt +0 -113
File without changes
File without changes
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fdsreader
3
- Version: 1.2.8
3
+ Version: 1.3.7
4
4
  Summary: Python reader for data generated by FDS.
5
- Home-page: https://github.com/JanVogelsang/fdsreader
5
+ Home-page: https://github.com/FireDynamics/fdsreader
6
6
  Author: FZJ IAS-7 (Prof. Dr. Lukas Arnold, Jan Vogelsang)
7
7
  Author-email: j.vogelsang@fz-juelich.de
8
8
  License: UNKNOWN
File without changes
@@ -7,5 +7,5 @@ Provides fdsreader version information.
7
7
 
8
8
  from incremental import Version
9
9
 
10
- __version__ = Version('fdsreader', 1, 2, 8)
10
+ __version__ = Version('fdsreader', 1, 3, 7)
11
11
  __all__ = ["__version__"]
@@ -149,7 +149,7 @@ class SubObstruction:
149
149
 
150
150
  :ivar extent: :class:`Extent` object containing 3-dimensional extent information.
151
151
  :ivar bound_indices: Indices used to define obstruction bounds in terms of mesh locations.
152
- :ivar side_surfaces: Tuple of six :class:`Surface`s for each side of the cuboid.
152
+ :ivar side_surfaces: Tuple of six :class:`Surface` s for each side of the cuboid.
153
153
  :ivar hide_times: List with points in time from when on the SubObstruction will be hidden.
154
154
  :ivar show_times: List with points in time from when on the SubObstruction will be shown.
155
155
  """
@@ -177,6 +177,10 @@ class SubObstruction:
177
177
  if not settings.LAZY_LOAD:
178
178
  _ = self._boundary_data[bid].data
179
179
 
180
+ @property
181
+ def has_boundary_data(self):
182
+ return len(self._boundary_data) != 0
183
+
180
184
  def get_data(self, quantity: Union[str, Quantity]):
181
185
  if type(quantity) == Quantity:
182
186
  quantity = quantity.name
@@ -304,7 +308,7 @@ class Obstruction:
304
308
  if type(quantity) == Quantity:
305
309
  quantity = quantity.name
306
310
 
307
- ret = [subobst.get_data(quantity) for subobst in self._subobstructions]
311
+ ret = [subobst.get_data(quantity) for subobst in self._subobstructions if subobst.has_boundary_data]
308
312
  if orientation == 0:
309
313
  return ret
310
314
  return [bndf for bndf in ret if orientation in bndf.data.keys()]
@@ -313,7 +317,7 @@ class Obstruction:
313
317
  def has_boundary_data(self):
314
318
  """Whether boundary data has been output in the simulation.
315
319
  """
316
- return len(self._subobstructions[0]._boundary_data) != 0
320
+ return any(subobst.has_boundary_data for subobst in self._subobstructions)
317
321
 
318
322
  def clear_cache(self):
319
323
  """Remove all data from the internal cache that has been loaded so far to free memory.
@@ -287,6 +287,7 @@ class EvacCollection(FDSDataCollection):
287
287
  def _load_eff_data(self):
288
288
  file_path = self._base_path + ".eff"
289
289
  if not os.path.exists(file_path):
290
+ self._eff = None
290
291
  return
291
292
 
292
293
  with open(file_path, 'rb') as infile:
@@ -66,7 +66,7 @@ class Evacuation:
66
66
  self.lower_bounds = {q.name: [] for q in self.quantities}
67
67
  self.upper_bounds = {q.name: [] for q in self.quantities}
68
68
 
69
- self._init_callback = None
69
+ self._init_callback = lambda: None
70
70
 
71
71
  @property
72
72
  def id(self):
@@ -0,0 +1,3 @@
1
+ from .smoke3d_exporter import export_smoke_raw
2
+ from .slcf_exporter import export_slcf_raw
3
+ from .obst_exporter import export_obst_raw
@@ -0,0 +1,116 @@
1
+ import os
2
+ from pathlib import Path
3
+ import numpy as np
4
+ from typing_extensions import Literal
5
+ from ..bndf import Obstruction
6
+ from ..bndf.utils import sort_patches_cartesian
7
+
8
+
9
+ def export_obst_raw(obst: Obstruction, output_dir: str, ordering: Literal['C', 'F'] = 'C'):
10
+ """Exports the 3d arrays to raw binary files with corresponding .yaml meta files.
11
+
12
+ :param smoke3d: The :class:`Smoke3D` object to export.
13
+ :param output_dir: The directory in which to save all files.
14
+ :param ordering: Whether to write the data in C or Fortran ordering.
15
+ """
16
+ from pathos.pools import ProcessPool as Pool
17
+ from multiprocess import Lock, Manager
18
+ filename_base = "obst-" + str(obst.id)
19
+ # Create all requested directories if they don't exist yet
20
+ Path(os.path.join(output_dir, filename_base + "-data")).mkdir(parents=True, exist_ok=True)
21
+
22
+ meta = {"BoundingBox": obst.bounding_box.as_list(), "QuantityNum": len(obst.quantities)}
23
+ m = Manager()
24
+ lock = m.Lock()
25
+ meta["Quantities"] = m.list()
26
+
27
+ def worker(quantity, bndf_data):
28
+ quantity_name = quantity.name.replace(" ", "_").replace(".", "-")
29
+ filename = filename_base + "_quantity-" + quantity_name + ".dat"
30
+
31
+ out = {"Quantity": quantity.name.replace(" ", "_").replace(".", "-"), "DataValMax": -100000.,
32
+ "DataValMin": 100000., "ScaleFactor": 1, "DataFile": os.path.join(filename_base + "-data", filename),
33
+ "Orientations": list()}
34
+ for bndf in bndf_data:
35
+ out["DataValMax"] = max(out["DataValMax"], np.max(bndf.upper_bounds))
36
+ out["DataValMin"] = min(out["DataValMin"], np.min(bndf.lower_bounds))
37
+ out["DataValMax"] = float(out["DataValMax"])
38
+ out["DataValMin"] = float(out["DataValMin"])
39
+ out["ScaleFactor"] = 255.0 / out["DataValMax"]
40
+
41
+ # Abort if no useful data is available
42
+ if meta[quantity]["DataValMax"] <= 0:
43
+ return
44
+
45
+ with open(os.path.join(output_dir, quantity_name, filename_base + "-data", filename), 'wb') as rawfile:
46
+ orientations = set()
47
+ for orientation in (-3, -2, -1, 1, 2, 3):
48
+ patches = list()
49
+ for bndf in bndf_data:
50
+ if orientation in bndf.data:
51
+ orientations.add(orientation)
52
+ patches.append(bndf.data[orientation])
53
+
54
+ if len(patches) == 0:
55
+ continue
56
+
57
+ # Combine patches to a single face for plotting
58
+ patches = sort_patches_cartesian(patches)
59
+
60
+ shape_dim1 = sum([patch_row[0].shape[0] for patch_row in patches])
61
+ shape_dim2 = sum([patch.shape[1] for patch in patches[0]])
62
+ n_t = patches[0][0].n_t # Number of timesteps
63
+
64
+ face = np.empty(shape=(n_t, shape_dim1, shape_dim2))
65
+ dim1_pos = 0
66
+ dim2_pos = 0
67
+ for patch_row in patches:
68
+ d1 = patch_row[0].shape[0]
69
+ for patch in patch_row:
70
+ d2 = patch.shape[1]
71
+ face[:, dim1_pos:dim1_pos + d1, dim2_pos:dim2_pos + d2] = patch.data
72
+ dim2_pos += d2
73
+ dim1_pos += d1
74
+ dim2_pos = 0
75
+
76
+ face = (face * meta["ScaleFactor"]).astype(np.uint8)
77
+
78
+ if abs(orientation) == 1:
79
+ spacing1 = (meta["BoundingBox"][3] - meta["BoundingBox"][2]) / face.shape[1]
80
+ spacing2 = (meta["BoundingBox"][5] - meta["BoundingBox"][4]) / face.shape[2]
81
+ elif abs(orientation) == 2:
82
+ spacing1 = (meta["BoundingBox"][1] - meta["BoundingBox"][0]) / face.shape[0]
83
+ spacing2 = (meta["BoundingBox"][5] - meta["BoundingBox"][4]) / face.shape[2]
84
+ else:
85
+ spacing1 = (meta["BoundingBox"][1] - meta["BoundingBox"][0]) / face.shape[0]
86
+ spacing2 = (meta["BoundingBox"][3] - meta["BoundingBox"][2]) / face.shape[1]
87
+
88
+
89
+ out["Orientations"].append({
90
+ "Orientation": orientation,
91
+ "MeshPos": f"{meta['BoundingBox'][0]:.6} {meta['BoundingBox'][2]:.6} {meta['BoundingBox'][4]:.6}",
92
+ "Spacing": f"{bndf_data[0].times[1] - bndf_data[0].times[0]:.6} {spacing1:.6} {spacing2:.6}",
93
+ "DimSize": f"{face.shape[2]} {face.shape[1]} {face.shape[2]}"
94
+ })
95
+
96
+ for d in face[:, [2, 0, 1]]: # Make time the first dimension so we can easily iterate over it
97
+ if ordering == 'F':
98
+ d = d.T
99
+ d.tofile(rawfile)
100
+
101
+ out["NumOrientations"] = len(orientations)
102
+
103
+ with lock:
104
+ meta["Quantities"].append(out)
105
+
106
+ worker_args = list()
107
+ for i, quantity in enumerate(obst.quantities):
108
+ bndf_data = obst.get_boundary_data(quantity)
109
+ worker_args.append((quantity, bndf_data))
110
+ Pool(8).map(lambda args: worker(*args), worker_args)
111
+
112
+ meta["Quantities"] = list(meta["Quantities"])
113
+
114
+ with open(os.path.join(output_dir, filename_base + ".yaml"), 'w') as metafile:
115
+ import yaml
116
+ yaml.dump(meta, metafile)
@@ -0,0 +1,63 @@
1
+ import os
2
+ from pathlib import Path
3
+ import numpy as np
4
+ from typing_extensions import Literal
5
+ from ..slcf import Slice
6
+
7
+
8
+ def export_slcf_raw(slc: Slice, output_dir: str, ordering: Literal['C', 'F'] = 'C'):
9
+ """Exports the 3d arrays to raw binary files with corresponding .yaml meta files.
10
+
11
+ :param slc: The :class:`Slice` object to export.
12
+ :param output_dir: The directory in which to save all files.
13
+ :param ordering: Whether to write the data in C or Fortran ordering.
14
+ """
15
+ from pathos.pools import ProcessPool as Pool
16
+ from multiprocess import Lock, Manager
17
+ slc2d = slc.type == '2D'
18
+ meta = {"DataValMax": float(slc.vmax), "DataValMin": float(slc.vmin), "ScaleFactor": 255. / (float(slc.vmax) - float(slc.vmin)),
19
+ "MeshNum": len(slc.subslices), "Quantity": slc.quantity.name}
20
+
21
+ filename_base = ("slice" + ("2D-" if slc2d else "3D-") + slc.id.lower()).replace(" ", "_").replace(".", "-")
22
+ # Create all requested directories if they don't exist yet
23
+ Path(os.path.join(output_dir, filename_base + "-data")).mkdir(parents=True, exist_ok=True)
24
+
25
+ m = Manager()
26
+ meta["Meshes"] = m.list()
27
+ lock = m.Lock()
28
+
29
+ def worker(mesh, subslice):
30
+ mesh_id = mesh.id.replace(" ", "_").replace(".", "-")
31
+ filename = filename_base + "_mesh-" + mesh_id + ".dat"
32
+
33
+ data = ((subslice.data - meta["DataValMin"]) * meta["ScaleFactor"]).astype(np.uint8)
34
+ shape = data.shape
35
+ if slc2d:
36
+ shape = shape[:subslice.orientation] + (1,) + shape[subslice.orientation:]
37
+
38
+ with open(os.path.join(output_dir, filename_base + "-data", filename), 'wb') as rawfile:
39
+ for d in data:
40
+ if ordering == 'F':
41
+ d = d.T
42
+ d.tofile(rawfile)
43
+
44
+ spacing = [slc.times[1] - slc.times[0],
45
+ mesh.coordinates['x'][1] - mesh.coordinates['x'][0],
46
+ mesh.coordinates['y'][1] - mesh.coordinates['y'][0],
47
+ mesh.coordinates['z'][1] - mesh.coordinates['z'][0]]
48
+ with lock:
49
+ meta["Meshes"].append({
50
+ "Mesh": mesh_id,
51
+ "DataFile": os.path.join(filename_base + "-data", filename),
52
+ "MeshPos": f"{mesh.coordinates['x'][0]:.6} {mesh.coordinates['y'][0]:.6} {mesh.coordinates['z'][0]:.6}",
53
+ "Spacing": f"{spacing[0]:.6} {spacing[1]:.6} {spacing[2]:.6} {spacing[3]:.6}",
54
+ "DimSize": f"{shape[0]} {shape[1]} {shape[2]} {shape[3]}"
55
+ })
56
+
57
+ Pool(8).map(lambda args: worker(*args), list(slc._subslices.items()))
58
+
59
+ meta["Meshes"] = list(meta["Meshes"])
60
+
61
+ with open(os.path.join(output_dir, filename_base + ".yaml"), 'w') as metafile:
62
+ import yaml
63
+ yaml.dump(meta, metafile)
@@ -0,0 +1,70 @@
1
+ import os
2
+ from pathlib import Path
3
+ import numpy as np
4
+ from typing_extensions import Literal
5
+ from ..smoke3d import Smoke3D
6
+
7
+
8
+ def export_smoke_raw(smoke3d: Smoke3D, output_dir: str, ordering: Literal['C', 'F'] = 'C'):
9
+ """Exports the 3d arrays to raw binary files with corresponding .yaml meta files.
10
+
11
+ :param smoke3d: The :class:`Smoke3D` object to export.
12
+ :param output_dir: The directory in which to save all files.
13
+ :param ordering: Whether to write the data in C or Fortran ordering.
14
+ """
15
+ from pathos.pools import ProcessPool as Pool
16
+ from multiprocess import Lock, Manager
17
+ filename_base = ("smoke-" + smoke3d.quantity.name.lower()).replace(" ", "_").replace(".", "-")
18
+ # Create all requested directories if they don't exist yet
19
+ Path(os.path.join(output_dir, filename_base + "-data")).mkdir(parents=True, exist_ok=True)
20
+
21
+ meta = {"DataValMax": -100000., "DataValMin": 100000., "ScaleFactor": 1, "MeshNum": len(smoke3d.subsmokes),
22
+ "Quantity": smoke3d.quantity.name}
23
+
24
+ for subsmoke in smoke3d._subsmokes.values():
25
+ meta["DataValMax"] = max(meta["DataValMax"], np.max(subsmoke.data))
26
+ meta["DataValMin"] = min(meta["DataValMin"], np.min(subsmoke.data))
27
+ meta["DataValMax"] = float(meta["DataValMax"])
28
+ meta["DataValMin"] = float(meta["DataValMin"])
29
+ meta["ScaleFactor"] = 255.0 / meta["DataValMax"]
30
+
31
+ # Abort if no useful data is available
32
+ if meta["DataValMax"] <= 0:
33
+ return
34
+
35
+ m = Manager()
36
+ meta["Meshes"] = m.list()
37
+ lock = m.Lock()
38
+
39
+ def worker(mesh, subsmoke):
40
+ mesh_id = mesh.id.replace(" ", "_").replace(".", "-")
41
+ filename = filename_base + "_mesh-" + mesh_id + ".dat"
42
+
43
+ data = (subsmoke.data * meta["ScaleFactor"]).astype(np.uint8)
44
+
45
+ with open(os.path.join(output_dir, filename_base + "-data", filename), 'wb') as rawfile:
46
+ for d in data:
47
+ if ordering == 'F':
48
+ d = d.T
49
+ d.tofile(rawfile)
50
+
51
+ spacing = [smoke3d.times[1] - smoke3d.times[0],
52
+ mesh.coordinates['x'][1] - mesh.coordinates['x'][0],
53
+ mesh.coordinates['y'][1] - mesh.coordinates['y'][0],
54
+ mesh.coordinates['z'][1] - mesh.coordinates['z'][0]]
55
+ with lock:
56
+ meta["Meshes"].append({
57
+ "Mesh": mesh_id,
58
+ "DataFile": os.path.join(filename_base + "-data", filename),
59
+ "MeshPos": f"{mesh.coordinates['x'][0]:.6} {mesh.coordinates['y'][0]:.6} {mesh.coordinates['z'][0]:.6}",
60
+ "Spacing": f"{spacing[0]:.6} {spacing[1]:.6} {spacing[2]:.6} {spacing[3]:.6}",
61
+ "DimSize": f"{data.shape[0]} {data.shape[1]} {data.shape[2]} {data.shape[3]}"
62
+ })
63
+
64
+ Pool(8).map(lambda args: worker(*args), list(smoke3d._subsmokes.items()))
65
+
66
+ meta["Meshes"] = list(meta["Meshes"])
67
+
68
+ with open(os.path.join(output_dir, filename_base + ".yaml"), 'w') as metafile:
69
+ import yaml
70
+ yaml.dump(meta, metafile)
@@ -68,7 +68,7 @@ class Mesh:
68
68
  as obstructions may be hidden as specific points in time.
69
69
  """
70
70
  orientation = subslice.orientation
71
- value = subslice.extent[orientation - 1][0]
71
+ value = subslice.extent[orientation][0]
72
72
  cell_centered = subslice.cell_centered
73
73
 
74
74
  slc_index = self.coordinate_to_index((value,), dimension=(orientation,), cell_centered=cell_centered)[0]
@@ -87,6 +87,7 @@ class Mesh:
87
87
  :param coordinate: Tuple of 3 floats. If the dimension parameter is supplied, up to 2
88
88
  dimensions can be left out from the tuple.
89
89
  :param dimension: The dimensions in which to return the indices (1=x, 2=y, 3=z).
90
+ :param cell_centered: Instead of finding the nearest point on the mesh, find the center of the nearest cell.
90
91
  """
91
92
  # Convert possible integer input to chars
92
93
  dimension = tuple(('x', 'y', 'z')[dim - 1] if type(dim) == int else dim for dim in dimension)
@@ -105,6 +106,25 @@ class Mesh:
105
106
  ret.append(idx)
106
107
  return tuple(ret)
107
108
 
109
+ def get_nearest_coordinate(self, coordinate: Tuple[float, ...],
110
+ dimension: Tuple[Literal[1, 2, 3, 'x', 'y', 'z'], ...] = ('x', 'y', 'z'),
111
+ cell_centered=False) -> Tuple[float, ...]:
112
+ """Finds the nearest point in the mesh's grid.
113
+
114
+ :param coordinate: Tuple of 3 floats. If the dimension parameter is supplied, up to 2
115
+ dimensions can be left out from the tuple.
116
+ :param dimension: The dimensions in which to return the indices (1=x, 2=y, 3=z).
117
+ :param cell_centered: Instead of finding the nearest point on the mesh, find the center of the nearest cell.
118
+ """
119
+ indices = self.coordinate_to_index(coordinate, dimension, cell_centered)
120
+ ret = list()
121
+ for i, dim in enumerate(dimension):
122
+ coords = self.coordinates[dim]
123
+ if cell_centered:
124
+ coords = coords[:-1] + (coords[1] - coords[0]) / 2
125
+ ret.append(coords[indices[i]])
126
+ return tuple(ret)
127
+
108
128
  def _add_patches(self, bid: int, cell_centered: bool, quantity: str, short_name: str, unit: str,
109
129
  patches: List[Patch], times: np.ndarray, n_t: int, lower_bounds: np.ndarray,
110
130
  upper_bounds: np.ndarray):
@@ -88,6 +88,12 @@ class Plot3D(np.lib.mixins.NDArrayOperatorsMixin):
88
88
  """
89
89
  return self._subplots[mesh]
90
90
 
91
+ def get_quantity_index(self, quantity: str):
92
+ """Returns the index of the quantity for the fourth dimension of the data array.
93
+ """
94
+ return next(i for i, q in enumerate(self.quantities) if
95
+ q.name.lower() == quantity.lower() or q.short_name.lower() == quantity.lower())
96
+
91
97
  @implements(np.mean)
92
98
  def mean(self) -> np.ndarray:
93
99
  """Calculates the mean for each quantity individually of the whole Plot3D.
@@ -43,8 +43,8 @@ class Simulation:
43
43
  :ivar isosurfaces: All defined isosurfaces combined into a :class:`IsosurfaceCollection`.
44
44
  :ivar particles: All defined particles combined into a :class:`ParticleCollection`.
45
45
  :ivar evacs: All defined evacuations combined into a :class:`EvacCollection`.
46
- :ivar devices: List containing all :class:`Device`s defined in this simulation.
47
- :ivar profiles: Dictionary mapping profile ids to the corresponding :class:`Profile`s defined in this simulation.
46
+ :ivar devices: List containing all :class:`Device` s defined in this simulation.
47
+ :ivar profiles: Dictionary mapping profile ids to the corresponding :class:`Profile` s defined in this simulation.
48
48
  :ivar geoms: List containing all geometries (:class:`Geometry`) defined in this simulation.
49
49
  :ivar geom_data: All geometry data by quantity combined into a :class:`GeometryCollection`.
50
50
  :ivar cpu: Dictionary mapping .csv header keys to numpy arrays containing cpu data.
@@ -924,7 +924,7 @@ class Simulation:
924
924
  def _load_DEVC_data(self, file_path: str):
925
925
  with open(file_path, 'r') as infile:
926
926
  units = infile.readline().split(',')
927
- names = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',')]
927
+ names = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',"')]
928
928
  values = np.genfromtxt(infile, delimiter=',', dtype=np.float32, autostrip=True)
929
929
  for k in range(len(names)):
930
930
  devc = self.devices[names[k]]
@@ -938,7 +938,7 @@ class Simulation:
938
938
  if os.path.exists(line_path):
939
939
  with open(line_path, 'r') as infile:
940
940
  units = infile.readline()
941
- names = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',')]
941
+ names = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',"')]
942
942
  data = np.genfromtxt(infile, delimiter=',', dtype=np.float32, autostrip=True)
943
943
  for k, key in enumerate(names):
944
944
  if key in self.devices:
@@ -953,7 +953,7 @@ class Simulation:
953
953
  def _load_HRR_data(self, file_path: str) -> Dict[str, np.ndarray]:
954
954
  with open(file_path, 'r') as infile:
955
955
  infile.readline()
956
- keys = infile.readline().split(',')
956
+ keys = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',')]
957
957
  values = np.genfromtxt(infile, delimiter=',', dtype=np.float32, autostrip=True)
958
958
  return self._transform_csv_data(keys, values, [np.float32] * len(keys))
959
959
 
@@ -961,7 +961,7 @@ class Simulation:
961
961
  def _load_step_data(self, file_path: str) -> Dict[str, np.ndarray]:
962
962
  with open(file_path, 'r') as infile:
963
963
  infile.readline()
964
- keys = infile.readline().split(',')
964
+ keys = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',')]
965
965
  dtypes = [np.float32] * len(keys)
966
966
  dtypes[0] = int
967
967
  dtypes[1] = np.dtype("datetime64[ms]")
@@ -973,7 +973,7 @@ class Simulation:
973
973
  file_path = os.path.join(self.root_path, self.chid + "_cpu.csv")
974
974
  if os.path.exists(file_path):
975
975
  with open(file_path, 'r') as infile:
976
- keys = infile.readline().split(",")
976
+ keys = [name.replace('"', '').replace('\n', '').strip() for name in infile.readline().split(',')]
977
977
  dtypes = [np.float32] * len(keys)
978
978
  dtypes[0] = int
979
979
  values = np.genfromtxt(infile, delimiter=',', dtype=dtypes, autostrip=True)
@@ -16,7 +16,7 @@ class SliceCollection(FDSDataCollection):
16
16
 
17
17
  @property
18
18
  def quantities(self) -> List[Quantity]:
19
- return list({slc.name for slc in self})
19
+ return list({slc.quantity.name for slc in self})
20
20
 
21
21
  def filter_by_quantity(self, quantity: Union[str, Quantity]):
22
22
  """Filters all slices by a specific quantity.
@@ -58,7 +58,7 @@ class SubSlice:
58
58
  return shape
59
59
 
60
60
  @property
61
- def orientation(self) -> Literal[1, 2, 3]:
61
+ def orientation(self) -> Literal[0, 1, 2, 3]:
62
62
  """Orientation [1,2,3] of the slice in case it is 2D, 0 otherwise.
63
63
  """
64
64
  return self._parent_slice.orientation
@@ -147,7 +147,7 @@ class Slice(np.lib.mixins.NDArrayOperatorsMixin):
147
147
  """Slice file data container including metadata. Consists of multiple subslices, one for each
148
148
  mesh the slice cuts through. In case a slice cuts right through the border of two meshes, the generated data
149
149
  would be duplicated. For edge-centered slices a random of both generated slices will be discarded as the data
150
- is completely identical. For cell-centered slices the data of both slices will be saved as :class:`SubSlice`s,
150
+ is completely identical. For cell-centered slices the data of both slices will be saved as :class:`SubSlice` s,
151
151
  therefore it might seem as if all slices would be duplicated, in reality however the slices might contain
152
152
  different data.
153
153
 
@@ -258,8 +258,7 @@ class Slice(np.lib.mixins.NDArrayOperatorsMixin):
258
258
  return list(self._subslices.values())
259
259
 
260
260
  @property
261
- def extent_dirs(self) -> Tuple[
262
- Literal['x', 'y', 'z'], Literal['x', 'y', 'z'], Literal['x', 'y', 'z']]:
261
+ def extent_dirs(self) -> Tuple[Literal['x', 'y', 'z'], Literal['x', 'y', 'z'], Literal['x', 'y', 'z']]:
263
262
  """The directions in which there is an extent. All three dimensions in case the slice is 3D.
264
263
  """
265
264
  ior = self.orientation
@@ -333,8 +332,67 @@ class Slice(np.lib.mixins.NDArrayOperatorsMixin):
333
332
  for subslice in self._subslices.values():
334
333
  subslice.clear_cache()
335
334
 
335
+ def get_2d_slice_from_3d(self, slice_direction: Literal['x', 'y', 'z', 1, 2, 3], value: float):
336
+ """Creates a 2D-Slice from a 3D-Slice by slicing the Slice.
337
+ :param slice_direction: The direction in which to cut through the slice.
338
+ :param value: The position at which to start cutting through the slice.
339
+ """
340
+ if type(slice_direction) == str:
341
+ slice_dim = {'x': 1, 'y': 2, 'z': 3}[slice_direction]
342
+ else:
343
+ slice_dim = slice_direction
344
+ slice_direction = ('x', 'y', 'z')[slice_dim - 1]
345
+ new_slice = deepcopy(self)
346
+
347
+ to_remove = list()
348
+ for mesh in new_slice._subslices.keys():
349
+ subslc = new_slice._subslices[mesh]
350
+ # Check if the new slice cuts through the subslice
351
+ cut_index = mesh.coordinate_to_index((value,), (slice_direction,),
352
+ cell_centered=self.cell_centered)
353
+ cut_value = mesh.get_nearest_coordinate((value,), (slice_direction,),
354
+ cell_centered=self.cell_centered)[0]
355
+ if mesh.coordinates[slice_direction][0] <= value <= mesh.coordinates[slice_direction][-1] and subslc.extent[slice_dim - 1][0] <= cut_value <= subslc.extent[slice_dim - 1][1]:
356
+ shape = subslc.dimension.shape(cell_centered=self.cell_centered)
357
+ indices = [slice(subslc.n_t)]
358
+
359
+ if subslc.dimension.x == 1 or subslc.dimension.y == 1 or subslc.dimension.z == 1:
360
+ indices.extend((slice(shape[0]), slice(shape[1])))
361
+ else:
362
+ indices.extend((slice(shape[0]), slice(shape[1]), slice(shape[2])))
363
+ indices[slice_dim - 1] = slice(cut_index[0], cut_index[0] + 1, 1)
364
+
365
+ subslc._data = subslc.data[tuple(indices)]
366
+ for direction in subslc.vector_filenames.keys():
367
+ subslc._vector_data[direction] = subslc.vector_data[direction][tuple(indices)]
368
+ subslc.extent._extents[slice_dim - 1] = (0, 0)
369
+ else:
370
+ to_remove.append(mesh)
371
+
372
+ for mesh in to_remove:
373
+ del new_slice._subslices[mesh]
374
+
375
+ vals = new_slice._subslices.values()
376
+ new_slice.extent = Extent(min(vals, key=lambda e: e.extent.x_start).extent.x_start,
377
+ max(vals, key=lambda e: e.extent.x_end).extent.x_end,
378
+ min(vals, key=lambda e: e.extent.y_start).extent.y_start,
379
+ max(vals, key=lambda e: e.extent.y_end).extent.y_end,
380
+ min(vals, key=lambda e: e.extent.z_start).extent.z_start,
381
+ max(vals, key=lambda e: e.extent.z_end).extent.z_end)
382
+
383
+ if new_slice.extent.x_start == new_slice.extent.x_end:
384
+ new_slice.orientation = 1
385
+ elif new_slice.extent.y_start == new_slice.extent.y_end:
386
+ new_slice.orientation = 2
387
+ elif new_slice.extent.z_start == new_slice.extent.z_end:
388
+ new_slice.orientation = 3
389
+ else:
390
+ new_slice.orientation = 0
391
+
392
+ return new_slice
393
+
336
394
  def sort_subslices_cartesian(self):
337
- """Returns all subslices sorted in cartesian coordinates (2D-slices only).
395
+ """Returns all subslices sorted in cartesian coordinates.
338
396
  """
339
397
  slices = list(self._subslices.values())
340
398
  slices_cart = [[slices[0]]]
@@ -403,6 +461,9 @@ class Slice(np.lib.mixins.NDArrayOperatorsMixin):
403
461
  return slc_array
404
462
 
405
463
  def to_global_nonuniform(self) -> np.ndarray:
464
+ """Creates a global 2D-numpy ndarray from all subslices (2D-slices only).
465
+ Beware, this method might create sparse np-arrays that consume lots of memory.
466
+ """
406
467
  # The global grid will use the finest mesh as base and duplicate values of the coarser meshes
407
468
  # Therefore we first find the finest mesh and calculate the step size in each dimension
408
469
  coords = self.coordinates
@@ -437,7 +498,7 @@ class Slice(np.lib.mixins.NDArrayOperatorsMixin):
437
498
  end_idx[dim] = int((mesh.coordinates[dim][-1] - start_coordinates[dim]) / step_sizes[dim]) + n_repeat
438
499
 
439
500
  if n_repeat > 1:
440
- slc_data = np.repeat(slc_data, n_repeat, axis=axis+1)
501
+ slc_data = np.repeat(slc_data, n_repeat, axis=axis + 1)
441
502
 
442
503
  grid[:, start_idx['x']: end_idx['x'], start_idx['y']: end_idx['y'],
443
504
  start_idx['z']: end_idx['z']] = slc_data.reshape(
@@ -6,7 +6,7 @@ from fdsreader.utils.data import FDSDataCollection, Quantity
6
6
 
7
7
  class Smoke3DCollection(FDSDataCollection):
8
8
  """Collection of :class:`Smoke3D` objects. Offers extensive functionality for filtering and
9
- using Smoke3Ds as well as its subclasses such as :class:`SubSmoke3D`.
9
+ using Smoke3Ds as well as its subclasses such as :class:`SubSmoke3D` .
10
10
  """
11
11
 
12
12
  def __init__(self, *smoke3ds: Iterable[Smoke3D]):
@@ -52,7 +52,7 @@ class SubSmoke3D:
52
52
  nx, ny, nz = int(header[3]), int(header[5]), int(header[7])
53
53
  data_shape = (nx + 1, ny + 1, nz + 1)
54
54
 
55
- self._data = np.empty((self.times.size,) + data_shape)
55
+ self._data = np.empty((self.times.size,) + data_shape, dtype=np.float32)
56
56
 
57
57
  for t in range(self.times.size):
58
58
  fdtype.read(infile, fdtype.FLOAT, 1) # Skip time value
@@ -127,54 +127,9 @@ class Smoke3D(np.lib.mixins.NDArrayOperatorsMixin):
127
127
  """
128
128
  return self._subsmokes[mesh]
129
129
 
130
- def export_raw(self, output_dir: str, bytesize: int, ordering: Literal['C', 'F'] = 'C'):
131
- """Exports the 3d arrays to raw binary files with corresponding .yaml meta files.
132
-
133
- :param output_dir: The directory in which to save all files.
134
- :param bytesize: The number of bytes used to save the data.
135
- :param ordering: Whether to write the data in C or Fortran ordering.
136
- """
137
- if bytesize == 1:
138
- dtype = np.uint8
139
- dtype_str = "uchar"
140
- elif bytesize == 2:
141
- dtype = np.uint16
142
- dtype_str = "ushort"
143
- else:
144
- dtype = np.uint32
145
- dtype_str = "uint"
146
-
147
- meta = {"DataType": dtype_str, "Meshes": str(len(self._subsmokes)), "MeshData": list()}
148
-
149
- filename_base = "smoke-" + self.quantity.name.lower()
150
- for mesh, subsmoke in self._subsmokes.items():
151
- filename = filename_base + "_mesh-" + mesh.id
152
- filename = filename.replace(" ", "_").replace(".", "-")
153
- filename += ".dat"
154
-
155
- data = subsmoke.data.astype(dtype)
156
-
157
- with open(os.path.join(output_dir, filename), 'wb') as rawfile:
158
- for d in data:
159
- if ordering == 'F':
160
- d = d.T
161
- d.tofile(rawfile)
162
-
163
- spacing = [self.times[1] - self.times[0],
164
- mesh.coordinates['x'][1] - mesh.coordinates['x'][0],
165
- mesh.coordinates['y'][1] - mesh.coordinates['y'][0],
166
- mesh.coordinates['z'][1] - mesh.coordinates['z'][0]]
167
- meta["MeshData"].append({
168
- "Mesh": mesh.id.replace(" ", "_").replace(".", "-"),
169
- "DataFile": filename,
170
- "MeshPos": f"{mesh.coordinates['x'][0]:.6} {mesh.coordinates['y'][0]:.6} {mesh.coordinates['z'][0]:.6}",
171
- "Spacing": f"{spacing[0]:.6} {spacing[1]:.6} {spacing[2]:.6} {spacing[3]:.6}",
172
- "DimSize": f"{subsmoke.data.shape[0]} {subsmoke.data.shape[1]} {subsmoke.data.shape[2]} {subsmoke.data.shape[3]}"
173
- })
174
-
175
- import yaml
176
- with open(os.path.join(output_dir, filename_base + ".yaml"), 'w') as metafile:
177
- yaml.dump(meta, metafile)
130
+ @property
131
+ def subsmokes(self):
132
+ return self._subsmokes.items()
178
133
 
179
134
  @property
180
135
  def vmax(self):
@@ -30,14 +30,14 @@ class Extent:
30
30
  self.y_start, self.y_end,
31
31
  self.z_start, self.z_end)
32
32
 
33
- def __getitem__(self, item: Union[int, Literal['x', 'y', 'z']]):
33
+ def __getitem__(self, item: Union[Literal['x', 'y', 'z', 1, 2, 3]]):
34
34
  if item == 'x':
35
35
  return self.x_start, self.x_end
36
36
  elif item == 'y':
37
37
  return self.y_start, self.y_end
38
38
  elif item == 'z':
39
39
  return self.z_start, self.z_end
40
- return self._extents[item]
40
+ return self._extents[item - 1]
41
41
 
42
42
  @property
43
43
  def x_start(self):
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fdsreader
3
- Version: 1.2.8
3
+ Version: 1.3.7
4
4
  Summary: Python reader for data generated by FDS.
5
- Home-page: https://github.com/JanVogelsang/fdsreader
5
+ Home-page: https://github.com/FireDynamics/fdsreader
6
6
  Author: FZJ IAS-7 (Prof. Dr. Lukas Arnold, Jan Vogelsang)
7
7
  Author-email: j.vogelsang@fz-juelich.de
8
8
  License: UNKNOWN
@@ -19,6 +19,10 @@ fdsreader/bndf/utils.py
19
19
  fdsreader/evac/EvacCollection.py
20
20
  fdsreader/evac/__init__.py
21
21
  fdsreader/evac/evacuation.py
22
+ fdsreader/export/__init__.py
23
+ fdsreader/export/obst_exporter.py
24
+ fdsreader/export/slcf_exporter.py
25
+ fdsreader/export/smoke3d_exporter.py
22
26
  fdsreader/fds_classes/MeshCollection.py
23
27
  fdsreader/fds_classes/__init__.py
24
28
  fdsreader/fds_classes/mesh.py
@@ -0,0 +1,118 @@
1
+ alabaster~=0.7.12
2
+ appdirs~=1.4.4
3
+ argon2-cffi~=20.1.0
4
+ async-generator~=1.10
5
+ attrs~=20.3.0
6
+ autodocsumm~=0.2.2
7
+ Automat~=20.2.0
8
+ Babel~=2.9.0
9
+ backcall~=0.2.0
10
+ bcrypt~=3.2.0
11
+ bleach~=3.3.0
12
+ brotlipy~=0.7.0
13
+ certifi~=2020.12.5
14
+ cffi~=1.14.5
15
+ chardet~=4.0.0
16
+ click~=7.1.2
17
+ colorama~=0.4.4
18
+ constantly~=15.1.0
19
+ cryptography~=3.4.7
20
+ cycler~=0.10.0
21
+ decorator~=5.0.6
22
+ defusedxml~=0.7.1
23
+ docutils~=0.16
24
+ entrypoints~=0.3
25
+ environment-kernels~=1.1.1
26
+ hyperlink~=21.0.0
27
+ idna~=2.10
28
+ imageio~=2.9.0
29
+ imageio-ffmpeg~=0.4.3
30
+ imagesize~=1.2.0
31
+ importlib-metadata~=3.10.0
32
+ incremental~=21.3.0
33
+ ipykernel~=5.3.4
34
+ ipython~=7.22.0
35
+ ipython-genutils~=0.2.0
36
+ jedi~=0.17.0
37
+ Jinja2~=2.11.3
38
+ jsonschema~=3.2.0
39
+ jupyter-client~=6.1.12
40
+ jupyter-core~=4.7.1
41
+ jupyterlab-pygments~=0.1.2
42
+ kiwisolver~=1.3.1
43
+ MarkupSafe~=1.1.1
44
+ matplotlib~=3.4.1
45
+ meshio~=4.3.13
46
+ mistune~=0.8.4
47
+ mkl-fft~=1.3.0
48
+ mkl-random~=1.1.1
49
+ mkl-service~=2.3.0
50
+ nbclient~=0.5.3
51
+ nbconvert~=6.0.7
52
+ nbformat~=5.1.3
53
+ nbsphinx~=0.8.3
54
+ nest-asyncio~=1.5.1
55
+ notebook~=6.3.0
56
+ numpy~=1.20.2
57
+ olefile~=0.46
58
+ packaging~=20.9
59
+ pandocfilters~=1.4.3
60
+ parso~=0.8.2
61
+ pickleshare~=0.7.5
62
+ Pillow~=8.2.0
63
+ pip~=21.0.1
64
+ prometheus-client~=0.10.1
65
+ prompt-toolkit~=3.0.17
66
+ pyasn1~=0.4.8
67
+ pyasn1-modules~=0.2.8
68
+ pycparser~=2.20
69
+ Pygments~=2.8.1
70
+ PyHamcrest~=2.0.2
71
+ pyOpenSSL~=20.0.1
72
+ pyparsing~=2.4.7
73
+ pyrsistent~=0.17.3
74
+ PySocks~=1.7.1
75
+ python-dateutil~=2.8.1
76
+ pytz~=2021.1
77
+ pyvista~=0.29.1
78
+ pywin32~=227
79
+ pywinpty~=0.5.7
80
+ pyzmq~=20.0.0
81
+ requests~=2.25.1
82
+ rise~=5.7.1
83
+ scooby~=0.5.7
84
+ Send2Trash~=1.5.0
85
+ service-identity~=18.1.0
86
+ setuptools~=58.0.0
87
+ six~=1.15.0
88
+ snowballstemmer~=2.1.0
89
+ Sphinx~=3.5.4
90
+ sphinx-rtd-theme~=0.5.2
91
+ sphinxcontrib-applehelp~=1.0.2
92
+ sphinxcontrib-devhelp~=1.0.2
93
+ sphinxcontrib-htmlhelp~=1.0.3
94
+ sphinxcontrib-jsmath~=1.0.1
95
+ sphinxcontrib-qthelp~=1.0.3
96
+ sphinxcontrib-serializinghtml~=1.1.4
97
+ terminado~=0.9.4
98
+ testpath~=0.4.4
99
+ tornado~=6.1
100
+ traitlets~=5.0.5
101
+ transforms3d~=0.3.1
102
+ Twisted~=21.2.0
103
+ twisted-iocpsupport~=1.0.1
104
+ typing-extensions~=3.7.4.3
105
+ urllib3~=1.26.4
106
+ vtk~=9.0.1
107
+ wcwidth~=0.2.5
108
+ webencodings~=0.5.1
109
+ wheel~=0.36.2
110
+ win-inet-pton~=1.1.0
111
+ wincertstore~=0.2
112
+ pyyaml~=5.4.1
113
+ zipp~=3.4.1
114
+ zope.interface~=5.3.0
115
+ pyvistaqt~=0.4.0
116
+ typing_extensions~=3.7.4.3
117
+ pathos~=0.2.8
118
+ multiprocess~=0.70.12.2
File without changes
@@ -4,7 +4,7 @@ import setuptools
4
4
 
5
5
  base_dir = os.path.dirname(os.path.realpath(__file__))
6
6
 
7
- with open(os.path.join(base_dir, "README.md"), 'r') as f:
7
+ with open(os.path.join(base_dir, "README.md"), 'r', encoding="utf-8") as f:
8
8
  long_description = f.read()
9
9
 
10
10
  setuptools.setup(
@@ -16,7 +16,7 @@ setuptools.setup(
16
16
  description="Python reader for data generated by FDS.",
17
17
  long_description=long_description,
18
18
  long_description_content_type="text/markdown",
19
- url="https://github.com/JanVogelsang/fdsreader",
19
+ url="https://github.com/FireDynamics/fdsreader",
20
20
  packages=setuptools.find_packages(),
21
21
  classifiers=[
22
22
  "Programming Language :: Python :: 3",
@@ -1,113 +0,0 @@
1
- alabaster==0.7.12
2
- appdirs==1.4.4
3
- argon2-cffi==20.1.0
4
- async-generator==1.10
5
- attrs==20.3.0
6
- autodocsumm==0.2.2
7
- Automat==20.2.0
8
- Babel==2.9.0
9
- backcall==0.2.0
10
- bcrypt==3.2.0
11
- bleach==3.3.0
12
- brotlipy==0.7.0
13
- certifi==2020.12.5
14
- cffi==1.14.5
15
- chardet==4.0.0
16
- click==7.1.2
17
- colorama==0.4.4
18
- constantly==15.1.0
19
- cryptography==3.4.7
20
- cycler==0.10.0
21
- decorator==5.0.6
22
- defusedxml==0.7.1
23
- docutils==0.16
24
- entrypoints==0.3
25
- environment-kernels==1.1.1
26
- hyperlink==21.0.0
27
- idna==2.10
28
- imageio==2.9.0
29
- imageio-ffmpeg==0.4.3
30
- imagesize==1.2.0
31
- importlib-metadata==3.10.0
32
- incremental==21.3.0
33
- ipykernel==5.3.4
34
- ipython==7.22.0
35
- ipython-genutils==0.2.0
36
- jedi==0.17.0
37
- Jinja2==2.11.3
38
- jsonschema==3.2.0
39
- jupyter-client==6.1.12
40
- jupyter-core==4.7.1
41
- jupyterlab-pygments==0.1.2
42
- kiwisolver==1.3.1
43
- MarkupSafe==1.1.1
44
- matplotlib==3.4.1
45
- meshio==4.3.13
46
- mistune==0.8.4
47
- mkl-fft==1.3.0
48
- mkl-random==1.1.1
49
- mkl-service==2.3.0
50
- nbclient==0.5.3
51
- nbconvert==6.0.7
52
- nbformat==5.1.3
53
- nbsphinx==0.8.3
54
- nest-asyncio==1.5.1
55
- notebook==6.3.0
56
- numpy==1.20.2
57
- olefile==0.46
58
- packaging==20.9
59
- pandocfilters==1.4.3
60
- parso==0.8.2
61
- pickleshare==0.7.5
62
- Pillow==8.2.0
63
- pip==21.0.1
64
- prometheus-client==0.10.1
65
- prompt-toolkit==3.0.17
66
- pyasn1==0.4.8
67
- pyasn1-modules==0.2.8
68
- pycparser==2.20
69
- Pygments==2.8.1
70
- PyHamcrest==2.0.2
71
- pyOpenSSL==20.0.1
72
- pyparsing==2.4.7
73
- pyrsistent==0.17.3
74
- PySocks==1.7.1
75
- python-dateutil==2.8.1
76
- pytz==2021.1
77
- pyvista==0.29.1
78
- pywin32==227
79
- pywinpty==0.5.7
80
- pyzmq==20.0.0
81
- requests==2.25.1
82
- rise==5.7.1
83
- scooby==0.5.7
84
- Send2Trash==1.5.0
85
- service-identity==18.1.0
86
- setuptools==52.0.0.post20210125
87
- six==1.15.0
88
- snowballstemmer==2.1.0
89
- Sphinx==3.5.4
90
- sphinx-rtd-theme==0.5.2
91
- sphinxcontrib-applehelp==1.0.2
92
- sphinxcontrib-devhelp==1.0.2
93
- sphinxcontrib-htmlhelp==1.0.3
94
- sphinxcontrib-jsmath==1.0.1
95
- sphinxcontrib-qthelp==1.0.3
96
- sphinxcontrib-serializinghtml==1.1.4
97
- terminado==0.9.4
98
- testpath==0.4.4
99
- tornado==6.1
100
- traitlets==5.0.5
101
- transforms3d==0.3.1
102
- Twisted==21.2.0
103
- twisted-iocpsupport==1.0.1
104
- typing-extensions==3.7.4.3
105
- urllib3==1.26.4
106
- vtk==9.0.1
107
- wcwidth==0.2.5
108
- webencodings==0.5.1
109
- wheel==0.36.2
110
- win-inet-pton==1.1.0
111
- wincertstore==0.2
112
- zipp==3.4.1
113
- zope.interface==5.3.0