PyHOPE 0.0.4__tar.gz → 0.0.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 (65) hide show
  1. {pyhope-0.0.4 → pyhope-0.0.7}/PKG-INFO +42 -26
  2. {pyhope-0.0.4 → pyhope-0.0.7}/README.md +38 -20
  3. pyhope-0.0.7/pyhope/__main__.py +43 -0
  4. pyhope-0.0.4/pyhope/basis/basis_jacobian.py → pyhope-0.0.7/pyhope/basis/basis_basis.py +62 -202
  5. pyhope-0.0.7/pyhope/basis/basis_jacobian.py +190 -0
  6. pyhope-0.0.7/pyhope/basis/basis_watertight.py +264 -0
  7. pyhope-0.0.7/pyhope/common/common.py +200 -0
  8. pyhope-0.0.7/pyhope/common/common_parallel.py +84 -0
  9. pyhope-0.0.7/pyhope/common/common_progress.py +64 -0
  10. pyhope-0.0.7/pyhope/common/common_tools.py +78 -0
  11. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/common/common_vars.py +20 -16
  12. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/config/config.py +1 -0
  13. pyhope-0.0.4/pyhope/common/common.py → pyhope-0.0.7/pyhope/gmsh/gmsh_install.py +37 -169
  14. pyhope-0.0.7/pyhope/gmsh/gmsh_override.py +53 -0
  15. pyhope-0.0.4/pyhope/io/io_cgns.py → pyhope-0.0.7/pyhope/io/formats/cgns.py +175 -173
  16. pyhope-0.0.7/pyhope/io/formats/gmsh.py +256 -0
  17. pyhope-0.0.7/pyhope/io/formats/meshio.py +610 -0
  18. pyhope-0.0.7/pyhope/io/formats/vtk.py +267 -0
  19. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/io/io.py +64 -129
  20. pyhope-0.0.7/pyhope/io/io_vars.py +106 -0
  21. pyhope-0.0.7/pyhope/mesh/connect/connect.py +631 -0
  22. pyhope-0.0.7/pyhope/mesh/connect/connect_mortar.py +622 -0
  23. pyhope-0.0.7/pyhope/mesh/elements/elements_ordering.py +119 -0
  24. pyhope-0.0.7/pyhope/mesh/elements/elements_shapefunctions.py +113 -0
  25. pyhope-0.0.7/pyhope/mesh/mesh.py +192 -0
  26. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/mesh/mesh_builtin.py +149 -39
  27. pyhope-0.0.7/pyhope/mesh/mesh_common.py +520 -0
  28. pyhope-0.0.7/pyhope/mesh/mesh_duplicates.py +91 -0
  29. pyhope-0.0.7/pyhope/mesh/mesh_external.py +128 -0
  30. pyhope-0.0.7/pyhope/mesh/mesh_orient.py +155 -0
  31. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/mesh/mesh_sides.py +52 -28
  32. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/mesh/mesh_sort.py +99 -104
  33. pyhope-0.0.7/pyhope/mesh/mesh_vars.py +259 -0
  34. pyhope-0.0.7/pyhope/mesh/reader/reader_gmsh.py +597 -0
  35. pyhope-0.0.7/pyhope/mesh/reader/reader_hopr.py +271 -0
  36. pyhope-0.0.7/pyhope/mesh/topology/mesh_serendipity.py +250 -0
  37. pyhope-0.0.7/pyhope/mesh/topology/mesh_splittohex.py +369 -0
  38. pyhope-0.0.7/pyhope/mesh/topology/mesh_topology.py +551 -0
  39. pyhope-0.0.7/pyhope/mesh/transform/mesh_transform.py +252 -0
  40. pyhope-0.0.7/pyhope/mesh/transform/templates/convtest.py +58 -0
  41. pyhope-0.0.4/pyhope/io/io_vars.py → pyhope-0.0.7/pyhope/mesh/transform/templates/default.py +7 -6
  42. pyhope-0.0.7/pyhope/mesh/transform/templates/phill.py +129 -0
  43. pyhope-0.0.7/pyhope/meshio/meshio_convert.py +104 -0
  44. pyhope-0.0.7/pyhope/meshio/meshio_ordering.py +162 -0
  45. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/output/output.py +14 -11
  46. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/readintools/commandline.py +18 -12
  47. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/readintools/readintools.py +59 -25
  48. pyhope-0.0.4/pyhope/pyhope.py → pyhope-0.0.7/pyhope/script/pyhope_cli.py +28 -6
  49. {pyhope-0.0.4 → pyhope-0.0.7}/pyproject.toml +28 -6
  50. pyhope-0.0.4/pyhope/__main__.py +0 -27
  51. pyhope-0.0.4/pyhope/io/io_meshio.py +0 -247
  52. pyhope-0.0.4/pyhope/io/io_vtk.py +0 -266
  53. pyhope-0.0.4/pyhope/mesh/mesh.py +0 -162
  54. pyhope-0.0.4/pyhope/mesh/mesh_common.py +0 -242
  55. pyhope-0.0.4/pyhope/mesh/mesh_connect.py +0 -405
  56. pyhope-0.0.4/pyhope/mesh/mesh_external.py +0 -496
  57. pyhope-0.0.4/pyhope/mesh/mesh_vars.py +0 -204
  58. {pyhope-0.0.4 → pyhope-0.0.7}/LICENSE.md +0 -0
  59. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/basis/__init__.py +0 -0
  60. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/common/__init__.py +0 -0
  61. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/config/__init__.py +0 -0
  62. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/io/__init__.py +0 -0
  63. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/mesh/__init__.py +0 -0
  64. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/output/__init__.py +0 -0
  65. {pyhope-0.0.4 → pyhope-0.0.7}/pyhope/readintools/__init__.py +0 -0
@@ -1,19 +1,16 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: PyHOPE
3
- Version: 0.0.4
3
+ Version: 0.0.7
4
4
  Summary: Python High-Order Preprocessing Environment
5
- Home-page: https://numericsresearchgroup.org
6
5
  License: GPL-3.0-only
7
6
  Keywords: PyHOPE,mesh generator
8
7
  Author: Numerics Research Group (NRG)
9
8
  Author-email: numerics@iag.uni-stuttgart.de
10
- Requires-Python: >=3.8
9
+ Requires-Python: >=3.10
11
10
  Classifier: Development Status :: 3 - Alpha
12
11
  Classifier: Operating System :: POSIX :: Linux
13
12
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
14
13
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
- Classifier: Programming Language :: Python :: 3.9
17
14
  Classifier: Programming Language :: Python :: 3.10
18
15
  Classifier: Programming Language :: Python :: 3.11
19
16
  Classifier: Programming Language :: Python :: 3.12
@@ -26,8 +23,9 @@ Requires-Dist: meshio
26
23
  Requires-Dist: numpy (>=2.0.0)
27
24
  Requires-Dist: packaging
28
25
  Requires-Dist: plotext
29
- Requires-Dist: pygmsh
30
26
  Requires-Dist: scipy
27
+ Requires-Dist: typing-extensions
28
+ Project-URL: Homepage, https://numericsresearchgroup.org
31
29
  Project-URL: Repository, https://gitlab.iag.uni-stuttgart.de/flexi/codes/pyhope
32
30
  Description-Content-Type: text/markdown
33
31
 
@@ -35,7 +33,7 @@ PyHOPE (Python High-Order Preprocessing Environment) is an open-source Python fr
35
33
 
36
34
  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.
37
35
 
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)
36
+ 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).
39
37
 
40
38
  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).
41
39
 
@@ -55,21 +53,17 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
55
53
  ┃ P y H O P E — Python High-Order Preprocessing Environment
56
54
  ┃ PyHOPE version x.x.x
57
55
  ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
58
- ├─────────────────────────────────────────────
59
56
  │ INIT PROGRAM...
60
- │ nThreads │ 4 │ DEFAULT │
61
- │ INIT PROGRAM DONE!
57
+ │ nThreads │ 10 │ DEFAULT │
62
58
  ├─────────────────────────────────────────────
63
59
  │ INIT OUTPUT...
64
60
  │ ProjectName │ 1-01-cartbox │ *CUSTOM │
65
61
  │ OutputFormat │ 0 [HDF5] │ *CUSTOM │
66
62
  │ DebugVisu │ F │ *CUSTOM │
67
- │ INIT OUTPUT DONE!
68
63
  ├─────────────────────────────────────────────
69
64
  │ INIT MESH...
70
- │ Mode │ 1 │ *CUSTOM │
71
- BoundaryOrder2DEFAULT
72
- │ INIT MESH DONE!
65
+ │ Mode │ 1 [Internal] │ *CUSTOM │
66
+ NGeo4*CUSTOM
73
67
  ├─────────────────────────────────────────────
74
68
  │ GENERATE MESH...
75
69
  ├────
@@ -77,6 +71,7 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
77
71
  ├── Generating zone 1
78
72
  │ Corner │ (/0.,0.,0. ,,1.,0.,0. ,,1.,1... │ *CUSTOM │
79
73
  │ nElems │ (/8,8,8/) │ *CUSTOM │
74
+ │ StretchType │ (/0,0,0/) │ DEFAULT │
80
75
  │ BCIndex │ (/1,2,3,4,5,6/) │ *CUSTOM │
81
76
  ├────
82
77
  ├── Setting boundary conditions
@@ -94,28 +89,51 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
94
89
  │ BoundaryName │ BC_zplus │ *CUSTOM │
95
90
  │ BoundaryType │ (/9,0,0,0/) │ *CUSTOM │
96
91
  ├────
92
+ │ vv │ (/1., 0., 0./) │ *CUSTOM │
93
+ │ vv │ (/0., 1., 0./) │ *CUSTOM │
94
+ │ vv │ (/0., 0., 1./) │ *CUSTOM │
95
+ ├────
96
+ │ ElemType │ 108 [hexahedron] │ *CUSTOM │
97
+ ├────
97
98
  ├── Generated mesh with 512 cells
99
+ ├─────────────────────────────────────────────
100
+ ├── BUILD DATA STRUCTURE...
101
+ ├────
102
+ ├── Removing duplicate points
103
+ ├── Ensuring normals point outward
104
+ ├────
105
+ │ CheckSurfaceNormals │ True │ DEFAULT │
106
+ │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (24000.00/s)
98
107
  ├────
99
- GENERATE MESH DONE!
108
+ ├── Generating sides
100
109
  ├─────────────────────────────────────────────
110
+ │ SORT MESH...
111
+ ├────
101
112
  │ doSortIJK │ False │ DEFAULT │
102
113
  ├────
103
114
  ├── Sorting elements along space-filling curve
104
115
  ├─────────────────────────────────────────────
105
116
  │ CONNECT MESH...
106
- ├─────────────────────────────────────────────
107
117
  ├────
108
- Number of sides : 3072
109
- Number of inner sides : 2688
110
- │ Number of boundary sides : 384
111
- │ Number of periodic sides : 0
118
+ doPeriodicCorrect True │ DEFAULT │
119
+ doMortars True │ DEFAULT │
112
120
  ├────
113
- CONNECT MESH DONE!
121
+ Number of sides : 3072
122
+ │ Number of inner sides : 2688
123
+ │ Number of mortar sides (big) : 0
124
+ │ Number of mortar sides (small) : 0
125
+ │ Number of boundary sides : 384
126
+ │ Number of periodic sides : 0
127
+ ├─────────────────────────────────────────────
128
+ │ CHECK WATERTIGHTNESS...
129
+ ├────
130
+ │ CheckWatertightness │ True │ DEFAULT │
131
+ │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (24000.00/s)
114
132
  ├─────────────────────────────────────────────
115
133
  │ CHECK JACOBIANS...
116
134
  ├────
117
135
  │ CheckElemJacobians │ True │ DEFAULT │
118
- │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (30004.72/s)
136
+ │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (24000.00/s)
119
137
  ├────
120
138
  │ Scaled Jacobians
121
139
  ├─────────────────
@@ -134,13 +152,11 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
134
152
  ├─────────────────────────────────────────────
135
153
  │ OUTPUT MESH...
136
154
  ├────
137
- Planar-faced Hexahedra : 512
155
+ Curved Hexahedra : 512
138
156
  ├────
139
157
  ├── Writing HDF5 mesh to "1-01-cartbox_mesh.h5"
140
- ├────
141
- │ OUTPUT MESH DONE!
142
158
  ┢━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
143
- ┃ PyHOPE completed in [0.18 sec]
159
+ ┃ PyHOPE completed in [0.25 sec]
144
160
  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
145
161
  ```
146
162
 
@@ -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 shares 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
 
@@ -22,21 +22,17 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
22
22
  ┃ P y H O P E — Python High-Order Preprocessing Environment
23
23
  ┃ PyHOPE version x.x.x
24
24
  ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25
- ├─────────────────────────────────────────────
26
25
  │ INIT PROGRAM...
27
- │ nThreads │ 4 │ DEFAULT │
28
- │ INIT PROGRAM DONE!
26
+ │ nThreads │ 10 │ DEFAULT │
29
27
  ├─────────────────────────────────────────────
30
28
  │ INIT OUTPUT...
31
29
  │ ProjectName │ 1-01-cartbox │ *CUSTOM │
32
30
  │ OutputFormat │ 0 [HDF5] │ *CUSTOM │
33
31
  │ DebugVisu │ F │ *CUSTOM │
34
- │ INIT OUTPUT DONE!
35
32
  ├─────────────────────────────────────────────
36
33
  │ INIT MESH...
37
- │ Mode │ 1 │ *CUSTOM │
38
- BoundaryOrder2DEFAULT
39
- │ INIT MESH DONE!
34
+ │ Mode │ 1 [Internal] │ *CUSTOM │
35
+ NGeo4*CUSTOM
40
36
  ├─────────────────────────────────────────────
41
37
  │ GENERATE MESH...
42
38
  ├────
@@ -44,6 +40,7 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
44
40
  ├── Generating zone 1
45
41
  │ Corner │ (/0.,0.,0. ,,1.,0.,0. ,,1.,1... │ *CUSTOM │
46
42
  │ nElems │ (/8,8,8/) │ *CUSTOM │
43
+ │ StretchType │ (/0,0,0/) │ DEFAULT │
47
44
  │ BCIndex │ (/1,2,3,4,5,6/) │ *CUSTOM │
48
45
  ├────
49
46
  ├── Setting boundary conditions
@@ -61,28 +58,51 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
61
58
  │ BoundaryName │ BC_zplus │ *CUSTOM │
62
59
  │ BoundaryType │ (/9,0,0,0/) │ *CUSTOM │
63
60
  ├────
61
+ │ vv │ (/1., 0., 0./) │ *CUSTOM │
62
+ │ vv │ (/0., 1., 0./) │ *CUSTOM │
63
+ │ vv │ (/0., 0., 1./) │ *CUSTOM │
64
+ ├────
65
+ │ ElemType │ 108 [hexahedron] │ *CUSTOM │
66
+ ├────
64
67
  ├── Generated mesh with 512 cells
68
+ ├─────────────────────────────────────────────
69
+ ├── BUILD DATA STRUCTURE...
70
+ ├────
71
+ ├── Removing duplicate points
72
+ ├── Ensuring normals point outward
73
+ ├────
74
+ │ CheckSurfaceNormals │ True │ DEFAULT │
75
+ │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (24000.00/s)
65
76
  ├────
66
- GENERATE MESH DONE!
77
+ ├── Generating sides
67
78
  ├─────────────────────────────────────────────
79
+ │ SORT MESH...
80
+ ├────
68
81
  │ doSortIJK │ False │ DEFAULT │
69
82
  ├────
70
83
  ├── Sorting elements along space-filling curve
71
84
  ├─────────────────────────────────────────────
72
85
  │ CONNECT MESH...
73
- ├─────────────────────────────────────────────
74
86
  ├────
75
- Number of sides : 3072
76
- Number of inner sides : 2688
77
- │ Number of boundary sides : 384
78
- │ Number of periodic sides : 0
87
+ doPeriodicCorrect True │ DEFAULT │
88
+ doMortars True │ DEFAULT │
79
89
  ├────
80
- CONNECT MESH DONE!
90
+ Number of sides : 3072
91
+ │ Number of inner sides : 2688
92
+ │ Number of mortar sides (big) : 0
93
+ │ Number of mortar sides (small) : 0
94
+ │ Number of boundary sides : 384
95
+ │ Number of periodic sides : 0
96
+ ├─────────────────────────────────────────────
97
+ │ CHECK WATERTIGHTNESS...
98
+ ├────
99
+ │ CheckWatertightness │ True │ DEFAULT │
100
+ │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (24000.00/s)
81
101
  ├─────────────────────────────────────────────
82
102
  │ CHECK JACOBIANS...
83
103
  ├────
84
104
  │ CheckElemJacobians │ True │ DEFAULT │
85
- │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (30004.72/s)
105
+ │ Processing Elements |█████████████████████████████████| 512/512 [100%] in 0.0s (24000.00/s)
86
106
  ├────
87
107
  │ Scaled Jacobians
88
108
  ├─────────────────
@@ -101,12 +121,10 @@ $ pyhope tutorials/1-01-cartbox/parameter.ini
101
121
  ├─────────────────────────────────────────────
102
122
  │ OUTPUT MESH...
103
123
  ├────
104
- Planar-faced Hexahedra : 512
124
+ Curved Hexahedra : 512
105
125
  ├────
106
126
  ├── Writing HDF5 mesh to "1-01-cartbox_mesh.h5"
107
- ├────
108
- │ OUTPUT MESH DONE!
109
127
  ┢━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
110
- ┃ PyHOPE completed in [0.18 sec]
128
+ ┃ PyHOPE completed in [0.25 sec]
111
129
  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
112
130
  ```
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #
4
+ # SPDX-License-Identifier: GPL-3.0-or-later
5
+ #
6
+ # This file is part of PyHOPE
7
+ #
8
+ # Copyright (c) 2024 Numerics Research Group, University of Stuttgart, Prof. Andrea Beck
9
+ #
10
+ # PyHOPE is free software: you can redistribute it and/or modify it under the
11
+ # terms of the GNU General Public License as published by the Free Software
12
+ # Foundation, either version 3 of the License, or (at your option) any later
13
+ # version.
14
+ #
15
+ # PyHOPE is distributed in the hope that it will be useful, but WITHOUT ANY
16
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License along with
20
+ # PyHOPE. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+ # ==================================================================================================================================
24
+ # Mesh generation library
25
+ # ==================================================================================================================================
26
+ # ----------------------------------------------------------------------------------------------------------------------------------
27
+ # Standard libraries
28
+ # ----------------------------------------------------------------------------------------------------------------------------------
29
+ # ----------------------------------------------------------------------------------------------------------------------------------
30
+ # Third-party libraries
31
+ # ----------------------------------------------------------------------------------------------------------------------------------
32
+ # ----------------------------------------------------------------------------------------------------------------------------------
33
+ # Local imports
34
+ # ----------------------------------------------------------------------------------------------------------------------------------
35
+ from pyhope.script.pyhope_cli import main
36
+ # ==================================================================================================================================
37
+
38
+
39
+ if __name__ == '__main__':
40
+ """ Main routine of PyHOPE
41
+ > __main__ to execute as a module
42
+ """
43
+ main()
@@ -25,11 +25,6 @@
25
25
  # ----------------------------------------------------------------------------------------------------------------------------------
26
26
  # Standard libraries
27
27
  # ----------------------------------------------------------------------------------------------------------------------------------
28
- from multiprocessing import Pool, Queue
29
- import plotext as plt
30
- from alive_progress import alive_bar
31
- from typing import Tuple
32
- import threading
33
28
  # ----------------------------------------------------------------------------------------------------------------------------------
34
29
  # Third-party libraries
35
30
  # ----------------------------------------------------------------------------------------------------------------------------------
@@ -40,7 +35,7 @@ import numpy as np
40
35
  # ==================================================================================================================================
41
36
 
42
37
 
43
- def legendre_gauss_lobatto_nodes(order: int) -> Tuple[np.ndarray, np.ndarray]:
38
+ def legendre_gauss_lobatto_nodes(order: int) -> tuple[np.ndarray, np.ndarray]:
44
39
  """ Return Legendre-Gauss-Lobatto nodes and weights for a given order in 1D
45
40
  """
46
41
  order -= 1
@@ -74,14 +69,14 @@ def legendre_gauss_lobatto_nodes(order: int) -> Tuple[np.ndarray, np.ndarray]:
74
69
  return nodes, weights
75
70
 
76
71
 
77
- def legendre_gauss_nodes(order: int) -> Tuple[np.ndarray, np.ndarray]:
72
+ def legendre_gauss_nodes(order: int) -> tuple[np.ndarray, np.ndarray]:
78
73
  """ Return Legendre-Gauss nodes and weights for a given order in 1D
79
74
  """
80
75
  nodes, weights = np.polynomial.legendre.leggauss(order)
81
76
  return nodes, weights
82
77
 
83
78
 
84
- def barycentric_weights(order: int, xGP: np.ndarray) -> np.ndarray:
79
+ def barycentric_weights(_: int, xGP: np.ndarray) -> np.ndarray:
85
80
  """ Compute the barycentric weights for a given node set
86
81
  > Algorithm 30, Kopriva
87
82
  """
@@ -121,20 +116,20 @@ def lagrange_interpolation_polys(x: float, order: int, xGP: np.ndarray, wBary: n
121
116
  > Algorithm 34, Kopriva
122
117
  """
123
118
  # Equal points need special treatment
124
- L = np.zeros(order)
119
+ lagrange = np.zeros(order)
125
120
  for iGP in range(order):
126
121
  if abs(x - xGP[iGP]) < 1.E-14:
127
- L[iGP] = 1
128
- return L
122
+ lagrange[iGP] = 1
123
+ return lagrange
129
124
 
130
125
  tmp = 0.
131
126
  for iGP in range(order):
132
- L[iGP] = wBary[iGP] / (x-xGP[iGP])
133
- tmp += L[iGP]
127
+ lagrange[iGP] = wBary[iGP] / (x-xGP[iGP])
128
+ tmp += lagrange[iGP]
134
129
 
135
130
  # Normalize
136
- L = L/tmp
137
- return L
131
+ lagrange = lagrange/tmp
132
+ return lagrange
138
133
 
139
134
 
140
135
  def calc_vandermonde(n_In: int, n_Out: int, wBary_In: np.ndarray, xi_In: np.ndarray, xi_Out: np.ndarray) -> np.ndarray:
@@ -164,23 +159,40 @@ def change_basis_3D(Vdm: np.ndarray, x3D_In: np.ndarray) -> np.ndarray:
164
159
 
165
160
  # Third contraction along the kN_In axis (axis 1 of Vdm, axis 3 of x3D_Buf2)
166
161
  x3D_Out = np.tensordot(Vdm, x3D_Buf2, axes=(1, 3))
167
- x3D_Out = np.moveaxis(x3D_Out , 0, 1) # Correct the shape to (dim1, n_Out, n_Out, n_Out)
162
+ x3D_Out = np.moveaxis(x3D_Out , 0, 3) # Correct the shape to (dim1, n_Out, n_Out, n_Out)
168
163
 
169
164
  return x3D_Out
170
165
 
171
166
 
167
+ def change_basis_2D(Vdm: np.ndarray, x2D_In: np.ndarray) -> np.ndarray:
168
+ """ Interpolate a 2D tensor product Lagrange basis defined by (N_in+1) 1D interpolation point positions xi_In(0:N_In)
169
+ to another 2D tensor product node positions (number of nodes N_out+1)
170
+ defined by (N_out+1) interpolation point positions xi_Out(0:N_Out)
171
+ xi is defined in the 1D reference element xi=[-1,1]
172
+ """
173
+ # First contraction along the iN_In axis (axis 1 of Vdm, axis 1 of x2D_In)
174
+ x2D_Buf1 = np.tensordot(Vdm, x2D_In, axes=(1, 1))
175
+ x2D_Buf1 = np.moveaxis(x2D_Buf1, 0, 1) # Correct the shape to (dim1, n_Out, n_In, n_In)
176
+
177
+ # Second contraction along the jN_In axis (axis 1 of Vdm, axis 2 of x2D_Buf1)
178
+ x2D_Out = np.tensordot(Vdm, x2D_Buf1, axes=(1, 2))
179
+ x2D_Out = np.moveaxis(x2D_Out, 0, 2) # Correct the shape to (dim1, n_Out, n_Out, n_In)
180
+
181
+ return x2D_Out
182
+
183
+
172
184
  def evaluate_jacobian(xGeo_In: np.ndarray, VdmGLtoAP: np.ndarray, D_EqToGL: np.ndarray) -> np.ndarray:
173
185
  # Perform tensor contraction for the first derivative (Xi direction)
174
186
  dXdXiGL = np.tensordot(D_EqToGL, xGeo_In, axes=(1, 1))
175
- dXdXiGL = np.moveaxis(dXdXiGL , 0, -3) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
187
+ dXdXiGL = np.moveaxis(dXdXiGL , 1, 0) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
176
188
 
177
189
  # Perform tensor contraction for the second derivative (Eta direction)
178
190
  dXdEtaGL = np.tensordot(D_EqToGL, xGeo_In, axes=(1, 2))
179
- dXdEtaGL = np.moveaxis(dXdEtaGL , 0, -3) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
191
+ dXdEtaGL = np.moveaxis(dXdEtaGL , 1, 0) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
180
192
 
181
193
  # Perform tensor contraction for the third derivative (Zeta direction)
182
194
  dXdZetaGL = np.tensordot(D_EqToGL, xGeo_In, axes=(1, 3))
183
- dXdZetaGL = np.moveaxis(dXdZetaGL, 0, -3) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
195
+ dXdZetaGL = np.moveaxis(dXdZetaGL, 1, 0) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
184
196
 
185
197
  # Change basis for each direction
186
198
  dXdXiAP = change_basis_3D(VdmGLtoAP, dXdXiGL )
@@ -196,186 +208,34 @@ def evaluate_jacobian(xGeo_In: np.ndarray, VdmGLtoAP: np.ndarray, D_EqToGL: np.n
196
208
  return jacOut
197
209
 
198
210
 
199
- def plot_histogram(data: np.ndarray) -> None:
200
- """ Plot a histogram of all Jacobians
201
- """
202
- # Local imports ----------------------------------------
203
- import pyhope.output.output as hopout
204
- from pyhope.output.output import STD_LENGTH
205
- # ------------------------------------------------------
206
-
207
- ticks = ['│<0.0 │',
208
- '│ 0.0-0.1 │',
209
- '│ 0.1-0.2 │',
210
- '│ 0.2-0.3 │',
211
- '│ 0.3-0.4 │',
212
- '│ 0.4-0.5 │',
213
- '│ 0.5-0.6 │',
214
- '│ 0.6-0.7 │',
215
- '│ 0.7-0.8 │',
216
- '│ 0.8-0.9 │',
217
- # '│ 0.9-0.99 │',
218
- '│>0.9-1.0 │']
219
-
220
- # Define the bins for categorizing jacobians
221
- # bins = [ -np.inf, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.99, np.inf]
222
- bins = [ -np.inf, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, np.inf]
223
-
224
- # Use np.histogram to count jacobians in the defined bins
225
- count, _ = np.histogram(data, bins=bins)
226
-
227
- # Setup plot
228
- hopout.sep()
229
- hopout.info('Scaled Jacobians')
230
- hopout.separator(18)
231
- plt.simple_bar(ticks, count, width=STD_LENGTH)
232
- plt.show()
233
- hopout.separator(18)
234
-
235
-
236
- def process_chunk(chunk):
237
- """Process a chunk of elements by evaluating the Jacobian for each
238
- """
239
- chunk_results = []
240
- for elem in chunk:
241
- # nodeCoords, nGeoRef, VdmGLtoAP, D_EqToGL = elem
242
- nodeCoords, _, VdmGLtoAP, D_EqToGL = elem
243
- jac = evaluate_jacobian(nodeCoords, VdmGLtoAP, D_EqToGL)
244
- maxJac = np.max(np.abs(jac))
245
- minJac = np.min(jac)
246
- chunk_results.append(minJac / maxJac)
247
- return chunk_results
248
-
249
-
250
- def distribute_work(elems, chunk_size):
251
- """Distribute elements into chunks of a given size
252
- """
253
- return [elems[i:i + chunk_size] for i in range(0, len(elems), chunk_size)]
254
-
255
-
256
- def run_in_parallel(elems, chunk_size=10):
257
- """Run the element processing in parallel using a specified number of processes
258
- """
259
- # Local imports ----------------------------------------
260
- from pyhope.common.common_vars import np_mtp
261
- # ------------------------------------------------------
262
-
263
- chunks = distribute_work(elems, chunk_size)
264
- total_elements = len(elems)
265
- progress_queue = Queue()
266
-
267
- # Use a separate thread for the progress bar
268
- progress_thread = threading.Thread(target=update_progress, args=(progress_queue, total_elements))
269
- progress_thread.start()
270
-
271
- # Use multiprocessing Pool for parallel processing
272
- with Pool(processes=np_mtp) as pool:
273
- # Map work across processes in chunks
274
- results = []
275
- for chunk_result in pool.imap_unordered(process_chunk, chunks):
276
- results.extend(chunk_result)
277
- # Update progress for each processed element in the chunk
278
- for _ in chunk_result:
279
- progress_queue.put(1)
280
-
281
- # Wait for the progress bar thread to finish
282
- progress_thread.join()
283
-
284
- return results
285
-
286
-
287
- def update_progress(progress_queue, total_elements):
288
- """ Function to update the progress bar from the queue
289
- """
290
- with alive_bar(total_elements, title='│ Processing Elements', length=33) as bar:
291
- for _ in range(total_elements):
292
- # Block until we receive a progress update from the queue
293
- progress_queue.get()
294
- bar()
295
-
296
-
297
- def CheckJacobians() -> None:
298
- # Local imports ----------------------------------------
299
- from pyhope.common.common_vars import np_mtp
300
- from pyhope.io.io import LINMAP
301
- import pyhope.mesh.mesh_vars as mesh_vars
302
- import pyhope.output.output as hopout
303
- from pyhope.readintools.readintools import GetLogical
304
- # ------------------------------------------------------
305
-
306
- hopout.separator()
307
- hopout.info('CHECK JACOBIANS...')
308
- hopout.sep()
309
-
310
- checkElemJacobians = GetLogical('CheckElemJacobians')
311
- if not checkElemJacobians:
312
- return None
313
-
314
- nGeo = mesh_vars.nGeo + 1
315
-
316
- # Compute the equidistant point set used by meshIO
317
- xEq = np.zeros(nGeo)
318
- for i in range(nGeo):
319
- xEq[i] = 2.*float(i)/float(nGeo-1) - 1.
320
- wBaryEq = barycentric_weights(nGeo, xEq)
321
-
322
- xGL, _ = legendre_gauss_lobatto_nodes(nGeo)
323
- DGL = polynomial_derivative_matrix(nGeo, xGL)
324
- VdmEqToGL = calc_vandermonde(nGeo, nGeo, wBaryEq, xEq, xGL)
325
- wbaryGL = barycentric_weights(nGeo, xGL)
326
-
327
- D_EqToGL = np.matmul(DGL, VdmEqToGL)
328
-
329
- # Interpolate derivatives on GL (N) to nGeoRef points
330
- nGeoRef = 3*(nGeo-1)+1
331
- xAP = np.zeros(nGeoRef)
332
- for i in range(nGeoRef):
333
- xAP[i] = 2. * float(i)/float(nGeoRef-1) - 1.
334
- VdmGLtoAP = calc_vandermonde(nGeo, nGeoRef, wbaryGL, xGL, xAP)
335
-
336
- # Map all points to tensor product
337
- elems = mesh_vars.elems
338
- nodes = mesh_vars.mesh.points
339
-
340
- # Prepare elements for parallel processing
341
- jacobian_tasks = []
342
-
343
- for iElem, elem in enumerate(elems):
344
- # Only consider hexahedrons
345
- if int(elem.type) % 100 != 8:
346
- continue
347
-
348
- # Get the mapping
349
- linMap = LINMAP(elem.type, order=mesh_vars.nGeo)
350
- mapLin = {k: v for v, k in enumerate(linMap)}
351
-
352
- # Fill the NodeCoords
353
- nodeCoords = np.zeros((nGeo ** 3, 3), dtype=np.float64)
354
- for iNode, nodeID in enumerate(elem.nodes):
355
- nodeCoords[mapLin[iNode], :] = nodes[nodeID]
356
-
357
- xGeo = np.zeros((3, nGeo, nGeo, nGeo))
358
- iNode = 0
359
- for k in range(nGeo):
360
- for j in range(nGeo):
361
- for i in range(nGeo):
362
- xGeo[:, i, j, k] = nodeCoords[iNode, :]
363
- iNode += 1
364
-
365
- if np_mtp > 0:
366
- # Add tasks for parallel processing
367
- jacobian_tasks.append((xGeo, nGeoRef, VdmGLtoAP, D_EqToGL))
368
- else:
369
- jac = evaluate_jacobian(xGeo, VdmGLtoAP, D_EqToGL)
370
- maxJac = np.max(np.abs(jac))
371
- minJac = np.min( jac)
372
- jacobian_tasks.append(minJac / maxJac)
373
-
374
- if np_mtp > 0:
375
- # Run in parallel with a chunk size
376
- jacs = run_in_parallel(jacobian_tasks, chunk_size=10)
377
- else:
378
- jacs = np.array(jacobian_tasks)
379
-
380
- # Plot the histogram of the Jacobians
381
- plot_histogram(np.array(jacs))
211
+ # INFO: ALTERNATIVE VERSION, CACHING VDM, D
212
+ # class JacobianEvaluator:
213
+ # def __init__(self, VdmGLtoAP: np.ndarray, D_EqToGL: np.ndarray) -> None:
214
+ # self.VdmGLtoAP: Final[np.ndarray] = VdmGLtoAP
215
+ # self.D_EqToGL: Final[np.ndarray] = D_EqToGL
216
+ #
217
+ # def evaluate_jacobian(self, xGeo_In: np.ndarray) -> np.ndarray:
218
+ # # Perform tensor contraction for the first derivative (Xi direction)
219
+ # dXdXiGL = np.tensordot(self.D_EqToGL, xGeo_In, axes=(1, 1))
220
+ # dXdXiGL = np.moveaxis(dXdXiGL , 1, 0) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
221
+ #
222
+ # # Perform tensor contraction for the second derivative (Eta direction)
223
+ # dXdEtaGL = np.tensordot(self.D_EqToGL, xGeo_In, axes=(1, 2))
224
+ # dXdEtaGL = np.moveaxis(dXdEtaGL , 1, 0) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
225
+ #
226
+ # # Perform tensor contraction for the third derivative (Zeta direction)
227
+ # dXdZetaGL = np.tensordot(self.D_EqToGL, xGeo_In, axes=(1, 3))
228
+ # dXdZetaGL = np.moveaxis(dXdZetaGL, 1, 0) # Correct the shape to (3, nGeoRef, nGeoRef, nGeoRef)
229
+ #
230
+ # # Change basis for each direction
231
+ # dXdXiAP = change_basis_3D(self.VdmGLtoAP, dXdXiGL )
232
+ # dXdEtaAP = change_basis_3D(self.VdmGLtoAP, dXdEtaGL )
233
+ # dXdZetaAP = change_basis_3D(self.VdmGLtoAP, dXdZetaGL)
234
+ #
235
+ # # Precompute cross products between dXdEtaAP and dXdZetaAP for all points
236
+ # cross_eta_zeta = np.cross(dXdEtaAP, dXdZetaAP, axis=0) # Shape: (3, nGeoRef, nGeoRef, nGeoRef)
237
+ #
238
+ # # Fill output Jacobian array
239
+ # jacOut = np.einsum('ijkl,ijkl->jkl', dXdXiAP, cross_eta_zeta)
240
+ #
241
+ # return jacOut