PyHOPE 0.0.2__tar.gz → 0.0.4__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 (42) hide show
  1. {pyhope-0.0.2 → pyhope-0.0.4}/LICENSE.md +1 -2
  2. {pyhope-0.0.2 → pyhope-0.0.4}/PKG-INFO +10 -15
  3. {pyhope-0.0.2 → pyhope-0.0.4}/README.md +2 -2
  4. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/basis/basis_jacobian.py +3 -3
  5. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/common/common.py +66 -46
  6. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/common/common_vars.py +61 -6
  7. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/io/io.py +28 -27
  8. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/mesh/mesh.py +35 -18
  9. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/mesh/mesh_builtin.py +30 -27
  10. pyhope-0.0.4/pyhope/mesh/mesh_common.py +242 -0
  11. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/mesh/mesh_connect.py +48 -48
  12. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/mesh/mesh_external.py +227 -69
  13. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/mesh/mesh_sides.py +35 -19
  14. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/mesh/mesh_sort.py +4 -4
  15. pyhope-0.0.4/pyhope/mesh/mesh_vars.py +204 -0
  16. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/output/output.py +3 -3
  17. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/pyhope.py +9 -5
  18. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/readintools/commandline.py +3 -2
  19. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/readintools/readintools.py +7 -7
  20. pyhope-0.0.4/pyproject.toml +46 -0
  21. pyhope-0.0.2/pyhope/inout/io.py +0 -341
  22. pyhope-0.0.2/pyhope/io/io_cgns.py +0 -257
  23. pyhope-0.0.2/pyhope/io/io_meshio.py +0 -247
  24. pyhope-0.0.2/pyhope/io/io_vars.py +0 -46
  25. pyhope-0.0.2/pyhope/io/io_vtk.py +0 -266
  26. pyhope-0.0.2/pyhope/mesh/mesh_common.py +0 -167
  27. pyhope-0.0.2/pyhope/mesh/mesh_vars.py +0 -93
  28. pyhope-0.0.2/pyhope/readintools/__init__.py +0 -0
  29. pyhope-0.0.2/pyproject.toml +0 -37
  30. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/__main__.py +0 -0
  31. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/basis/__init__.py +0 -0
  32. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/common/__init__.py +0 -0
  33. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/config/__init__.py +0 -0
  34. {pyhope-0.0.2 → pyhope-0.0.4}/pyhope/config/config.py +0 -0
  35. {pyhope-0.0.2/pyhope/inout → pyhope-0.0.4/pyhope/io}/__init__.py +0 -0
  36. {pyhope-0.0.2/pyhope/inout → pyhope-0.0.4/pyhope/io}/io_cgns.py +0 -0
  37. {pyhope-0.0.2/pyhope/inout → pyhope-0.0.4/pyhope/io}/io_meshio.py +0 -0
  38. {pyhope-0.0.2/pyhope/inout → pyhope-0.0.4/pyhope/io}/io_vars.py +0 -0
  39. {pyhope-0.0.2/pyhope/inout → pyhope-0.0.4/pyhope/io}/io_vtk.py +0 -0
  40. {pyhope-0.0.2/pyhope/io → pyhope-0.0.4/pyhope/mesh}/__init__.py +0 -0
  41. {pyhope-0.0.2/pyhope/mesh → pyhope-0.0.4/pyhope/output}/__init__.py +0 -0
  42. {pyhope-0.0.2/pyhope/output → pyhope-0.0.4/pyhope/readintools}/__init__.py +0 -0
@@ -630,7 +630,6 @@ attach them to the start of each source file to most effectively state
630
630
  the exclusion of warranty; and each file should have at least the
631
631
  "copyright" line and a pointer to where the full notice is found.
632
632
 
633
- <one line to give the program's name and a brief idea of what it does.>
634
633
  Copyright (c) 2024 Numerics Research Group, University of Stuttgart, Prof. Andrea Beck
635
634
 
636
635
  This program is free software: you can redistribute it and/or modify
@@ -652,7 +651,7 @@ mail.
652
651
  If the program does terminal interaction, make it output a short
653
652
  notice like this when it starts in an interactive mode:
654
653
 
655
- <program> Copyright (c) 2024 Numerics Research Group, University of Stuttgart, Prof. Andrea Beck
654
+ PyHOPE Copyright (c) 2024 Numerics Research Group, University of Stuttgart, Prof. Andrea Beck
656
655
  This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
656
  This is free software, and you are welcome to redistribute it
658
657
  under certain conditions; type `show c' for details.
@@ -1,22 +1,17 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: PyHOPE
3
- Version: 0.0.2
4
- Summary: Coming soon
5
- Home-page: https://gitlab.iag.uni-stuttgart.de/flexi/codes/pyhope
6
- License: GPL-3.0
3
+ Version: 0.0.4
4
+ Summary: Python High-Order Preprocessing Environment
5
+ Home-page: https://numericsresearchgroup.org
6
+ License: GPL-3.0-only
7
7
  Keywords: PyHOPE,mesh generator
8
8
  Author: Numerics Research Group (NRG)
9
9
  Author-email: numerics@iag.uni-stuttgart.de
10
+ Requires-Python: >=3.8
10
11
  Classifier: Development Status :: 3 - Alpha
11
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
12
12
  Classifier: Operating System :: POSIX :: Linux
13
- Classifier: Programming Language :: Python :: 2
14
- Classifier: Programming Language :: Python :: 2.7
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
14
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.4
17
- Classifier: Programming Language :: Python :: 3.5
18
- Classifier: Programming Language :: Python :: 3.6
19
- Classifier: Programming Language :: Python :: 3.7
20
15
  Classifier: Programming Language :: Python :: 3.8
21
16
  Classifier: Programming Language :: Python :: 3.9
22
17
  Classifier: Programming Language :: Python :: 3.10
@@ -28,7 +23,7 @@ Requires-Dist: gmsh
28
23
  Requires-Dist: h5py
29
24
  Requires-Dist: hilbertcurve
30
25
  Requires-Dist: meshio
31
- Requires-Dist: numpy
26
+ Requires-Dist: numpy (>=2.0.0)
32
27
  Requires-Dist: packaging
33
28
  Requires-Dist: plotext
34
29
  Requires-Dist: pygmsh
@@ -40,7 +35,7 @@ PyHOPE (Python High-Order Preprocessing Environment) is an open-source Python fr
40
35
 
41
36
  PyHOPE has been developed by the Numerics Research Group (NRG) lead by Prof. Andrea Beck at the Institute of Aerodynamics and Gas Dynamics at the University of Stuttgart, Germany.
42
37
 
43
- PyHOPE is heavily inspired by [HOPR (High Order Preprocessor)](https://github.com/hopr-framework/hopr) and share the same input/output format. For more information and tutorials, please visit the [HOPR documentation](https://hopr.readthedocs.io)
38
+ PyHOPE is heavily inspired by [HOPR (High Order Preprocessor)](https://github.com/hopr-framework/hopr) and shares the same input/output format. For more information and tutorials, please visit the [HOPR documentation](https://hopr.readthedocs.io)
44
39
 
45
40
  This is a scientific project. If you use pyHOPE for publications or presentations in science, please support the project by citing our publications given at [numericsresearchgroup.org](https://numericsresearchgroup.org/publications.html).
46
41
 
@@ -58,7 +53,7 @@ PyHOPE is invoked from the command line. Run parameters are read from a configur
58
53
  $ pyhope tutorials/1-01-cartbox/parameter.ini
59
54
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
60
55
  ┃ P y H O P E — Python High-Order Preprocessing Environment
61
- ┃ PyHOPE version 0.0.2
56
+ ┃ PyHOPE version x.x.x
62
57
  ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63
58
  ├─────────────────────────────────────────────
64
59
  │ INIT PROGRAM...
@@ -2,7 +2,7 @@ PyHOPE (Python High-Order Preprocessing Environment) is an open-source Python fr
2
2
 
3
3
  PyHOPE has been developed by the Numerics Research Group (NRG) lead by Prof. Andrea Beck at the Institute of Aerodynamics and Gas Dynamics at the University of Stuttgart, Germany.
4
4
 
5
- PyHOPE is heavily inspired by [HOPR (High Order Preprocessor)](https://github.com/hopr-framework/hopr) and share the same input/output format. For more information and tutorials, please visit the [HOPR documentation](https://hopr.readthedocs.io)
5
+ PyHOPE is heavily inspired by [HOPR (High Order Preprocessor)](https://github.com/hopr-framework/hopr) and shares the same input/output format. For more information and tutorials, please visit the [HOPR documentation](https://hopr.readthedocs.io)
6
6
 
7
7
  This is a scientific project. If you use pyHOPE for publications or presentations in science, please support the project by citing our publications given at [numericsresearchgroup.org](https://numericsresearchgroup.org/publications.html).
8
8
 
@@ -20,7 +20,7 @@ PyHOPE is invoked from the command line. Run parameters are read from a configur
20
20
  $ pyhope tutorials/1-01-cartbox/parameter.ini
21
21
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
22
22
  ┃ P y H O P E — Python High-Order Preprocessing Environment
23
- ┃ PyHOPE version 0.0.2
23
+ ┃ PyHOPE version x.x.x
24
24
  ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25
25
  ├─────────────────────────────────────────────
26
26
  │ INIT PROGRAM...
@@ -342,16 +342,16 @@ def CheckJacobians() -> None:
342
342
 
343
343
  for iElem, elem in enumerate(elems):
344
344
  # Only consider hexahedrons
345
- if int(elem['Type']) % 100 != 8:
345
+ if int(elem.type) % 100 != 8:
346
346
  continue
347
347
 
348
348
  # Get the mapping
349
- linMap = LINMAP(elem['Type'], order=mesh_vars.nGeo)
349
+ linMap = LINMAP(elem.type, order=mesh_vars.nGeo)
350
350
  mapLin = {k: v for v, k in enumerate(linMap)}
351
351
 
352
352
  # Fill the NodeCoords
353
353
  nodeCoords = np.zeros((nGeo ** 3, 3), dtype=np.float64)
354
- for iNode, nodeID in enumerate(elem['Nodes']):
354
+ for iNode, nodeID in enumerate(elem.nodes):
355
355
  nodeCoords[mapLin[iNode], :] = nodes[nodeID]
356
356
 
357
357
  xGeo = np.zeros((3, nGeo, nGeo, nGeo))
@@ -145,16 +145,29 @@ def PkgsMetaVersion(pkgs) -> Union[str, None]:
145
145
  def PkgsCheckGmsh() -> None:
146
146
  # Local imports ----------------------------------------
147
147
  import pyhope.output.output as hopout
148
+ from pyhope.common.common_vars import Gitlab
148
149
  # ------------------------------------------------------
150
+
151
+ # Check the current platform
152
+ system = platform.system().lower()
153
+ arch = platform.machine().lower()
154
+
149
155
  gmsh_version = PkgsMetaVersion('gmsh')
150
156
  if gmsh_version is None:
151
157
  # Gmsh is not installed
152
158
  if IsInteractive():
153
- warning = 'Gmsh is not installed. For compatibility, the NRG Gmsh version will be installed. Continue? (Y/n):'
154
- response = input('\n' + hopout.warn(warning) + '\n')
155
- if response.lower() in ['yes', 'y', '']:
156
- PkgsInstallGmsh()
157
- return None
159
+ if system in Gitlab.LIB_SUPPORT and arch in Gitlab.LIB_SUPPORT[system]:
160
+ warning = 'Gmsh is not installed. For compatibility, the NRG Gmsh version will be installed. Continue? (Y/n):'
161
+ response = input('\n' + hopout.warn(warning) + '\n')
162
+ if response.lower() in ['yes', 'y', '']:
163
+ PkgsInstallGmsh(system,arch,version='nrg')
164
+ return None
165
+ else:
166
+ warning = 'Gmsh is not installed. As NRG does not provide a compatible Gmsh version, the PyPI Gmsh version will be installed. Continue? (Y/n):'
167
+ response = input('\n' + hopout.warn(warning) + '\n')
168
+ if response.lower() in ['yes', 'y', '']:
169
+ PkgsInstallGmsh(system,arch,version='pypi')
170
+ return None
158
171
  else:
159
172
  hopout.warning('Gmsh is not installed, exiting...')
160
173
  sys.exit(1)
@@ -166,27 +179,23 @@ def PkgsCheckGmsh() -> None:
166
179
  return None
167
180
 
168
181
  # Check if the installed version is the NRG version
169
- if PkgsMetaData('gmsh', 'Intended Audience: NRG'):
182
+ if PkgsMetaData('gmsh', 'Intended Audience :: NRG'):
170
183
  return None
171
184
 
172
- # Check the current platform
173
- system = platform.system()
174
- arch = platform.machine()
175
-
176
- if system != 'Linux' or arch != 'x86_64':
185
+ if system not in Gitlab.LIB_SUPPORT or arch not in Gitlab.LIB_SUPPORT[system]:
177
186
  warning = hopout.warn(f'Detected non-NRG Gmsh version on unsupported platform [{system}/{arch}]. ' +
178
187
  'Functionality may be limited.')
179
188
  print(warning)
180
189
  return None
181
190
 
182
- if not PkgsMetaData('gmsh', 'Intended Audience: NRG'):
191
+ if not PkgsMetaData('gmsh', 'Intended Audience :: NRG'):
183
192
  if IsInteractive():
184
193
  warning = 'Detected Gmsh package uses an outdated CGNS (v3.4). For compatibility, ' \
185
194
  'the package will be uninstalled and replaced with the updated NRG GMSH ' \
186
195
  'version. Continue? (Y/n):'
187
196
  response = input('\n' + hopout.warn(warning) + '\n')
188
197
  if response.lower() in ['yes', 'y', '']:
189
- PkgsInstallGmsh()
198
+ PkgsInstallGmsh(system,arch,version='nrg')
190
199
  return None
191
200
  else:
192
201
  warning = hopout.warn('Detected Gmsh package uses an outdated CGNS (v3.4). Functionality may be limited.')
@@ -194,7 +203,7 @@ def PkgsCheckGmsh() -> None:
194
203
  return None
195
204
 
196
205
 
197
- def PkgsInstallGmsh():
206
+ def PkgsInstallGmsh(system: str, arch: str, version: str):
198
207
  # Local imports ----------------------------------------
199
208
  import hashlib
200
209
  import tempfile
@@ -202,41 +211,52 @@ def PkgsInstallGmsh():
202
211
  from pyhope.common.common_vars import Gitlab
203
212
  # ------------------------------------------------------
204
213
 
205
- # Gitlab "python-gmsh" access
206
- lfs = 'yes'
207
- lib = 'gmsh-{}-py3-none-linux_x86_64.whl'.format(Gitlab.LIB_VERSION)
208
-
209
- # Create a temporary directory
210
- with tempfile.TemporaryDirectory() as path:
211
- pkgs = os.path.join(path, lib)
212
- curl = [f'curl https://{Gitlab.LIB_GITLAB}/api/v4/projects/{Gitlab.LIB_PROJECT}/repository/files/{lib}/raw?lfs={lfs} --output {pkgs}'] # noqa: E501
213
- subprocess.run(curl, check=True, shell=True)
214
-
215
- # Compare the hash
216
- # > Initialize a new sha256 hash
217
- sha256 = hashlib.sha256()
218
- with open(pkgs, 'rb') as f:
219
- # Read and update hash string value in blocks of 4K
220
- for chunk in iter(lambda: f.read(4096), b""):
221
- sha256.update(chunk)
222
-
223
- if sha256.hexdigest() == Gitlab.LIB_HASH:
224
- hopout.info('Hash matches, installing Gmsh wheel...')
225
- else:
226
- hopout.warning('Hash mismatch, exiting...')
227
- sys.exit(1)
228
-
229
- # Remove the old version
230
- try:
231
- meta = metadata.metadata('gmsh')
232
- if meta is not None:
233
- subprocess.run([sys.executable, '-m', 'pip', 'uninstall', '-y', 'gmsh'], check=True)
214
+ if version == 'nrg':
215
+ # Gitlab "python-gmsh" access
216
+ lfs = 'yes'
217
+ lib = 'gmsh-{}-py3-none-{}_{}.whl'.format(Gitlab.LIB_VERSION,system,arch)
218
+
219
+ # Create a temporary directory
220
+ with tempfile.TemporaryDirectory() as path:
221
+ # On macOS add major version string to filename an rename darwin to macosx in whl filename
222
+ if system == 'darwin':
223
+ mac_ver = platform.mac_ver()[0].split('.')[0]
224
+ lib = lib.replace('darwin','macosx')
225
+ pkgs = os.path.join(path, lib.replace('macosx_',f'macosx_{mac_ver}_0_'))
226
+ else:
227
+ pkgs = os.path.join(path, lib)
228
+
229
+ curl = [f'curl https://{Gitlab.LIB_GITLAB}/api/v4/projects/{Gitlab.LIB_PROJECT}/repository/files/{lib}/raw?lfs={lfs} --output {pkgs}'] # noqa: E501
230
+ subprocess.run(curl, check=True, shell=True)
231
+
232
+ # Compare the hash
233
+ # > Initialize a new sha256 hash
234
+ sha256 = hashlib.sha256()
235
+ with open(pkgs, 'rb') as f:
236
+ # Read and update hash string value in blocks of 4K
237
+ for chunk in iter(lambda: f.read(4096), b""):
238
+ sha256.update(chunk)
239
+
240
+ if sha256.hexdigest() == Gitlab.LIB_SUPPORT[system][arch]:
241
+ hopout.info('Hash matches, installing Gmsh wheel...')
242
+ else:
243
+ hopout.warning('Hash mismatch, exiting...')
244
+ sys.exit(1)
245
+
246
+ # Remove the old version
247
+ try:
248
+ meta = metadata.metadata('gmsh')
249
+ if meta is not None:
250
+ subprocess.run([sys.executable, '-m', 'pip', 'uninstall', '-y', 'gmsh'], check=True)
234
251
 
235
- except metadata.PackageNotFoundError:
236
- pass
252
+ except metadata.PackageNotFoundError:
253
+ pass
237
254
 
255
+ # Install the package in the current environment
256
+ subprocess.run([sys.executable, '-m', 'pip', 'install', pkgs], check=True)
257
+ else:
238
258
  # Install the package in the current environment
239
- subprocess.run([sys.executable, '-m', 'pip', 'install', pkgs], check=True)
259
+ subprocess.run([sys.executable, '-m', 'pip', 'install', 'gmsh'], check=True)
240
260
 
241
261
 
242
262
  # > https://stackoverflow.com/a/5419576/23851165
@@ -25,6 +25,10 @@
25
25
  # ----------------------------------------------------------------------------------------------------------------------------------
26
26
  # Standard libraries
27
27
  # ----------------------------------------------------------------------------------------------------------------------------------
28
+ import importlib.metadata
29
+ import pathlib
30
+ import re
31
+ from typing import Self
28
32
  # ----------------------------------------------------------------------------------------------------------------------------------
29
33
  # Third-party libraries
30
34
  # ----------------------------------------------------------------------------------------------------------------------------------
@@ -38,12 +42,55 @@ from packaging.version import Version
38
42
  # ==================================================================================================================================
39
43
 
40
44
 
45
+ # PEP 318 – Decorators for Functions and Methods
46
+ # > https://peps.python.org/pep-0318/
47
+ def singleton(cls):
48
+ instances = {}
49
+
50
+ def getinstance():
51
+ if cls not in instances:
52
+ instances[cls] = cls()
53
+ return instances[cls]
54
+ return getinstance
55
+
56
+
57
+ @singleton
41
58
  class Common():
42
- __version__ = Version('0.0.2')
43
- __program__ = 'PyHOPE'
59
+ def __init__(self: Self) -> None:
60
+ self._version = self.__version__
61
+ self._program = self.__program__
62
+
63
+ @property
64
+ def __version__(self):
65
+ # Retrieve version from package metadata
66
+ try:
67
+ package = pathlib.Path(__file__).parent.parent.name
68
+ version = importlib.metadata.version(package)
69
+ # Fallback to pyproject.toml
70
+ except importlib.metadata.PackageNotFoundError:
71
+ pyproject = pathlib.Path(__file__).parent.parent.parent / 'pyproject.toml'
72
+ if not pyproject.exists():
73
+ raise FileNotFoundError(f'pyproject.toml not found at {pyproject}')
74
+
75
+ with pyproject.open('r') as p:
76
+ match = re.search(r'version\s*=\s*["\'](.+?)["\']', p.read())
77
+ if not match:
78
+ raise ValueError('Version not found in pyproject.toml')
79
+ version = match.group(1)
80
+
81
+ return Version(version)
82
+
83
+ @property
84
+ def __program__(self):
85
+ return 'PyHOPE'
86
+
87
+ @property
88
+ def program(self):
89
+ return str(self._program)
44
90
 
45
- program: str = str(__program__)
46
- version: str = str(__version__)
91
+ @property
92
+ def version(self):
93
+ return str(self._version)
47
94
 
48
95
 
49
96
  class Gitlab():
@@ -52,7 +99,15 @@ class Gitlab():
52
99
  # LIB_PROJECT = 'libs/python-gmsh'
53
100
  LIB_PROJECT: str = '797'
54
101
  LIB_VERSION: str = '4.13.1'
55
- LIB_HASH: str = '82f655d3a7d97da5b4de06fd0af2198a95b8098a10b3f89edc99764f635c5d4d'
102
+ LIB_SUPPORT = {
103
+ "linux": {
104
+ "x86_64" : "00a42b3b9c9ae51297052a9e9a16646d34743fa0b0742d1998df297c48a212ce",
105
+ "aarch64": "c57abb56759cc476752c21b6b19127888bd3fed67c4a0dd38f6755603d8d6b74"
106
+ },
107
+ "darwin": {
108
+ "arm64" : "ed03477fa3cdee5594a18e46a450acadf63b3d41c7bd575ef71192f221719361"
109
+ }
110
+ }
56
111
 
57
112
 
58
- np_mtp : int # Number of threads for multiprocessing
113
+ np_mtp : int # Number of threads for multiprocessing
@@ -147,10 +147,10 @@ def DefineIO() -> None:
147
147
 
148
148
  CreateSection('Output')
149
149
  CreateStr('ProjectName', help='Name of output files')
150
- CreateIntFromString('OutputFormat', default=0 , help='Mesh output format')
150
+ CreateIntFromString('OutputFormat', default='HDF5', help='Mesh output format')
151
151
  CreateIntOption( 'OutputFormat', number=MeshFormat.FORMAT_HDF5, name='HDF5')
152
152
  CreateIntOption( 'OutputFormat', number=MeshFormat.FORMAT_VTK , name='VTK')
153
- CreateLogical( 'DebugVisu' , default=False, help='Launch the GMSH GUI to visualize the mesh')
153
+ CreateLogical( 'DebugVisu' , default=False , help='Launch the GMSH GUI to visualize the mesh')
154
154
 
155
155
 
156
156
  def InitIO() -> None:
@@ -191,7 +191,7 @@ def IO() -> None:
191
191
 
192
192
  nElems = len(elems)
193
193
  nSides = len(sides)
194
- nNodes = np.sum([s['Nodes'].size for s in elems]) # number of non-unique nodes
194
+ nNodes = np.sum([s.nodes.size for s in elems]) # number of non-unique nodes
195
195
 
196
196
  bcs = mesh_vars.bcs
197
197
  nBCs = len(bcs)
@@ -213,8 +213,9 @@ def IO() -> None:
213
213
 
214
214
  with h5py.File(fname, mode='w') as f:
215
215
  # Store same basic information
216
- f.attrs['HoprVersion' ] = Common.version
217
- f.attrs['HoprVersionInt'] = Common.__version__.micro + Common.__version__.minor*100 + Common.__version__.major*10000
216
+ common = Common()
217
+ f.attrs['HoprVersion' ] = common.version
218
+ f.attrs['HoprVersionInt'] = common.__version__.micro + common.__version__.minor*100 + common.__version__.major*10000
218
219
 
219
220
  # Store mesh information
220
221
  f.attrs['Ngeo' ] = mesh_vars.nGeo
@@ -229,10 +230,10 @@ def IO() -> None:
229
230
 
230
231
  # Store boundary information
231
232
  f.attrs['nBCs' ] = nBCs
232
- bcNames = [f'{s["Name"]:<255}' for s in bcs]
233
+ bcNames = [f'{s.name:<255}' for s in bcs]
233
234
  bcTypes = np.zeros((nBCs, 4), dtype=np.int32)
234
235
  for iBC, bc in enumerate(bcs):
235
- bcTypes[iBC, :] = bc['Type']
236
+ bcTypes[iBC, :] = bc.type
236
237
 
237
238
  f.create_dataset('BCNames' , data=np.bytes_(bcNames))
238
239
  f.create_dataset('BCType' , data=bcTypes)
@@ -265,7 +266,7 @@ def getMeshInfo() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, dict]
265
266
 
266
267
  nElems = len(elems)
267
268
  nSides = len(sides)
268
- nNodes = np.sum([s['Nodes'].size for s in elems]) # number of non-unique nodes
269
+ nNodes = np.sum([s.nodes.size for s in elems]) # number of non-unique nodes
269
270
 
270
271
  # Create the ElemCounter
271
272
  elemCounter = dict()
@@ -278,44 +279,44 @@ def getMeshInfo() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, dict]
278
279
  nodeCount = 0 # elem['Nodes'] contains the unique nodes
279
280
 
280
281
  for iElem, elem in enumerate(elems):
281
- elemInfo[iElem, ELEM.TYPE ] = elem['Type']
282
+ elemInfo[iElem, ELEM.TYPE ] = elem.type
282
283
  elemInfo[iElem, ELEM.ZONE ] = 1 # FIXME
283
284
 
284
285
  elemInfo[iElem, ELEM.FIRSTSIDE] = sideCount
285
- elemInfo[iElem, ELEM.LASTSIDE ] = sideCount + len(elem['Sides'])
286
- sideCount += len(elem['Sides'])
286
+ elemInfo[iElem, ELEM.LASTSIDE ] = sideCount + len(elem.sides)
287
+ sideCount += len(elem.sides)
287
288
 
288
289
  elemInfo[iElem, ELEM.FIRSTNODE] = nodeCount
289
- elemInfo[iElem, ELEM.LASTNODE ] = nodeCount + len(elem['Nodes'])
290
- nodeCount += len(elem['Nodes'])
290
+ elemInfo[iElem, ELEM.LASTNODE ] = nodeCount + len(elem.nodes)
291
+ nodeCount += len(elem.nodes)
291
292
 
292
- elemCounter[elem['Type']] += 1
293
+ elemCounter[elem.type] += 1
293
294
 
294
295
  # Fill the SideInfo
295
296
  sideInfo = np.zeros((nSides, SIDE.INFOSIZE), dtype=np.int32)
296
297
 
297
298
  for iSide, side in enumerate(sides):
298
- sideInfo[iSide, SIDE.TYPE ] = side['Type' ]
299
- sideInfo[iSide, SIDE.ID ] = side['GlobalSideID']
299
+ sideInfo[iSide, SIDE.TYPE ] = side.sideType
300
+ sideInfo[iSide, SIDE.ID ] = side.globalSideID
300
301
  # Connected sides
301
- if 'Connection' in side:
302
- nbSideID = side['Connection']
303
- nbElemID = sides[nbSideID]['ElemID'] + 1 # Python -> HOPR index
302
+ if side.connection is not None:
303
+ nbSideID = side.connection
304
+ nbElemID = sides[nbSideID].elemID + 1 # Python -> HOPR index
304
305
  sideInfo[iSide, SIDE.NBELEMID ] = nbElemID
305
- if side['Flip'] == 0: # Master side
306
- sideInfo[iSide, SIDE.NBLOCSIDE_FLIP] = sides[nbSideID]['LocSide']*10
306
+ if side.flip == 0: # Master side
307
+ sideInfo[iSide, SIDE.NBLOCSIDE_FLIP] = sides[nbSideID].locSide*10
307
308
  else:
308
- sideInfo[iSide, SIDE.NBLOCSIDE_FLIP] = sides[nbSideID]['LocSide']*10 + side['Flip']
309
+ sideInfo[iSide, SIDE.NBLOCSIDE_FLIP] = sides[nbSideID].locSide*10 + side.flip
309
310
 
310
311
  # Periodic sides still have a BCID
311
- if 'BCID' in side:
312
- sideInfo[iSide, SIDE.BCID ] = side['BCID'] + 1
312
+ if side.bcid is not None:
313
+ sideInfo[iSide, SIDE.BCID ] = side.bcid + 1
313
314
  else:
314
315
  sideInfo[iSide, SIDE.BCID ] = 0
315
316
  else:
316
317
  sideInfo[iSide, SIDE.NBELEMID ] = 0
317
318
  sideInfo[iSide, SIDE.NBLOCSIDE_FLIP] = 0
318
- sideInfo[iSide, SIDE.BCID ] = side['BCID'] + 1
319
+ sideInfo[iSide, SIDE.BCID ] = side.bcid + 1
319
320
 
320
321
  # Fill the NodeInfo
321
322
  nodeInfo = np.zeros((ELEM.INFOSIZE, nNodes), dtype=np.int32)
@@ -326,11 +327,11 @@ def getMeshInfo() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, dict]
326
327
 
327
328
  for iElem, elem in enumerate(elems):
328
329
  # Mesh coordinates are stored in meshIO sorting
329
- linMap = LINMAP(elem['Type'], order=mesh_vars.nGeo)
330
+ linMap = LINMAP(elem.type, order=mesh_vars.nGeo)
330
331
  # meshio accesses them in their own ordering
331
332
  # > need to reverse the mapping
332
333
  mapLin = {k: v for v, k in enumerate(linMap)}
333
- elemNodes = elem['Nodes']
334
+ elemNodes = elem.nodes
334
335
 
335
336
  # Access the actual nodeCoords and reorder them
336
337
  for iNode, nodeID in enumerate(elemNodes):
@@ -44,26 +44,32 @@ def DefineMesh() -> None:
44
44
  """
45
45
  # Local imports ----------------------------------------
46
46
  from pyhope.readintools.readintools import CreateInt, CreateIntArray, CreateRealArray, CreateSection, CreateStr, CreateLogical
47
+ from pyhope.readintools.readintools import CreateIntFromString, CreateIntOption
48
+ from pyhope.mesh.mesh_vars import ELEMTYPE
47
49
  # ------------------------------------------------------
48
50
 
49
51
  CreateSection('Mesh')
50
- CreateInt( 'Mode', help='Mesh generation mode (1 - Internal, 2 - External [MeshIO])')
52
+ CreateInt( 'Mode', help='Mesh generation mode (1 - Internal, 2 - External [MeshIO])')
51
53
  # Internal mesh generator
52
- CreateInt( 'nZones', help='Number of mesh zones')
53
- CreateRealArray('Corner', 24, multiple=True, help='Corner node positions: (/ x_1,y_1,z_1,, x_2,y_2,z_2,, '
54
- '... ,, x_8,y_8,z_8/)') # noqa: E127
55
- CreateIntArray( 'nElems', 3, multiple=True, help='Number of elements in each direction')
56
- CreateStr( 'BoundaryName', multiple=True, help='Name of domain boundary')
57
- CreateIntArray( 'BoundaryType', 4, multiple=True, help='(/ Type, curveIndex, State, alpha /)')
58
- CreateIntArray( 'BCIndex', 6, multiple=True, help='Index of BC for each boundary face')
59
- CreateRealArray('vv', 3, multiple=True, help='Vector for periodic BC')
54
+ CreateInt( 'nZones', help='Number of mesh zones')
55
+ CreateRealArray('Corner', 24, multiple=True, help='Corner node positions: (/ x_1,y_1,z_1,, x_2,y_2,z_2,, '
56
+ '... ,, x_8,y_8,z_8/)') # noqa: E127
57
+ CreateIntArray( 'nElems', 3, multiple=True, help='Number of elements in each direction')
58
+ CreateIntFromString('ElemType' , multiple=True, default='hexahedron', help='Element type')
59
+ for key, val in ELEMTYPE.name.items():
60
+ CreateIntOption('ElemType', number=val, name=key)
61
+ CreateStr( 'BoundaryName', multiple=True, help='Name of domain boundary')
62
+ CreateIntArray( 'BoundaryType', 4, multiple=True, help='(/ Type, curveIndex, State, alpha /)')
63
+ CreateIntArray( 'BCIndex', 6, multiple=True, help='Index of BC for each boundary face')
64
+ CreateRealArray('vv', 3, multiple=True, help='Vector for periodic BC')
60
65
  # External mesh readin through GMSH
61
- CreateStr( 'Filename', multiple=True, help='Name of external mesh file')
62
- CreateLogical( 'MeshIsAlreadyCurved',default=False, help='Enables mesh agglomeration')
66
+ CreateStr( 'Filename', multiple=True, help='Name of external mesh file')
67
+ CreateLogical( 'MeshIsAlreadyCurved', default=False, help='Enables mesh agglomeration')
63
68
  # Common settings
64
- CreateInt( 'BoundaryOrder', default=2, help='Order of spline-reconstruction for curved surfaces')
65
- CreateLogical( 'doSortIJK', default=False, help='Sort the mesh elements along the I,J,K directions')
66
- CreateLogical( 'CheckElemJacobians', default=True, help='Check the Jacobian and scaled Jacobian for each element')
69
+ CreateInt( 'NGeo' , default=1, help='Order of spline-reconstruction for curved surfaces')
70
+ CreateInt( 'BoundaryOrder', default=2, help='Order of spline-reconstruction for curved surfaces (legacy)')
71
+ CreateLogical( 'doSortIJK', default=False, help='Sort the mesh elements along the I,J,K directions')
72
+ CreateLogical( 'CheckElemJacobians', default=True, help='Check the Jacobian and scaled Jacobian for each element')
67
73
 
68
74
 
69
75
  def InitMesh() -> None:
@@ -72,17 +78,28 @@ def InitMesh() -> None:
72
78
  # Local imports ----------------------------------------
73
79
  import pyhope.mesh.mesh_vars as mesh_vars
74
80
  import pyhope.output.output as hopout
75
- from pyhope.readintools.readintools import GetInt
81
+ from pyhope.readintools.readintools import GetInt, CountOption
76
82
  # ------------------------------------------------------
77
83
 
78
84
  hopout.separator()
79
85
  hopout.info('INIT MESH...')
80
86
 
81
87
  mesh_vars.mode = GetInt('Mode')
82
- mesh_vars.nGeo = GetInt('BoundaryOrder') - 1
83
- if mesh_vars.nGeo < 1:
84
- hopout.warning('Effective boundary order < 1. Try increasing the BoundaryOrder parameter!')
88
+
89
+ NGeo = GetInt('NGeo') if CountOption('NGeo') else None
90
+ BCOrder = GetInt('BoundaryOrder') if CountOption('BoundaryOrder') else None
91
+
92
+ if not NGeo and not BCOrder:
93
+ mesh_vars.nGeo = 1
94
+ elif NGeo and BCOrder and NGeo != BCOrder - 1:
95
+ hopout.warning('NGeo / BoundaryOrder must be equal to NGeo + 1!')
85
96
  sys.exit(1)
97
+ else:
98
+ mesh_vars.nGeo = NGeo or (BCOrder - 1)
99
+
100
+ if mesh_vars.nGeo < 1:
101
+ hopout.warning('Effective boundary order < 1. Try increasing the NGeo / BoundaryOrder parameter!')
102
+ sys.exit(1)
86
103
 
87
104
  hopout.info('INIT MESH DONE!')
88
105