cubitpy 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cubitpy/__init__.py +34 -0
- cubitpy/conf.py +158 -0
- cubitpy/cubit_group.py +353 -0
- cubitpy/cubit_utility.py +49 -0
- cubitpy/cubit_wrapper/__init__.py +22 -0
- cubitpy/cubit_wrapper/cubit_wrapper_client.py +255 -0
- cubitpy/cubit_wrapper/cubit_wrapper_host.py +379 -0
- cubitpy/cubit_wrapper/cubit_wrapper_utility.py +60 -0
- cubitpy/cubitpy.py +441 -0
- cubitpy/cubitpy_to_dat.py +207 -0
- cubitpy/cubitpy_types.py +358 -0
- cubitpy/geometry_creation_functions.py +224 -0
- cubitpy/mesh_creation_functions.py +276 -0
- cubitpy-0.0.1.dist-info/METADATA +100 -0
- cubitpy-0.0.1.dist-info/RECORD +20 -0
- cubitpy-0.0.1.dist-info/WHEEL +5 -0
- cubitpy-0.0.1.dist-info/licenses/LICENSE +21 -0
- cubitpy-0.0.1.dist-info/top_level.txt +2 -0
- tutorial/__init__.py +25 -0
- tutorial/tutorial.py +250 -0
cubitpy/__init__.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2018-2025 CubitPy Authors
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
# THE SOFTWARE.
|
|
22
|
+
"""This module contains extensions and utility functions for the cubit python
|
|
23
|
+
interface."""
|
|
24
|
+
|
|
25
|
+
from cubitpy.conf import cupy
|
|
26
|
+
from cubitpy.cubitpy import CubitPy
|
|
27
|
+
|
|
28
|
+
# Define the items that will be exported by default.
|
|
29
|
+
__all__ = [
|
|
30
|
+
# cubit options.
|
|
31
|
+
"cupy",
|
|
32
|
+
# Cubit objects.
|
|
33
|
+
"CubitPy",
|
|
34
|
+
]
|
cubitpy/conf.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2018-2025 CubitPy Authors
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
# THE SOFTWARE.
|
|
22
|
+
"""This module defines a global object that manages all kind of stuff regarding
|
|
23
|
+
cubitpy."""
|
|
24
|
+
|
|
25
|
+
import getpass
|
|
26
|
+
import glob
|
|
27
|
+
import os
|
|
28
|
+
import shutil
|
|
29
|
+
from sys import platform
|
|
30
|
+
|
|
31
|
+
from cubitpy.cubitpy_types import (
|
|
32
|
+
BoundaryConditionType,
|
|
33
|
+
CubitItems,
|
|
34
|
+
ElementType,
|
|
35
|
+
FiniteElementObject,
|
|
36
|
+
GeometryType,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_path(environment_variable, test_function, *, throw_error=True):
|
|
41
|
+
"""Check if he environment variable is set and the path exits."""
|
|
42
|
+
if environment_variable in os.environ.keys():
|
|
43
|
+
if test_function(os.environ[environment_variable]):
|
|
44
|
+
return os.environ[environment_variable]
|
|
45
|
+
|
|
46
|
+
# No valid path found or given.
|
|
47
|
+
if throw_error:
|
|
48
|
+
raise ValueError("Path for {} not found!".format(environment_variable))
|
|
49
|
+
else:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class CubitOptions(object):
|
|
54
|
+
"""Object for types in cubitpy."""
|
|
55
|
+
|
|
56
|
+
def __init__(self):
|
|
57
|
+
# Temporary directory for cubitpy.
|
|
58
|
+
self.temp_dir = os.path.join(
|
|
59
|
+
"/tmp/cubitpy_{}".format(getpass.getuser()), # nosec
|
|
60
|
+
"pid_{}".format(os.getpid()),
|
|
61
|
+
)
|
|
62
|
+
self.temp_log = os.path.join(self.temp_dir, "cubitpy.log")
|
|
63
|
+
|
|
64
|
+
# Check if temp path exits, if not create it.
|
|
65
|
+
os.makedirs(self.temp_dir, exist_ok=True)
|
|
66
|
+
|
|
67
|
+
# Geometry types.
|
|
68
|
+
self.geometry = GeometryType
|
|
69
|
+
|
|
70
|
+
# Finite element types.
|
|
71
|
+
self.finite_element_object = FiniteElementObject
|
|
72
|
+
|
|
73
|
+
# Element shape types.
|
|
74
|
+
self.element_type = ElementType
|
|
75
|
+
|
|
76
|
+
# Cubit internal items.
|
|
77
|
+
self.cubit_items = CubitItems
|
|
78
|
+
|
|
79
|
+
# Boundary condition type.
|
|
80
|
+
self.bc_type = BoundaryConditionType
|
|
81
|
+
|
|
82
|
+
# Tolerance for geometry.
|
|
83
|
+
self.eps_pos = 1e-10
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def get_cubit_root_path(**kwargs):
|
|
87
|
+
"""Get Path to cubit root directory."""
|
|
88
|
+
return get_path("CUBIT_ROOT", os.path.isdir, **kwargs)
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def get_cubit_exe_path(cls, **kwargs):
|
|
92
|
+
"""Get Path to cubit executable."""
|
|
93
|
+
cubit_root = cls.get_cubit_root_path(**kwargs)
|
|
94
|
+
if platform == "linux" or platform == "linux2":
|
|
95
|
+
if cupy.is_coreform():
|
|
96
|
+
return os.path.join(cubit_root, "bin", "coreform_cubit")
|
|
97
|
+
else:
|
|
98
|
+
return os.path.join(cubit_root, "cubit")
|
|
99
|
+
elif platform == "darwin":
|
|
100
|
+
if cupy.is_coreform():
|
|
101
|
+
cubit_exe_name = cubit_root.split("/")[-1].split(".app")[0]
|
|
102
|
+
return os.path.join(cubit_root, "Contents/MacOS", cubit_exe_name)
|
|
103
|
+
else:
|
|
104
|
+
return os.path.join(cubit_root, "Contents/MacOS/Cubit")
|
|
105
|
+
else:
|
|
106
|
+
raise ValueError("Got unexpected platform")
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def get_cubit_lib_path(cls, **kwargs):
|
|
110
|
+
"""Get Path to cubit lib directory."""
|
|
111
|
+
cubit_root = cls.get_cubit_root_path(**kwargs)
|
|
112
|
+
if platform == "linux" or platform == "linux2":
|
|
113
|
+
return os.path.join(cubit_root, "bin")
|
|
114
|
+
elif platform == "darwin":
|
|
115
|
+
if cls.is_coreform():
|
|
116
|
+
return os.path.join(cubit_root, "Contents/lib")
|
|
117
|
+
else:
|
|
118
|
+
return os.path.join(cubit_root, "Contents/MacOS")
|
|
119
|
+
else:
|
|
120
|
+
raise ValueError("Got unexpected platform")
|
|
121
|
+
|
|
122
|
+
@classmethod
|
|
123
|
+
def get_cubit_interpreter(cls):
|
|
124
|
+
"""Get the path to the python interpreter to be used for CubitPy."""
|
|
125
|
+
cubit_root = cls.get_cubit_root_path()
|
|
126
|
+
if cls.is_coreform():
|
|
127
|
+
pattern = "**/python3"
|
|
128
|
+
full_pattern = os.path.join(cubit_root, pattern)
|
|
129
|
+
python3_matches = glob.glob(full_pattern, recursive=True)
|
|
130
|
+
python3_files = [path for path in python3_matches if os.path.isfile(path)]
|
|
131
|
+
if not len(python3_files) == 1:
|
|
132
|
+
raise ValueError(
|
|
133
|
+
"Could not find the path to the cubit python interpreter"
|
|
134
|
+
)
|
|
135
|
+
cubit_python_interpreter = python3_files[0]
|
|
136
|
+
return cubit_python_interpreter
|
|
137
|
+
else:
|
|
138
|
+
if shutil.which("python2.7") is not None:
|
|
139
|
+
return "python2.7"
|
|
140
|
+
|
|
141
|
+
imcs_python2_path = "/imcs/public/compsim/opt/Python-2.7.18/python"
|
|
142
|
+
if os.path.exists(imcs_python2_path):
|
|
143
|
+
return imcs_python2_path
|
|
144
|
+
|
|
145
|
+
raise ValueError("Could not find a python2 interpreter")
|
|
146
|
+
|
|
147
|
+
@classmethod
|
|
148
|
+
def is_coreform(cls):
|
|
149
|
+
"""Return if the given path is a path to cubit coreform."""
|
|
150
|
+
cubit_root = cls.get_cubit_root_path()
|
|
151
|
+
if "15.2" in cubit_root:
|
|
152
|
+
return False
|
|
153
|
+
else:
|
|
154
|
+
return True
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# Global object with options for cubitpy.
|
|
158
|
+
cupy = CubitOptions()
|
cubitpy/cubit_group.py
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2018-2025 CubitPy Authors
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
# THE SOFTWARE.
|
|
22
|
+
"""This file contains a class to represent groups in cubit."""
|
|
23
|
+
|
|
24
|
+
from cubitpy.conf import cupy
|
|
25
|
+
from cubitpy.cubit_wrapper.cubit_wrapper_host import CubitObject
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CubitGroup(object):
|
|
29
|
+
"""This object helps to represent groups in cubit."""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
cubit,
|
|
34
|
+
*,
|
|
35
|
+
name=None,
|
|
36
|
+
add_value=None,
|
|
37
|
+
group_from_id=None,
|
|
38
|
+
group_from_name=None,
|
|
39
|
+
):
|
|
40
|
+
"""Set up the group object.
|
|
41
|
+
|
|
42
|
+
Args
|
|
43
|
+
----
|
|
44
|
+
cubit: CubitPy
|
|
45
|
+
Link to a cubitpy object.
|
|
46
|
+
name: str
|
|
47
|
+
Name of the group in cubit.
|
|
48
|
+
add_value: str
|
|
49
|
+
If this argument is given, it is added to the group.
|
|
50
|
+
group_from_id: int
|
|
51
|
+
Id of an existing group in cubit. If this parameter is given, the
|
|
52
|
+
other optional parameters have to be empty.
|
|
53
|
+
group_from_name: str
|
|
54
|
+
Name of an existing group in cubit. If this parameter is given, the
|
|
55
|
+
other optional parameters have to be empty.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
self.name = name
|
|
59
|
+
self.cubit = cubit
|
|
60
|
+
|
|
61
|
+
self.n_node_sets = 0
|
|
62
|
+
self.n_blocks = 0
|
|
63
|
+
|
|
64
|
+
if group_from_id is None and group_from_name is None:
|
|
65
|
+
# Create a new group.
|
|
66
|
+
self._id = cubit.create_new_group()
|
|
67
|
+
|
|
68
|
+
# Rename it if a name was given.
|
|
69
|
+
if self.name is not None:
|
|
70
|
+
# Check that the name does not already exist.
|
|
71
|
+
if not cubit.get_id_from_name(self.name) == 0:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
'The given group name "{}" already exists!'.format(self.name)
|
|
74
|
+
)
|
|
75
|
+
cubit.cmd("group {} rename '{}'".format(self._id, self.name))
|
|
76
|
+
|
|
77
|
+
if add_value is not None:
|
|
78
|
+
self.add(add_value)
|
|
79
|
+
elif group_from_id is not None:
|
|
80
|
+
if (
|
|
81
|
+
add_value is not None
|
|
82
|
+
or self.name is not None
|
|
83
|
+
or group_from_name is not None
|
|
84
|
+
):
|
|
85
|
+
raise ValueError(
|
|
86
|
+
'A group can not be initiated with a "group_from_id" and "add_value" or "name" or "group_from_id".'
|
|
87
|
+
)
|
|
88
|
+
self._id = group_from_id
|
|
89
|
+
self.name = self.cubit.cubit.get_entity_name("group", self._id)
|
|
90
|
+
elif group_from_name is not None:
|
|
91
|
+
if (
|
|
92
|
+
add_value is not None
|
|
93
|
+
or self.name is not None
|
|
94
|
+
or group_from_id is not None
|
|
95
|
+
):
|
|
96
|
+
raise ValueError(
|
|
97
|
+
'A group can not be initiated with a "group_from_id" and "add_value" or "name" or "group_from_id".'
|
|
98
|
+
)
|
|
99
|
+
self._id = cubit.get_id_from_name(group_from_name)
|
|
100
|
+
self.name = group_from_name
|
|
101
|
+
if self._id == 0:
|
|
102
|
+
raise NameError(
|
|
103
|
+
'No group with the name "{}" could be found'.format(group_from_name)
|
|
104
|
+
)
|
|
105
|
+
else:
|
|
106
|
+
raise NotImplementedError("This case is not implemented")
|
|
107
|
+
|
|
108
|
+
def add(self, add_value):
|
|
109
|
+
"""Add items to the group. This can be done in three different ways:
|
|
110
|
+
|
|
111
|
+
Args
|
|
112
|
+
----
|
|
113
|
+
add_value:
|
|
114
|
+
str:
|
|
115
|
+
A string that will be executed in cubit to add items.
|
|
116
|
+
CubitObject.
|
|
117
|
+
Add this object to the group.
|
|
118
|
+
[CubitObject]:
|
|
119
|
+
Add this list of cubit objects.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
if isinstance(add_value, str):
|
|
123
|
+
self.cubit.cmd("group {} {}".format(self._id, add_value))
|
|
124
|
+
elif isinstance(add_value, CubitObject):
|
|
125
|
+
self.cubit.add_entity_to_group(
|
|
126
|
+
self._id,
|
|
127
|
+
add_value.id(),
|
|
128
|
+
add_value.get_geometry_type().get_cubit_string(),
|
|
129
|
+
)
|
|
130
|
+
elif isinstance(add_value, list):
|
|
131
|
+
for item in add_value:
|
|
132
|
+
self.add(item)
|
|
133
|
+
else:
|
|
134
|
+
raise TypeError("Got wrong type {}!".format(type(add_value)))
|
|
135
|
+
|
|
136
|
+
def get_geometry_type(self):
|
|
137
|
+
"""Return the geometry type of this group.
|
|
138
|
+
|
|
139
|
+
This only works if the group contains a single type of geometry
|
|
140
|
+
of finite element objects.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
group_items = self.get_item_ids()
|
|
144
|
+
group_keys = [key for key in group_items if len(group_items[key]) > 0]
|
|
145
|
+
if not len(group_keys) == 1:
|
|
146
|
+
raise TypeError("Got wrong types in get_geometry_type")
|
|
147
|
+
|
|
148
|
+
key = group_keys[0]
|
|
149
|
+
if key in cupy.geometry:
|
|
150
|
+
return key
|
|
151
|
+
elif key == cupy.finite_element_object.node:
|
|
152
|
+
return cupy.geometry.vertex
|
|
153
|
+
elif (
|
|
154
|
+
key == cupy.finite_element_object.triangle
|
|
155
|
+
or key == cupy.finite_element_object.face
|
|
156
|
+
):
|
|
157
|
+
return cupy.geometry.surface
|
|
158
|
+
elif (
|
|
159
|
+
key == cupy.finite_element_object.tet
|
|
160
|
+
or key == cupy.finite_element_object.hex
|
|
161
|
+
or key == cupy.finite_element_object.wedge
|
|
162
|
+
):
|
|
163
|
+
return cupy.geometry.volume
|
|
164
|
+
else:
|
|
165
|
+
raise TypeError("Error in get_geometry_type")
|
|
166
|
+
|
|
167
|
+
def get_geometry_objects(self, item_type):
|
|
168
|
+
"""Get a list of all items in the group for the given geometry_type."""
|
|
169
|
+
return self.cubit.get_items(
|
|
170
|
+
item_type, item_ids=self.get_item_ids_from_type(item_type)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
def get_item_ids_from_type(self, item_type):
|
|
174
|
+
"""Get the IDs of a certain type of item in this group."""
|
|
175
|
+
|
|
176
|
+
# Geometry items.
|
|
177
|
+
if item_type == cupy.geometry.vertex:
|
|
178
|
+
return self.cubit.get_group_vertices(self._id)
|
|
179
|
+
elif item_type == cupy.geometry.curve:
|
|
180
|
+
return self.cubit.get_group_curves(self._id)
|
|
181
|
+
elif item_type == cupy.geometry.surface:
|
|
182
|
+
return self.cubit.get_group_surfaces(self._id)
|
|
183
|
+
elif item_type == cupy.geometry.volume:
|
|
184
|
+
return self.cubit.get_group_volumes(self._id)
|
|
185
|
+
|
|
186
|
+
# Finite element items.
|
|
187
|
+
elif item_type == cupy.finite_element_object.node:
|
|
188
|
+
return self.cubit.get_group_nodes(self._id)
|
|
189
|
+
elif item_type == cupy.finite_element_object.edge:
|
|
190
|
+
return self.cubit.get_group_edges(self._id)
|
|
191
|
+
elif item_type == cupy.finite_element_object.face:
|
|
192
|
+
return self.cubit.get_group_quads(self._id)
|
|
193
|
+
elif item_type == cupy.finite_element_object.triangle:
|
|
194
|
+
return self.cubit.get_group_tris(self._id)
|
|
195
|
+
elif item_type == cupy.finite_element_object.tet:
|
|
196
|
+
return self.cubit.get_group_tets(self._id)
|
|
197
|
+
elif item_type == cupy.finite_element_object.hex:
|
|
198
|
+
return self.cubit.get_group_hexes(self._id)
|
|
199
|
+
elif item_type == cupy.finite_element_object.wedge:
|
|
200
|
+
return self.cubit.get_group_wedges(self._id)
|
|
201
|
+
|
|
202
|
+
# Cubit items.
|
|
203
|
+
elif item_type == cupy.cubit_items.group:
|
|
204
|
+
return self.cubit.get_group_groups(self._id)
|
|
205
|
+
|
|
206
|
+
else:
|
|
207
|
+
raise TypeError("Wrong item type.")
|
|
208
|
+
|
|
209
|
+
def _get_item_ids(self, group_items):
|
|
210
|
+
"""Add all items in this group to group_items.
|
|
211
|
+
|
|
212
|
+
Also add all items of contained subgroups.
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
# Add entries from subgroups.
|
|
216
|
+
sub_groups = [
|
|
217
|
+
self.cubit.group(group_id=group_id)
|
|
218
|
+
for group_id in self.get_item_ids_from_type(cupy.cubit_items.group)
|
|
219
|
+
]
|
|
220
|
+
for sub_group in sub_groups:
|
|
221
|
+
sub_group._get_item_ids(group_items)
|
|
222
|
+
|
|
223
|
+
# Add entries from this group.
|
|
224
|
+
for geometry_type in cupy.geometry:
|
|
225
|
+
group_items[geometry_type].extend(
|
|
226
|
+
self.get_item_ids_from_type(geometry_type)
|
|
227
|
+
)
|
|
228
|
+
for fe_object in cupy.finite_element_object:
|
|
229
|
+
group_items[fe_object].extend(self.get_item_ids_from_type(fe_object))
|
|
230
|
+
|
|
231
|
+
def get_item_ids(self):
|
|
232
|
+
"""Get a dictionary with the IDs of all entries in this group, this
|
|
233
|
+
also includes items in subgroups."""
|
|
234
|
+
|
|
235
|
+
# Initialize the empty dictionary.
|
|
236
|
+
group_items = {}
|
|
237
|
+
for geometry_type in cupy.geometry:
|
|
238
|
+
group_items[geometry_type] = []
|
|
239
|
+
for fe_object in cupy.finite_element_object:
|
|
240
|
+
group_items[fe_object] = []
|
|
241
|
+
|
|
242
|
+
# Get all entries.
|
|
243
|
+
self._get_item_ids(group_items)
|
|
244
|
+
|
|
245
|
+
# Remove double entries.
|
|
246
|
+
for key in group_items.keys():
|
|
247
|
+
group_items[key] = list(set(group_items[key]))
|
|
248
|
+
return group_items
|
|
249
|
+
|
|
250
|
+
def add_to_block(self, block_id, el_type):
|
|
251
|
+
"""Add the items of this group to a block in cubit. If there are
|
|
252
|
+
explicit elements in this group, they are also added to the block.
|
|
253
|
+
|
|
254
|
+
Args
|
|
255
|
+
----
|
|
256
|
+
block_id: int
|
|
257
|
+
Number of the block which the geometry and or elements should be
|
|
258
|
+
added to.
|
|
259
|
+
el_type: ElementType
|
|
260
|
+
Type of the finite elements.
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
self_geometry = self.get_geometry_type()
|
|
264
|
+
if (
|
|
265
|
+
self_geometry != cupy.geometry.surface
|
|
266
|
+
and self_geometry != cupy.geometry.volume
|
|
267
|
+
):
|
|
268
|
+
raise NotImplementedError("This case is not implemented")
|
|
269
|
+
|
|
270
|
+
group_items = self.get_item_ids()
|
|
271
|
+
cubit_scheme, cubit_element_type = el_type.get_cubit_names()
|
|
272
|
+
|
|
273
|
+
# Set element type and meshing scheme for each geometry item in the group.
|
|
274
|
+
for i in group_items[self_geometry]:
|
|
275
|
+
self.cubit.cmd(
|
|
276
|
+
"{} {} scheme {}".format(
|
|
277
|
+
self_geometry.get_cubit_string(), i, cubit_scheme
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
self.cubit.cmd(
|
|
281
|
+
"block {} element type {}".format(block_id, cubit_element_type)
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
self.cubit.cmd(f"block {block_id} add group {self._id}")
|
|
285
|
+
|
|
286
|
+
def add_to_nodeset(self, nodeset_id):
|
|
287
|
+
"""Add the nodes from this geometry to a node set.
|
|
288
|
+
|
|
289
|
+
Args
|
|
290
|
+
----
|
|
291
|
+
nodeset_id: int
|
|
292
|
+
Number of the node set which the geometry and or nodes should be
|
|
293
|
+
added to.
|
|
294
|
+
"""
|
|
295
|
+
|
|
296
|
+
# Add this group. This will add all geometry and directly contained
|
|
297
|
+
# nodes in this group. If there are elements in this group, there will
|
|
298
|
+
# be a warning. This warning is explicitly deactivated here.
|
|
299
|
+
self.cubit.cmd("set warning off")
|
|
300
|
+
self.cubit.cmd("nodeset {} group {}".format(nodeset_id, self._id))
|
|
301
|
+
self.cubit.cmd("set warning on")
|
|
302
|
+
|
|
303
|
+
# Add all nodes that are part of faces and elements to the node set.
|
|
304
|
+
group_items = self.get_item_ids()
|
|
305
|
+
nodes = []
|
|
306
|
+
for mesh_item in cupy.finite_element_object:
|
|
307
|
+
for i in group_items[mesh_item]:
|
|
308
|
+
nodes.extend(
|
|
309
|
+
self.cubit.get_connectivity(mesh_item.get_cubit_string(), i)
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
# Add all nodes to the node set.
|
|
313
|
+
for i_node in nodes:
|
|
314
|
+
self.cubit.cmd("nodeset {} node {}".format(nodeset_id, i_node))
|
|
315
|
+
|
|
316
|
+
def get_name(self, set_type):
|
|
317
|
+
"""Return the name for this set to be used in cubit.
|
|
318
|
+
|
|
319
|
+
Args
|
|
320
|
+
----
|
|
321
|
+
set_type: str
|
|
322
|
+
Type of the set this group is added to. Can be one of the
|
|
323
|
+
following:
|
|
324
|
+
- 'nodeset'
|
|
325
|
+
- 'block'
|
|
326
|
+
"""
|
|
327
|
+
|
|
328
|
+
return_string = None
|
|
329
|
+
if set_type == "nodeset":
|
|
330
|
+
if self.n_node_sets == 0:
|
|
331
|
+
return_string = self.name
|
|
332
|
+
else:
|
|
333
|
+
return_string = "{}_{}".format(self.name, self.n_node_sets)
|
|
334
|
+
self.n_node_sets += 1
|
|
335
|
+
elif set_type == "block":
|
|
336
|
+
if self.n_blocks > 0:
|
|
337
|
+
raise ValueError(
|
|
338
|
+
"Only one block can be created from a single group object."
|
|
339
|
+
)
|
|
340
|
+
return_string = self.name
|
|
341
|
+
self.n_blocks += 1
|
|
342
|
+
else:
|
|
343
|
+
raise ValueError('Got unexpected set_type "{}"'.format(set_type))
|
|
344
|
+
return return_string
|
|
345
|
+
|
|
346
|
+
def id(self):
|
|
347
|
+
"""Return the string with all ids of the types in this object."""
|
|
348
|
+
id_list = self.get_item_ids_from_type(self.get_geometry_type())
|
|
349
|
+
return " ".join(map(str, id_list))
|
|
350
|
+
|
|
351
|
+
def __str__(self, *args, **kwargs):
|
|
352
|
+
"""The string representation of a group is its name."""
|
|
353
|
+
return self.name
|
cubitpy/cubit_utility.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2018-2025 CubitPy Authors
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
# THE SOFTWARE.
|
|
22
|
+
"""Utility functions for the use of cubitpy."""
|
|
23
|
+
|
|
24
|
+
from cubitpy.conf import cupy
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_surface_center(surf):
|
|
28
|
+
"""Get a 3D point that has the local coordinated on the surface of (0,0),
|
|
29
|
+
with the parameter space being ([-1,1],[-1,1])."""
|
|
30
|
+
|
|
31
|
+
if not surf.get_geometry_type() == cupy.geometry.surface:
|
|
32
|
+
raise TypeError("Did not expect {}".format(type(surf)))
|
|
33
|
+
|
|
34
|
+
range_u = surf.get_param_range_U()
|
|
35
|
+
u = 0.5 * (range_u[1] + range_u[0])
|
|
36
|
+
range_v = surf.get_param_range_V()
|
|
37
|
+
v = 0.5 * (range_v[1] + range_v[0])
|
|
38
|
+
return surf.position_from_u_v(u, v)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def import_fluent_geometry(cubit, file, feature_angle=135):
|
|
42
|
+
"""Import fluent mesh geometry in cubit from file with according
|
|
43
|
+
feature_angle."""
|
|
44
|
+
|
|
45
|
+
cubit.cmd(
|
|
46
|
+
'import fluent mesh geometry "{}" feature_angle {} '.format(
|
|
47
|
+
file, feature_angle
|
|
48
|
+
)
|
|
49
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# The MIT License (MIT)
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2018-2025 CubitPy Authors
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
# THE SOFTWARE.
|
|
22
|
+
"""This module defines a wrapper for cubit python interpreters."""
|