cffview 0.3.0__tar.gz → 0.3.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cffview
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A Python CLI tool to inspect Ansys Fluent .cas.h5/.msh.h5 files without opening Fluent
5
5
  Author-email: preamer <1524477126@qq.com>
6
6
  License-Expression: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cffview"
7
- version = "0.3.0"
7
+ version = "0.3.2"
8
8
  description = "A Python CLI tool to inspect Ansys Fluent .cas.h5/.msh.h5 files without opening Fluent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -31,3 +31,6 @@ Repository = "https://github.com/preamer/cffview"
31
31
 
32
32
  [tool.setuptools.packages.find]
33
33
  where = ["src"]
34
+
35
+ [tool.autopep8]
36
+ max_line_length = 120
@@ -1,6 +1,61 @@
1
1
  from dataclasses import dataclass
2
2
 
3
3
 
4
+ class BoundaryConsts:
5
+ VELOCITY_SPEC = {
6
+ '0': 'Magnitude and Direction',
7
+ '1': 'Components',
8
+ '2': 'Magnitude, Normal to Boundary',
9
+ }
10
+
11
+ FRAME_OF_REFERENCE = {
12
+ '0': 'Absolute',
13
+ '1': 'Ralative to Adjacent Cell Zone',
14
+ }
15
+
16
+ COORDINATE_SYSTEM = {
17
+ '0': 'Cartesian(X, Y, Z)',
18
+ '1': 'Cylindrical(Radial, Tangential, Axial)',
19
+ '2': 'Local Cylindrical(Radial, Tangential, Axial)',
20
+ '3': 'Local Cylindrical Swirl',
21
+ }
22
+
23
+ KE_SPEC = {
24
+ '1': 'Intensity and Length Scale',
25
+ '2': 'Intensity and Viscosity Ratio',
26
+ '3': 'Intensity and Hydraulic Diameter',
27
+ }
28
+
29
+ DIRECTION_SPEC = {
30
+ '0': 'Direction Vector',
31
+ '1': 'Normal to Boundary',
32
+ }
33
+
34
+ THERMAL_BC = {
35
+ '0': 'Heat Flux',
36
+ '1': 'Temperature',
37
+ '2': 'Convection',
38
+ '3': 'Coupled',
39
+ '4': 'Radiation',
40
+ '5': 'Mixed',
41
+ '8': 'via System Coupling',
42
+ }
43
+
44
+ MOTION_BC = {
45
+ '0': 'Stationary Wall',
46
+ '1': 'Moving Wall',
47
+ }
48
+
49
+ SHEAR_BC = {
50
+ '0': 'No Slip',
51
+ '1': 'Specified Shear',
52
+ '2': 'Specularity Coefficient',
53
+ '3': 'Marangoni Stress',
54
+ }
55
+
56
+ ROUGH_BC = {}
57
+
58
+
4
59
  class BoundaryFactory:
5
60
  _REGISTRY = {}
6
61
 
@@ -71,34 +126,27 @@ class VelocityInlet:
71
126
  frame_of_reference: str = ''
72
127
  vmag: str = ''
73
128
  t: str = ''
129
+
74
130
  ke_spec: str = ''
75
131
  turb_intensity: str = ''
76
132
  turb_hydraulic_diam: str = ''
77
133
  turb_viscosity_ratio: str = ''
78
134
 
79
- _VELOCITY_SPEC = {
80
- '1': 'Magnitude and Direction',
81
- '2': 'Magnitude, Normal to Boundary',
82
- '3': 'Components',
83
- }
84
-
85
- _FRAME_OF_REFERENCE = {
86
- '0': 'Absolute',
87
- '1': 'Ralative to Adjacent Cell Zone',
88
- }
89
-
90
- _KE_SPEC = {
91
- '1': 'Intensity and Length Scale',
92
- '2': 'Intensity and Viscosity Ratio',
93
- '3': 'Intensity and Hydraulic Diameter',
94
- }
135
+ coordinate_system: str = ''
136
+ ni: str = ''
137
+ nj: str = ''
138
+ nk: str = ''
139
+ u: str = ''
140
+ v: str = ''
141
+ w: str = ''
95
142
 
96
143
  def to_dict(self) -> dict[str, str]:
97
144
  data = self.__dict__.copy()
98
145
 
99
- data['velocity_spec'] = self._VELOCITY_SPEC.get(self.velocity_spec, 'unknown')
100
- data['frame_of_reference'] = self._FRAME_OF_REFERENCE.get(self.frame_of_reference, 'unknown')
101
- data['ke_spec'] = self._KE_SPEC.get(self.ke_spec, 'unknown')
146
+ data['velocity_spec'] = BoundaryConsts.VELOCITY_SPEC.get(self.velocity_spec, 'unknown')
147
+ data['frame_of_reference'] = BoundaryConsts.FRAME_OF_REFERENCE.get(self.frame_of_reference, 'unknown')
148
+ data['coordinate_system'] = BoundaryConsts.COORDINATE_SYSTEM.get(self.coordinate_system, 'unknown')
149
+ data['ke_spec'] = BoundaryConsts.KE_SPEC.get(self.ke_spec, 'unknown')
102
150
 
103
151
  match data['ke_spec']:
104
152
  case 'Intensity and Length Scale':
@@ -111,6 +159,24 @@ class VelocityInlet:
111
159
  data.pop('turb_length_scale', None)
112
160
  data.pop('turb_viscosity_ratio', None)
113
161
 
162
+ match data['velocity_spec']:
163
+ case 'Magnitude and Direction':
164
+ data.pop('u', None)
165
+ data.pop('v', None)
166
+ data.pop('w', None)
167
+ case 'Components':
168
+ data.pop('ni', None)
169
+ data.pop('nj', None)
170
+ data.pop('nk', None)
171
+ case 'Magnitude, Normal to Boundary':
172
+ data.pop('coordinate_system', None)
173
+ data.pop('ni', None)
174
+ data.pop('nj', None)
175
+ data.pop('nk', None)
176
+ data.pop('u', None)
177
+ data.pop('v', None)
178
+ data.pop('w', None)
179
+
114
180
  return data
115
181
 
116
182
 
@@ -147,6 +213,13 @@ class PressureInlet:
147
213
  p0: str = ''
148
214
  p: str = ''
149
215
  t0: str = ''
216
+
217
+ direction_spec: str = ''
218
+ coordinate_system: str = ''
219
+ ni: str = ''
220
+ nj: str = ''
221
+ nk: str = ''
222
+
150
223
  ke_spec: str = ''
151
224
  prevent_reverse_flow: str = ''
152
225
  turb_intensity: str = ''
@@ -154,22 +227,22 @@ class PressureInlet:
154
227
  turb_hydraulic_diam: str = ''
155
228
  turb_viscosity_ratio: str = ''
156
229
 
157
- _FRAME_OF_REFERENCE = {
158
- '0': 'Absolute',
159
- '1': 'Ralative to Adjacent Cell Zone',
160
- }
161
-
162
- _KE_SPEC = {
163
- '1': 'Intensity and Length Scale',
164
- '2': 'Intensity and Viscosity Ratio',
165
- '3': 'Intensity and Hydraulic Diameter',
166
- }
167
-
168
230
  def to_dict(self) -> dict[str, str]:
169
231
  data = self.__dict__.copy()
170
232
 
171
- data['frame_of_reference'] = self._FRAME_OF_REFERENCE.get(self.frame_of_reference, 'unknown')
172
- data['ke_spec'] = self._KE_SPEC.get(self.ke_spec, 'unknown')
233
+ data['frame_of_reference'] = BoundaryConsts.FRAME_OF_REFERENCE.get(self.frame_of_reference, 'unknown')
234
+ data['direction_spec'] = BoundaryConsts.DIRECTION_SPEC.get(self.direction_spec, 'unknown')
235
+ data['coordinate_system'] = BoundaryConsts.COORDINATE_SYSTEM.get(self.coordinate_system, 'unknown')
236
+ data['ke_spec'] = BoundaryConsts.KE_SPEC.get(self.ke_spec, 'unknown')
237
+
238
+ match data['direction_spec']:
239
+ case 'Direction Vector':
240
+ pass
241
+ case 'Normal to Boundary':
242
+ data.pop('coordinate_system', None)
243
+ data.pop('ni', None)
244
+ data.pop('nj', None)
245
+ data.pop('nk', None)
173
246
 
174
247
  match data['ke_spec']:
175
248
  case 'Intensity and Length Scale':
@@ -202,20 +275,17 @@ class PressureOutlet:
202
275
  turb_hydraulic_diam: str = ''
203
276
  turb_viscosity_ratio: str = ''
204
277
 
205
- _KE_SPEC = {
206
- '1': 'Intensity and Length Scale',
207
- '2': 'Intensity and Viscosity Ratio',
208
- '3': 'Intensity and Hydraulic Diameter',
209
- }
210
-
211
278
  def to_dict(self) -> dict[str, str]:
212
279
  data = self.__dict__.copy()
213
280
 
214
281
  if self.prevent_reverse_flow == '#t':
215
- for key in ['t', 'ke_spec', 'turb_intensity', 'turb_length_scale', 'targeted_mf_boundary', 'turb_hydraulic_diam', 'turb_viscosity_ratio']:
282
+ for key in [
283
+ 't', 'ke_spec', 'turb_intensity', 'turb_length_scale',
284
+ 'targeted_mf_boundary', 'turb_hydraulic_diam', 'turb_viscosity_ratio',
285
+ ]:
216
286
  data.pop(key, None)
217
287
  else:
218
- data['ke_spec'] = self._KE_SPEC.get(self.ke_spec, 'unknown')
288
+ data['ke_spec'] = BoundaryConsts.KE_SPEC.get(self.ke_spec, 'unknown')
219
289
  match data['ke_spec']:
220
290
  case 'Intensity and Length Scale':
221
291
  data.pop('turb_viscosity_ratio', None)
@@ -235,6 +305,7 @@ class PressureOutlet:
235
305
  class Outflow:
236
306
  name: str
237
307
  id_: str
308
+ flowrate_frac: str = ''
238
309
 
239
310
 
240
311
  @dataclass
@@ -245,10 +316,12 @@ class Wall:
245
316
  d: str = ''
246
317
  q_dot: str = ''
247
318
  material: str = ''
319
+
248
320
  thermal_bc: str = ''
249
321
  t: str = ''
250
322
  q: str = ''
251
323
  h: str = ''
324
+
252
325
  motion_bc: str = ''
253
326
  shear_bc: str = ''
254
327
  rough_bc: str = ''
@@ -257,21 +330,12 @@ class Wall:
257
330
  roughness_height: str = ''
258
331
  roughness_const: str = ''
259
332
 
260
- _THERMAL_BC = {
261
- '1': 'Heat Flux',
262
- '2': 'Temperature',
263
- '3': 'Coupled',
264
- }
265
-
266
- _MOTION_BC = {}
267
-
268
- _SHEAR_BC = {}
269
-
270
- _ROUGH_BC = {}
333
+ planar_conduction: str = ''
334
+ shell_conduction: str = ''
271
335
 
272
336
  _THERMAL_BC_WHITELIST = {
273
- '1': {'q_dot'}, # Heat Flux
274
- '2': {'t'}, # Temperature
337
+ '0': {'q_dot'}, # Heat Flux
338
+ '1': {'t'}, # Temperature
275
339
  '3': set(), # Coupled
276
340
  }
277
341
 
@@ -284,7 +348,12 @@ class Wall:
284
348
  for attr in attrs_to_remove:
285
349
  data.pop(attr, None)
286
350
 
287
- data['thermal_bc'] = self._THERMAL_BC.get(self.thermal_bc, 'unknown')
351
+ data['thermal_bc'] = BoundaryConsts.THERMAL_BC.get(self.thermal_bc, 'unknown')
352
+ data['motion_bc'] = BoundaryConsts.MOTION_BC.get(self.motion_bc, 'unknown')
353
+ data['shear_bc'] = BoundaryConsts.SHEAR_BC.get(self.shear_bc, 'unknown')
354
+
355
+ if data['planar_conduction'] == '#f':
356
+ data.pop('shell_conduction', None)
288
357
 
289
358
  return data
290
359
 
@@ -1,4 +1,4 @@
1
- from typing import Literal
1
+ from typing import Literal, TypeAlias, Union
2
2
 
3
3
 
4
4
  def print_version(file_path: str) -> str:
@@ -42,6 +42,9 @@ def read_case(file_path: str, **kwargs) -> dict[
42
42
  """
43
43
  import re
44
44
  import h5py
45
+ import sexpdata
46
+
47
+ SexpdataList: TypeAlias = list[Union[sexpdata.Symbol, 'SexpdataList']]
45
48
 
46
49
  with h5py.File(file_path) as f:
47
50
  settings: h5py.Group = f['/settings']
@@ -150,36 +153,53 @@ def read_case(file_path: str, **kwargs) -> dict[
150
153
  }
151
154
 
152
155
  if kwargs['mat']:
153
- import sexpdata
154
-
155
156
  data['materials'] = {}
156
157
  materials = re.search(
157
158
  r'(\(materials.*)',
158
159
  general_info,
159
160
  re.M
160
161
  ).group(1)
161
- materials: list = sexpdata.loads(materials)
162
+ materials: SexpdataList = sexpdata.loads(materials)
162
163
  for material in materials[1]:
163
164
  name = str(material[0])
164
165
  data['materials'][name] = {}
165
166
  data['materials'][name]['type'] = str(material[1])
166
- for i in range(2, len(material)):
167
- property_ = material[i]
167
+ for property_ in material[2:]:
168
+ property_name = str(property_[0])
168
169
  if property_[1] == sexpdata.Symbol('.'):
169
- data['materials'][name][str(property_[0])] = str(property_[2])
170
- elif isinstance(p1 := property_[1], list):
171
- if p1[1] == sexpdata.Symbol('.'):
172
- data['materials'][name][str(property_[0])] = f'{p1[0]}/{p1[2]}'
170
+ data['materials'][name][property_name] = str(property_[2])
171
+ elif isinstance(property_value_list := property_[1], list):
172
+ if property_value_list[1] == sexpdata.Symbol('.'):
173
+ data['materials'][name][property_name] = f'{property_value_list[0]}/{property_value_list[2]}'
174
+ elif str(property_value_list[1]) == 'piecewise-linear':
175
+ value = [f'{p[0]}, {p[2]}' for p in property_value_list[2:]]
176
+ data['materials'][name][property_name] = {
177
+ f'{property_value_list[0]}/{property_value_list[1]}': value
178
+ }
179
+ elif str(property_value_list[1]) in ['piecewise-polynomial', 'nasa-9-piecewise-polynomial']:
180
+ value = [str(p).strip('[]') for p in property_value_list[2:]]
181
+ data['materials'][name][property_name] = {
182
+ f'{property_value_list[0]}/{property_value_list[1]}': value
183
+ }
184
+ elif str(property_value_list[0]) == 'orthotropic':
185
+ value = {}
186
+ for p in property_value_list[1:]:
187
+ orth_property_name = str(p[0])
188
+ if orth_property_name in ['direction-0', 'direction-1', 'direction-2']:
189
+ value[orth_property_name] = str(p[1:]).strip('[]')
190
+ value[orth_property_name] = sexpdata.cdr(p)
191
+ elif orth_property_name in ['k0', 'k1', 'k2']:
192
+ value[orth_property_name] = f'{sexpdata.car(p[1])}/{sexpdata.cdr(p[1])}'
193
+ data['materials'][name][property_name] = {f'{property_value_list[0]}': value}
173
194
  else:
174
- value = ' '.join(str(p) for p in p1[1:])
175
- data['materials'][name][str(property_[0])] = f'{p1[0]}/{value}'
195
+ value = ' '.join(str(p) for p in property_value_list[1:])
196
+ data['materials'][name][property_name] = f'{property_value_list[0]}/{value}'
176
197
 
177
198
  if kwargs['bd']:
178
- import sexpdata
179
199
  from .boundary import BoundaryFactory
180
200
 
181
201
  data['boundary'] = {}
182
- boundaries: list[list] = sexpdata.parse(boundary_info, true=None)
202
+ boundaries: list[SexpdataList] = sexpdata.parse(boundary_info, true=None)
183
203
  for boundary_info in boundaries:
184
204
  id_, type_, name, _ = [str(_) for _ in boundary_info[1]]
185
205
  new_boundary = BoundaryFactory.create(name, id_, type_)
@@ -198,15 +218,13 @@ def read_case(file_path: str, **kwargs) -> dict[
198
218
  data['boundary'][type_] = b_list
199
219
 
200
220
  if kwargs['ne']:
201
- import sexpdata
202
-
203
221
  data['named-expressions'] = {}
204
222
  nes = re.search(
205
223
  r'(\(named-expressions.*)',
206
224
  general_info,
207
225
  re.M
208
226
  ).group(1)
209
- nes: list = sexpdata.loads(nes, true=None)[1]
227
+ nes: SexpdataList = sexpdata.loads(nes, true=None)[1]
210
228
  for ne in nes:
211
229
  ne_dict = {
212
230
  str(property_[0]): str(property_[2])
@@ -252,15 +270,13 @@ def read_case(file_path: str, **kwargs) -> dict[
252
270
  data['relax-factor'][eq] = relax_factor.get(eq, '')
253
271
 
254
272
  if kwargs['rd']:
255
- import sexpdata
256
-
257
273
  data['report-definitions'] = {}
258
274
  rds = re.search(
259
275
  r'(\(monitor/report-definitions.*)',
260
276
  general_info,
261
277
  re.M
262
278
  ).group(1)
263
- rds: list = sexpdata.loads(rds, true=None)[1]
279
+ rds: SexpdataList = sexpdata.loads(rds, true=None)[1]
264
280
  for rd in rds:
265
281
  name = str(rd[0][2])
266
282
  type_ = str(rd[1][1])
@@ -278,15 +294,13 @@ def read_case(file_path: str, **kwargs) -> dict[
278
294
  data['report-definitions'][name]['per-zone?'] = str(rd[1][-5][2])
279
295
 
280
296
  if kwargs['plotsets']:
281
- import sexpdata
282
-
283
297
  data['plotsets'] = {}
284
298
  plotsets = re.search(
285
299
  r'(\(monitor/plotsets.*)',
286
300
  general_info,
287
301
  re.M
288
302
  ).group(1)
289
- plotsets: list = sexpdata.loads(plotsets, true=None)[1]
303
+ plotsets: SexpdataList = sexpdata.loads(plotsets, true=None)[1]
290
304
  for plotset in plotsets:
291
305
  plotset_dict = {
292
306
  str(property_[0]): str(property_[2])
@@ -297,15 +311,13 @@ def read_case(file_path: str, **kwargs) -> dict[
297
311
  data['plotsets'][plotset_dict['name']] = plotset_dict
298
312
 
299
313
  if kwargs['monitorsets']:
300
- import sexpdata
301
-
302
314
  data['monitorsets'] = {}
303
315
  monitorsets = re.search(
304
316
  r'(\(monitor/monitorsets.*)',
305
317
  general_info,
306
318
  re.M
307
319
  ).group(1)
308
- monitorsets: list = sexpdata.loads(monitorsets, true=None)[1]
320
+ monitorsets: SexpdataList = sexpdata.loads(monitorsets, true=None)[1]
309
321
  for monitorset in monitorsets:
310
322
  monitorset_dict = {
311
323
  str(property_[0]): str(property_[2])
@@ -316,8 +328,6 @@ def read_case(file_path: str, **kwargs) -> dict[
316
328
  data['monitorsets'][monitorset_dict['name']] = monitorset_dict
317
329
 
318
330
  if kwargs['residuals']:
319
- import sexpdata
320
-
321
331
  data['residuals'] = {}
322
332
 
323
333
  for setting in [
@@ -350,7 +360,7 @@ def read_case(file_path: str, **kwargs) -> dict[
350
360
  general_info,
351
361
  re.M
352
362
  ).group(1)
353
- res: list = sexpdata.loads(res, true=None)[1]
363
+ res: SexpdataList = sexpdata.loads(res, true=None)[1]
354
364
  for eq in res:
355
365
  data['residuals'][str(eq[0])] = {
356
366
  'monitor': str(eq[1]),
@@ -395,15 +405,13 @@ def read_case(file_path: str, **kwargs) -> dict[
395
405
  ).group(1)
396
406
 
397
407
  if kwargs['contours']:
398
- import sexpdata
399
-
400
408
  data['contours'] = {}
401
409
  contours = re.search(
402
410
  r'(\(graphics/contours.*)',
403
411
  general_info,
404
412
  re.M
405
413
  ).group(1)
406
- contours: list = sexpdata.loads(contours, true=None)[1]
414
+ contours: SexpdataList = sexpdata.loads(contours, true=None)[1]
407
415
  for contour in contours:
408
416
  contour_dict = {
409
417
  str(property_[0]): str(property_[2])
@@ -426,15 +434,13 @@ def read_case(file_path: str, **kwargs) -> dict[
426
434
  data['contours'][contour_dict['name']] = contour_dict
427
435
 
428
436
  if kwargs['vectors']:
429
- import sexpdata
430
-
431
437
  data['vectors'] = {}
432
438
  vectors = re.search(
433
439
  r'(\(graphics/vectors\s.*)',
434
440
  general_info,
435
441
  re.M
436
442
  ).group(1)
437
- vectors: list = sexpdata.loads(vectors, true=None)[1]
443
+ vectors: SexpdataList = sexpdata.loads(vectors, true=None)[1]
438
444
  for vector in vectors:
439
445
  vector_dict = {
440
446
  str(property_[0]): str(property_[2])
@@ -495,6 +501,8 @@ def show_mesh(file_path: str) -> None:
495
501
  Path to the .h5 file
496
502
  """
497
503
  import pyvista as pv
504
+ from .utils import KEYBOARD_SHORTCUTS, print_colored_dict
505
+
498
506
  if file_path.endswith('cas.h5'):
499
507
  mesh = pv.read(file_path)
500
508
  elif file_path.endswith('msh.h5'):
@@ -546,14 +554,11 @@ def show_mesh(file_path: str) -> None:
546
554
  pl = pv.Plotter()
547
555
  pl.enable_anti_aliasing()
548
556
 
549
- mesh = mesh.combine() if mesh.n_blocks > 1 else mesh
557
+ mesh = mesh.combine() if isinstance(mesh, pv.MultiBlock) else mesh
550
558
  mesh_actor = pl.add_mesh(mesh, show_edges=True)
551
559
 
552
- def toggle_opacity(value):
553
- mesh_actor.prop.opacity = value
554
-
555
560
  opacity_slider_widget = pl.add_slider_widget(
556
- toggle_opacity,
561
+ lambda value: setattr(mesh_actor.prop, 'opacity', value),
557
562
  rng=(0.1, 1.0),
558
563
  value=1.0,
559
564
  title="Opacity",
@@ -591,13 +596,18 @@ def show_mesh(file_path: str) -> None:
591
596
  pl.add_checkbox_button_widget(
592
597
  callback=toggle_slice,
593
598
  value=False,
599
+ position=(10, 10),
600
+ size=40,
594
601
  )
602
+ pl.add_text("Clip Plane", position=(60, 20), font_size=10)
595
603
 
596
- pl.add_axes()
604
+ pl.add_axes(viewport=(0.8, 0.0, 1.0, 0.2))
605
+ print_colored_dict(KEYBOARD_SHORTCUTS)
597
606
  pl.show()
598
607
 
599
608
 
600
609
  def main() -> None:
610
+ import os
601
611
  import argparse
602
612
 
603
613
  BANNER = r"""
@@ -623,8 +633,9 @@ A Python CLI tool to inspect Ansys Fluent .cas.h5/.msh.h5 files without opening
623
633
  )
624
634
 
625
635
  ARGUMENTS = [
626
- (("--extract",), "extract cas.h5 general and boundary string to files"),
627
636
  (("--version",), "show the version of the .h5 file"),
637
+ (("--extract",), "extract cas.h5 general and boundary string to files"),
638
+ (("--showmesh",), "show mesh using pyvista"),
628
639
  (("--solver",), "show solver settings"),
629
640
  (("--mat", "--materials"), "show materials settings"),
630
641
  (("--bd", "--boundary"), "show boundary settings"),
@@ -638,7 +649,6 @@ A Python CLI tool to inspect Ansys Fluent .cas.h5/.msh.h5 files without opening
638
649
  (("--contours",), "show graphics contours settings"),
639
650
  (("--vectors",), "show graphics vectors settings"),
640
651
  (("--save",), "save output to file"),
641
- (("--showmesh",), "show mesh using pyvista"),
642
652
  ]
643
653
 
644
654
  for flags, help_text in ARGUMENTS:
@@ -646,6 +656,10 @@ A Python CLI tool to inspect Ansys Fluent .cas.h5/.msh.h5 files without opening
646
656
 
647
657
  args = parser.parse_args()
648
658
 
659
+ if not args.file_path.endswith((".cas.h5", ".msh.h5")):
660
+ print("Invalid file path. Please provide a .cas.h5 or .msh.h5 file.")
661
+ return
662
+
649
663
  if args.version:
650
664
  print_version(args.file_path)
651
665
  elif args.extract:
@@ -1,3 +1,5 @@
1
+ import sys
2
+
1
3
  # From context.scm
2
4
  FLUENT_ENUM = {
3
5
  "0": "First Order Upwind",
@@ -64,6 +66,43 @@ CELL_TYPES = {
64
66
  7: "Polyhedron",
65
67
  }
66
68
 
69
+ KEYBOARD_SHORTCUTS = {
70
+ 'q': 'Close the rendering window',
71
+ 'f': 'Focus and zoom in on a point',
72
+ 'v': 'Isometric camera view',
73
+ 'w': 'Switch all datasets to a wireframe representation',
74
+ 'r': 'Reset the camera to view all datasets',
75
+ 's': 'Switch all datasets to a surface representation',
76
+ 'shift+click or middle-click' if not sys.platform.startswith('darwin') else 'shift+click': 'Pan the rendering scene',
77
+ 'left-click' if not sys.platform.startswith('darwin') else 'cmd+click': 'Rotate the rendering scene in 3D',
78
+ 'ctrl+click': 'Rotate the rendering scene in 2D(view-plane)',
79
+ 'mouse-wheel or right-click' if not sys.platform.startswith('darwin') else 'ctl+click': 'Continuously zoom the rendering scene',
80
+ 'shift+s': 'Save a screenshot(only on BackgroundPlotter)',
81
+ 'shift+c': 'Enable interactive cell selection/picking',
82
+ 'up/down': 'Zoom in and out',
83
+ '+ /-': 'Increase/decrease the point size and line widths',
84
+ }
85
+
86
+ DATA_KEYS = (
87
+ 'SV_BF_V',
88
+ 'SV_DENSITY',
89
+ 'SV_DENSITY_RG_AUX',
90
+ 'SV_DISCONT',
91
+ 'SV_H',
92
+ 'SV_H_RG_AUX',
93
+ 'SV_MU_LAM',
94
+ 'SV_NORMAL_MACH',
95
+ 'SV_P',
96
+ 'SV_P_RG_AUX',
97
+ 'SV_T',
98
+ 'SV_U',
99
+ 'SV_U_RG_AUX',
100
+ 'SV_V',
101
+ 'SV_V_RG_AUX',
102
+ 'SV_W',
103
+ 'SV_W_RG_AUX',
104
+ )
105
+
67
106
 
68
107
  def print_colored_dict(data) -> None:
69
108
  """Print nested data in 4-space JSON format.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cffview
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: A Python CLI tool to inspect Ansys Fluent .cas.h5/.msh.h5 files without opening Fluent
5
5
  Author-email: preamer <1524477126@qq.com>
6
6
  License-Expression: BSD-3-Clause
File without changes
File without changes
File without changes