fiqus 2025.2.0__py3-none-any.whl → 2025.10.0__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.
- fiqus/MainFiQuS.py +4 -9
- fiqus/data/DataConductor.py +350 -301
- fiqus/data/DataFiQuS.py +42 -115
- fiqus/data/DataFiQuSCCT.py +150 -150
- fiqus/data/DataFiQuSConductor.py +97 -84
- fiqus/data/DataFiQuSConductorAC_Strand.py +701 -565
- fiqus/data/DataModelCommon.py +439 -0
- fiqus/data/DataMultipole.py +0 -13
- fiqus/data/DataRoxieParser.py +7 -0
- fiqus/data/DataWindingsCCT.py +37 -37
- fiqus/data/RegionsModelFiQuS.py +61 -104
- fiqus/geom_generators/GeometryCCT.py +904 -905
- fiqus/geom_generators/GeometryConductorAC_Strand.py +1863 -1391
- fiqus/geom_generators/GeometryMultipole.py +5 -4
- fiqus/geom_generators/GeometryPancake3D.py +1 -1
- fiqus/getdp_runners/RunGetdpCCT.py +13 -4
- fiqus/getdp_runners/RunGetdpConductorAC_Strand.py +341 -201
- fiqus/getdp_runners/RunGetdpPancake3D.py +2 -2
- fiqus/mains/MainConductorAC_Strand.py +141 -133
- fiqus/mains/MainMultipole.py +6 -5
- fiqus/mains/MainPancake3D.py +3 -4
- fiqus/mesh_generators/MeshCCT.py +209 -209
- fiqus/mesh_generators/MeshConductorAC_Strand.py +709 -656
- fiqus/mesh_generators/MeshMultipole.py +43 -46
- fiqus/parsers/ParserDAT.py +16 -16
- fiqus/parsers/ParserGetDPOnSection.py +212 -212
- fiqus/parsers/ParserGetDPTimeTable.py +134 -134
- fiqus/parsers/ParserMSH.py +53 -53
- fiqus/parsers/ParserPOS.py +214 -214
- fiqus/parsers/ParserRES.py +142 -142
- fiqus/plotters/PlotPythonCCT.py +133 -133
- fiqus/plotters/PlotPythonConductorAC.py +1079 -855
- fiqus/plotters/PlotPythonMultipole.py +18 -18
- fiqus/post_processors/PostProcessCCT.py +444 -440
- fiqus/post_processors/PostProcessConductorAC.py +997 -49
- fiqus/post_processors/PostProcessMultipole.py +19 -19
- fiqus/pre_processors/PreProcessCCT.py +175 -175
- fiqus/pro_material_functions/ironBHcurves.pro +246 -246
- fiqus/pro_templates/combined/CCT_template.pro +275 -274
- fiqus/pro_templates/combined/ConductorAC_template.pro +1474 -1025
- fiqus/pro_templates/combined/Multipole_template.pro +5 -5
- fiqus/utils/Utils.py +12 -7
- {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/METADATA +65 -63
- fiqus-2025.10.0.dist-info/RECORD +86 -0
- {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/WHEEL +1 -1
- tests/test_geometry_generators.py +4 -0
- tests/test_mesh_generators.py +5 -0
- tests/test_solvers.py +41 -4
- tests/utils/fiqus_test_classes.py +15 -6
- tests/utils/generate_reference_files_ConductorAC.py +57 -57
- tests/utils/helpers.py +97 -97
- fiqus-2025.2.0.dist-info/RECORD +0 -85
- {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/LICENSE.txt +0 -0
- {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/top_level.txt +0 -0
fiqus/parsers/ParserPOS.py
CHANGED
|
@@ -1,214 +1,214 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import inspect
|
|
3
|
-
import pandas as pd
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ParserPOS:
|
|
7
|
-
|
|
8
|
-
def __init__(self, pos_file_path):
|
|
9
|
-
"""
|
|
10
|
-
Read pos file and returns its content as object attribute .data_dict that is a dictionary.
|
|
11
|
-
:param pos_file_path: Full path to .pos file, including file name and extension.
|
|
12
|
-
"""
|
|
13
|
-
self._mesh_format_markers = {'s': '$MeshFormat', 'e': '$EndMeshFormat'}
|
|
14
|
-
self._nodes_markers = {'s': '$Nodes', 'e': '$EndNodes'}
|
|
15
|
-
self._elements_markers = {'s': '$Elements', 'e': '$EndElements'}
|
|
16
|
-
self._elements_node_data_markers = {'s': '$ElementNodeData', 'e': '$EndElementNodeData'}
|
|
17
|
-
self._physical_name_markers = {'s': 'PhysicalNames', 'e': '$EndPhysicalNames'}
|
|
18
|
-
|
|
19
|
-
with open(pos_file_path) as f:
|
|
20
|
-
self._contents = f.read()
|
|
21
|
-
# node properteis
|
|
22
|
-
self._node_numbers = []
|
|
23
|
-
self._node_coordinates = []
|
|
24
|
-
# element properties
|
|
25
|
-
self._element_numbers = []
|
|
26
|
-
self._element_types = []
|
|
27
|
-
self._element_number_of_tags = []
|
|
28
|
-
self._element_physical_tags = []
|
|
29
|
-
self._element_elementary_tags = []
|
|
30
|
-
self._element_node_numbers = []
|
|
31
|
-
# elements_node_data properties
|
|
32
|
-
self._data_element_tags = []
|
|
33
|
-
self._data_num_nodes_per_element = []
|
|
34
|
-
self._values = []
|
|
35
|
-
# parse the content (output is in this class attributes)
|
|
36
|
-
self._parse()
|
|
37
|
-
|
|
38
|
-
def __get_content(self, markers_dict):
|
|
39
|
-
"""
|
|
40
|
-
Gets text string between two markers specified in markers_dict
|
|
41
|
-
"""
|
|
42
|
-
return self._contents[self._contents.find(markers_dict['s']) + len(markers_dict['s']):self._contents.find(markers_dict['e'])]
|
|
43
|
-
|
|
44
|
-
@staticmethod
|
|
45
|
-
def __get_lines(data_str, empty_lines=[0, -1]):
|
|
46
|
-
"""
|
|
47
|
-
Converts text string into a list of lines
|
|
48
|
-
"""
|
|
49
|
-
data_str = re.sub('\n', "'", data_str)
|
|
50
|
-
data_str = re.sub('"', '', data_str)
|
|
51
|
-
str_list = re.split("'", data_str)
|
|
52
|
-
for empty_line in empty_lines:
|
|
53
|
-
if not str_list.pop(empty_line) == '':
|
|
54
|
-
raise ValueError('Error in parsing lines')
|
|
55
|
-
return str_list
|
|
56
|
-
|
|
57
|
-
@staticmethod
|
|
58
|
-
def __list_from_list_at_pos(dest_list, source_list, d_type, pos):
|
|
59
|
-
"""
|
|
60
|
-
This one is a bit complex. It converts a supplied in source list and appends it destination list.
|
|
61
|
-
It uses data type and position to append to the right type to the destination list from the right place in the source list.
|
|
62
|
-
Position could be an integer, a list of integers or a tuple with a reference variables to figure out positions from them.
|
|
63
|
-
"""
|
|
64
|
-
if isinstance(pos, int):
|
|
65
|
-
dest_list.append(d_type(source_list[pos]))
|
|
66
|
-
elif isinstance(pos, list):
|
|
67
|
-
dest_list.append([d_type(source_list[p]) for p in pos])
|
|
68
|
-
elif isinstance(pos, tuple):
|
|
69
|
-
offset = pos[0]
|
|
70
|
-
dimension = pos[1]
|
|
71
|
-
ref_list = pos[2]
|
|
72
|
-
current_num_elem = ref_list[len(dest_list)] # get current element
|
|
73
|
-
pos = list(range(offset, dimension * current_num_elem + offset))
|
|
74
|
-
dest_list.append([d_type(source_list[p]) for p in pos])
|
|
75
|
-
|
|
76
|
-
def __parse_lines(self, lines, list_of_outputs_lists, list_of_data_types, list_of_positions, len_check, ):
|
|
77
|
-
"""
|
|
78
|
-
Simply loop through lines and append to class attributes lists. Basic error check if number of lines in the list matches that declared in the file.
|
|
79
|
-
"""
|
|
80
|
-
for line in lines:
|
|
81
|
-
values = re.split(' ', line)
|
|
82
|
-
for dest_list, d_type, pos in zip(list_of_outputs_lists, list_of_data_types, list_of_positions):
|
|
83
|
-
self.__list_from_list_at_pos(dest_list, values, d_type, pos)
|
|
84
|
-
for out_list in list_of_outputs_lists:
|
|
85
|
-
if not len_check == len(out_list):
|
|
86
|
-
raise ValueError(f'Error in parsing {inspect.stack()[1].function}')
|
|
87
|
-
|
|
88
|
-
def _mesh_format(self):
|
|
89
|
-
"""
|
|
90
|
-
Parse mesh_generators field and assign it to the class attribute
|
|
91
|
-
"""
|
|
92
|
-
self.mesh_format = self.__get_content(self._mesh_format_markers)
|
|
93
|
-
|
|
94
|
-
def _physical_names(self):
|
|
95
|
-
"""
|
|
96
|
-
Parse physical_names field and assign it to the class attribute
|
|
97
|
-
"""
|
|
98
|
-
self.physical_names = self.__get_content(self._physical_name_markers)
|
|
99
|
-
|
|
100
|
-
def _nodes(self):
|
|
101
|
-
"""
|
|
102
|
-
Parse nodes and assign it to the class attributes
|
|
103
|
-
"""
|
|
104
|
-
data_str = self.__get_content(self._nodes_markers)
|
|
105
|
-
lines = self.__get_lines(data_str)
|
|
106
|
-
self._number_of_nodes = int(lines.pop(0))
|
|
107
|
-
list_of_outputs_lists = [self._node_numbers, self._node_coordinates]
|
|
108
|
-
list_of_data_types = [int, float]
|
|
109
|
-
list_of_positions = [0, [1, 2, 3]]
|
|
110
|
-
self.__parse_lines(lines, list_of_outputs_lists, list_of_data_types, list_of_positions, self._number_of_nodes)
|
|
111
|
-
|
|
112
|
-
def _elements(self):
|
|
113
|
-
"""
|
|
114
|
-
Parse elements and assign it to the class attributes
|
|
115
|
-
"""
|
|
116
|
-
data_str = self.__get_content(self._elements_markers)
|
|
117
|
-
lines = self.__get_lines(data_str)
|
|
118
|
-
self._number_of_elements = int(lines.pop(0))
|
|
119
|
-
list_of_outputs_lists = [self._element_numbers, self._element_types, self._element_number_of_tags, self._element_physical_tags, self._element_elementary_tags, self._element_node_numbers]
|
|
120
|
-
list_of_data_types = [int, int, int, int, int, int]
|
|
121
|
-
list_of_positions = [0, 1, 2, 3, 4, (5, 1, self._data_num_nodes_per_element)]
|
|
122
|
-
self.__parse_lines(lines, list_of_outputs_lists, list_of_data_types, list_of_positions, self._number_of_elements)
|
|
123
|
-
|
|
124
|
-
def _elements_node_data(self):
|
|
125
|
-
"""
|
|
126
|
-
Parse elements data and assign it to the class attributes
|
|
127
|
-
"""
|
|
128
|
-
data_str = self.__get_content(self._elements_node_data_markers)
|
|
129
|
-
lines = self.__get_lines(data_str)
|
|
130
|
-
self._numStringTags = int(lines.pop(0))
|
|
131
|
-
self._stringTags = str(lines.pop(0))
|
|
132
|
-
self._numRealTags = int(lines.pop(0))
|
|
133
|
-
self._realTags = float(lines.pop(0))
|
|
134
|
-
self._numIntegerTags = int(lines.pop(0))
|
|
135
|
-
self._integerTags = int(lines.pop(0))
|
|
136
|
-
self._entityDim = int(lines.pop(0))
|
|
137
|
-
self._number_of_elements_data = int(lines.pop(0))
|
|
138
|
-
self._not_sure = int(lines.pop(0)) # not sure what this number is
|
|
139
|
-
list_of_outputs_lists = [self._data_element_tags, self._data_num_nodes_per_element, self._values]
|
|
140
|
-
list_of_data_types = [int, int, float]
|
|
141
|
-
list_of_positions = [0, 1, (2, self._entityDim, self._data_num_nodes_per_element)]
|
|
142
|
-
self.__parse_lines(lines, list_of_outputs_lists, list_of_data_types, list_of_positions, self._number_of_elements_data)
|
|
143
|
-
|
|
144
|
-
def __element_for_node(self):
|
|
145
|
-
self._elem_list_for_nodes = []
|
|
146
|
-
self._index_elem = []
|
|
147
|
-
element_node_numbers = pd.DataFrame(self._element_node_numbers)
|
|
148
|
-
for node in self._node_numbers:
|
|
149
|
-
index = pd.Index
|
|
150
|
-
i = -1
|
|
151
|
-
while index.empty:
|
|
152
|
-
i += 1
|
|
153
|
-
index = element_node_numbers[element_node_numbers[i] == node].index
|
|
154
|
-
self._elem_list_for_nodes.append(index[0])
|
|
155
|
-
self._index_elem.append(i)
|
|
156
|
-
|
|
157
|
-
# element_node_numbers = pd.DataFrame(self._element_node_numbers)
|
|
158
|
-
# for node in self._node_numbers:
|
|
159
|
-
# column = []
|
|
160
|
-
# for i in range(len(element_node_numbers.loc[0, :])):
|
|
161
|
-
# index = element_node_numbers[element_node_numbers[i] == node].index
|
|
162
|
-
# column.append(index[0] if not index.empty else float('nan'))
|
|
163
|
-
# first_elem = np.nanmin(column)
|
|
164
|
-
# self._elem_list_for_nodes.append(int(first_elem))
|
|
165
|
-
# self._index_elem.append(column.index(first_elem))
|
|
166
|
-
|
|
167
|
-
# for node in self._node_numbers:
|
|
168
|
-
# self._elem_list_for_nodes.append([i for i in range(len(self._element_node_numbers))
|
|
169
|
-
# if node in self._element_node_numbers[i]][0])
|
|
170
|
-
# self._index_elem.append(self._element_node_numbers[self._elem_list_for_nodes[-1]].index(node))
|
|
171
|
-
|
|
172
|
-
# for node in self._node_numbers:
|
|
173
|
-
# n_idx = -1
|
|
174
|
-
# e_idx = 0
|
|
175
|
-
# while n_idx == -1:
|
|
176
|
-
# try:
|
|
177
|
-
# n_idx = self._element_node_numbers[e_idx].index(node)
|
|
178
|
-
# self._elem_list_for_nodes.append(e_idx)
|
|
179
|
-
# self._index_elem.append(n_idx)
|
|
180
|
-
# except ValueError:
|
|
181
|
-
# e_idx += 1
|
|
182
|
-
|
|
183
|
-
def _node_values_dict(self):
|
|
184
|
-
self.regions_dict = {}
|
|
185
|
-
for reg_tag, elem_of_reg in zip(self._element_physical_tags, self._data_element_tags):
|
|
186
|
-
if reg_tag not in self.regions_dict:
|
|
187
|
-
self.regions_dict[reg_tag] = []
|
|
188
|
-
self.regions_dict[reg_tag].append(elem_of_reg)
|
|
189
|
-
|
|
190
|
-
self.elements_dict = {}
|
|
191
|
-
for elem_tag, nodes_of_elem in zip(self._data_element_tags, self._element_node_numbers):
|
|
192
|
-
self.elements_dict[elem_tag] = nodes_of_elem
|
|
193
|
-
|
|
194
|
-
self.nodes_dict = {}
|
|
195
|
-
for n_num, coors, elem_tag, idx in zip(self._node_numbers, self._node_coordinates,
|
|
196
|
-
self._elem_list_for_nodes, self._index_elem):
|
|
197
|
-
self.nodes_dict[n_num] = {}
|
|
198
|
-
for i, key in zip(range(self._entityDim), ['x', 'y', 'z']):
|
|
199
|
-
self.nodes_dict[n_num][key] = coors[i]
|
|
200
|
-
for i, key in zip(range(self._entityDim), ['Vx', 'Vy', 'Vz']):
|
|
201
|
-
self.nodes_dict[n_num][key] = self._values[elem_tag][idx * self._entityDim + i]
|
|
202
|
-
self.nodes_dict[n_num]['e'] = self._data_element_tags[elem_tag]
|
|
203
|
-
|
|
204
|
-
def _parse(self):
|
|
205
|
-
"""
|
|
206
|
-
Call all parsing functions in the right sequence.
|
|
207
|
-
"""
|
|
208
|
-
self._mesh_format()
|
|
209
|
-
self._physical_names()
|
|
210
|
-
self._nodes()
|
|
211
|
-
self._elements_node_data() # this one needs to be called before _elements method.
|
|
212
|
-
self._elements()
|
|
213
|
-
self.__element_for_node()
|
|
214
|
-
self._node_values_dict()
|
|
1
|
+
import re
|
|
2
|
+
import inspect
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ParserPOS:
|
|
7
|
+
|
|
8
|
+
def __init__(self, pos_file_path):
|
|
9
|
+
"""
|
|
10
|
+
Read pos file and returns its content as object attribute .data_dict that is a dictionary.
|
|
11
|
+
:param pos_file_path: Full path to .pos file, including file name and extension.
|
|
12
|
+
"""
|
|
13
|
+
self._mesh_format_markers = {'s': '$MeshFormat', 'e': '$EndMeshFormat'}
|
|
14
|
+
self._nodes_markers = {'s': '$Nodes', 'e': '$EndNodes'}
|
|
15
|
+
self._elements_markers = {'s': '$Elements', 'e': '$EndElements'}
|
|
16
|
+
self._elements_node_data_markers = {'s': '$ElementNodeData', 'e': '$EndElementNodeData'}
|
|
17
|
+
self._physical_name_markers = {'s': 'PhysicalNames', 'e': '$EndPhysicalNames'}
|
|
18
|
+
|
|
19
|
+
with open(pos_file_path, "r", encoding="utf-8", errors="replace") as f:
|
|
20
|
+
self._contents = f.read()
|
|
21
|
+
# node properteis
|
|
22
|
+
self._node_numbers = []
|
|
23
|
+
self._node_coordinates = []
|
|
24
|
+
# element properties
|
|
25
|
+
self._element_numbers = []
|
|
26
|
+
self._element_types = []
|
|
27
|
+
self._element_number_of_tags = []
|
|
28
|
+
self._element_physical_tags = []
|
|
29
|
+
self._element_elementary_tags = []
|
|
30
|
+
self._element_node_numbers = []
|
|
31
|
+
# elements_node_data properties
|
|
32
|
+
self._data_element_tags = []
|
|
33
|
+
self._data_num_nodes_per_element = []
|
|
34
|
+
self._values = []
|
|
35
|
+
# parse the content (output is in this class attributes)
|
|
36
|
+
self._parse()
|
|
37
|
+
|
|
38
|
+
def __get_content(self, markers_dict):
|
|
39
|
+
"""
|
|
40
|
+
Gets text string between two markers specified in markers_dict
|
|
41
|
+
"""
|
|
42
|
+
return self._contents[self._contents.find(markers_dict['s']) + len(markers_dict['s']):self._contents.find(markers_dict['e'])]
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def __get_lines(data_str, empty_lines=[0, -1]):
|
|
46
|
+
"""
|
|
47
|
+
Converts text string into a list of lines
|
|
48
|
+
"""
|
|
49
|
+
data_str = re.sub('\n', "'", data_str)
|
|
50
|
+
data_str = re.sub('"', '', data_str)
|
|
51
|
+
str_list = re.split("'", data_str)
|
|
52
|
+
for empty_line in empty_lines:
|
|
53
|
+
if not str_list.pop(empty_line) == '':
|
|
54
|
+
raise ValueError('Error in parsing lines')
|
|
55
|
+
return str_list
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def __list_from_list_at_pos(dest_list, source_list, d_type, pos):
|
|
59
|
+
"""
|
|
60
|
+
This one is a bit complex. It converts a supplied in source list and appends it destination list.
|
|
61
|
+
It uses data type and position to append to the right type to the destination list from the right place in the source list.
|
|
62
|
+
Position could be an integer, a list of integers or a tuple with a reference variables to figure out positions from them.
|
|
63
|
+
"""
|
|
64
|
+
if isinstance(pos, int):
|
|
65
|
+
dest_list.append(d_type(source_list[pos]))
|
|
66
|
+
elif isinstance(pos, list):
|
|
67
|
+
dest_list.append([d_type(source_list[p]) for p in pos])
|
|
68
|
+
elif isinstance(pos, tuple):
|
|
69
|
+
offset = pos[0]
|
|
70
|
+
dimension = pos[1]
|
|
71
|
+
ref_list = pos[2]
|
|
72
|
+
current_num_elem = ref_list[len(dest_list)] # get current element
|
|
73
|
+
pos = list(range(offset, dimension * current_num_elem + offset))
|
|
74
|
+
dest_list.append([d_type(source_list[p]) for p in pos])
|
|
75
|
+
|
|
76
|
+
def __parse_lines(self, lines, list_of_outputs_lists, list_of_data_types, list_of_positions, len_check, ):
|
|
77
|
+
"""
|
|
78
|
+
Simply loop through lines and append to class attributes lists. Basic error check if number of lines in the list matches that declared in the file.
|
|
79
|
+
"""
|
|
80
|
+
for line in lines:
|
|
81
|
+
values = re.split(' ', line)
|
|
82
|
+
for dest_list, d_type, pos in zip(list_of_outputs_lists, list_of_data_types, list_of_positions):
|
|
83
|
+
self.__list_from_list_at_pos(dest_list, values, d_type, pos)
|
|
84
|
+
for out_list in list_of_outputs_lists:
|
|
85
|
+
if not len_check == len(out_list):
|
|
86
|
+
raise ValueError(f'Error in parsing {inspect.stack()[1].function}')
|
|
87
|
+
|
|
88
|
+
def _mesh_format(self):
|
|
89
|
+
"""
|
|
90
|
+
Parse mesh_generators field and assign it to the class attribute
|
|
91
|
+
"""
|
|
92
|
+
self.mesh_format = self.__get_content(self._mesh_format_markers)
|
|
93
|
+
|
|
94
|
+
def _physical_names(self):
|
|
95
|
+
"""
|
|
96
|
+
Parse physical_names field and assign it to the class attribute
|
|
97
|
+
"""
|
|
98
|
+
self.physical_names = self.__get_content(self._physical_name_markers)
|
|
99
|
+
|
|
100
|
+
def _nodes(self):
|
|
101
|
+
"""
|
|
102
|
+
Parse nodes and assign it to the class attributes
|
|
103
|
+
"""
|
|
104
|
+
data_str = self.__get_content(self._nodes_markers)
|
|
105
|
+
lines = self.__get_lines(data_str)
|
|
106
|
+
self._number_of_nodes = int(lines.pop(0))
|
|
107
|
+
list_of_outputs_lists = [self._node_numbers, self._node_coordinates]
|
|
108
|
+
list_of_data_types = [int, float]
|
|
109
|
+
list_of_positions = [0, [1, 2, 3]]
|
|
110
|
+
self.__parse_lines(lines, list_of_outputs_lists, list_of_data_types, list_of_positions, self._number_of_nodes)
|
|
111
|
+
|
|
112
|
+
def _elements(self):
|
|
113
|
+
"""
|
|
114
|
+
Parse elements and assign it to the class attributes
|
|
115
|
+
"""
|
|
116
|
+
data_str = self.__get_content(self._elements_markers)
|
|
117
|
+
lines = self.__get_lines(data_str)
|
|
118
|
+
self._number_of_elements = int(lines.pop(0))
|
|
119
|
+
list_of_outputs_lists = [self._element_numbers, self._element_types, self._element_number_of_tags, self._element_physical_tags, self._element_elementary_tags, self._element_node_numbers]
|
|
120
|
+
list_of_data_types = [int, int, int, int, int, int]
|
|
121
|
+
list_of_positions = [0, 1, 2, 3, 4, (5, 1, self._data_num_nodes_per_element)]
|
|
122
|
+
self.__parse_lines(lines, list_of_outputs_lists, list_of_data_types, list_of_positions, self._number_of_elements)
|
|
123
|
+
|
|
124
|
+
def _elements_node_data(self):
|
|
125
|
+
"""
|
|
126
|
+
Parse elements data and assign it to the class attributes
|
|
127
|
+
"""
|
|
128
|
+
data_str = self.__get_content(self._elements_node_data_markers)
|
|
129
|
+
lines = self.__get_lines(data_str)
|
|
130
|
+
self._numStringTags = int(lines.pop(0))
|
|
131
|
+
self._stringTags = str(lines.pop(0))
|
|
132
|
+
self._numRealTags = int(lines.pop(0))
|
|
133
|
+
self._realTags = float(lines.pop(0))
|
|
134
|
+
self._numIntegerTags = int(lines.pop(0))
|
|
135
|
+
self._integerTags = int(lines.pop(0))
|
|
136
|
+
self._entityDim = int(lines.pop(0))
|
|
137
|
+
self._number_of_elements_data = int(lines.pop(0))
|
|
138
|
+
self._not_sure = int(lines.pop(0)) # not sure what this number is
|
|
139
|
+
list_of_outputs_lists = [self._data_element_tags, self._data_num_nodes_per_element, self._values]
|
|
140
|
+
list_of_data_types = [int, int, float]
|
|
141
|
+
list_of_positions = [0, 1, (2, self._entityDim, self._data_num_nodes_per_element)]
|
|
142
|
+
self.__parse_lines(lines, list_of_outputs_lists, list_of_data_types, list_of_positions, self._number_of_elements_data)
|
|
143
|
+
|
|
144
|
+
def __element_for_node(self):
|
|
145
|
+
self._elem_list_for_nodes = []
|
|
146
|
+
self._index_elem = []
|
|
147
|
+
element_node_numbers = pd.DataFrame(self._element_node_numbers)
|
|
148
|
+
for node in self._node_numbers:
|
|
149
|
+
index = pd.Index
|
|
150
|
+
i = -1
|
|
151
|
+
while index.empty:
|
|
152
|
+
i += 1
|
|
153
|
+
index = element_node_numbers[element_node_numbers[i] == node].index
|
|
154
|
+
self._elem_list_for_nodes.append(index[0])
|
|
155
|
+
self._index_elem.append(i)
|
|
156
|
+
|
|
157
|
+
# element_node_numbers = pd.DataFrame(self._element_node_numbers)
|
|
158
|
+
# for node in self._node_numbers:
|
|
159
|
+
# column = []
|
|
160
|
+
# for i in range(len(element_node_numbers.loc[0, :])):
|
|
161
|
+
# index = element_node_numbers[element_node_numbers[i] == node].index
|
|
162
|
+
# column.append(index[0] if not index.empty else float('nan'))
|
|
163
|
+
# first_elem = np.nanmin(column)
|
|
164
|
+
# self._elem_list_for_nodes.append(int(first_elem))
|
|
165
|
+
# self._index_elem.append(column.index(first_elem))
|
|
166
|
+
|
|
167
|
+
# for node in self._node_numbers:
|
|
168
|
+
# self._elem_list_for_nodes.append([i for i in range(len(self._element_node_numbers))
|
|
169
|
+
# if node in self._element_node_numbers[i]][0])
|
|
170
|
+
# self._index_elem.append(self._element_node_numbers[self._elem_list_for_nodes[-1]].index(node))
|
|
171
|
+
|
|
172
|
+
# for node in self._node_numbers:
|
|
173
|
+
# n_idx = -1
|
|
174
|
+
# e_idx = 0
|
|
175
|
+
# while n_idx == -1:
|
|
176
|
+
# try:
|
|
177
|
+
# n_idx = self._element_node_numbers[e_idx].index(node)
|
|
178
|
+
# self._elem_list_for_nodes.append(e_idx)
|
|
179
|
+
# self._index_elem.append(n_idx)
|
|
180
|
+
# except ValueError:
|
|
181
|
+
# e_idx += 1
|
|
182
|
+
|
|
183
|
+
def _node_values_dict(self):
|
|
184
|
+
self.regions_dict = {}
|
|
185
|
+
for reg_tag, elem_of_reg in zip(self._element_physical_tags, self._data_element_tags):
|
|
186
|
+
if reg_tag not in self.regions_dict:
|
|
187
|
+
self.regions_dict[reg_tag] = []
|
|
188
|
+
self.regions_dict[reg_tag].append(elem_of_reg)
|
|
189
|
+
|
|
190
|
+
self.elements_dict = {}
|
|
191
|
+
for elem_tag, nodes_of_elem in zip(self._data_element_tags, self._element_node_numbers):
|
|
192
|
+
self.elements_dict[elem_tag] = nodes_of_elem
|
|
193
|
+
|
|
194
|
+
self.nodes_dict = {}
|
|
195
|
+
for n_num, coors, elem_tag, idx in zip(self._node_numbers, self._node_coordinates,
|
|
196
|
+
self._elem_list_for_nodes, self._index_elem):
|
|
197
|
+
self.nodes_dict[n_num] = {}
|
|
198
|
+
for i, key in zip(range(self._entityDim), ['x', 'y', 'z']):
|
|
199
|
+
self.nodes_dict[n_num][key] = coors[i]
|
|
200
|
+
for i, key in zip(range(self._entityDim), ['Vx', 'Vy', 'Vz']):
|
|
201
|
+
self.nodes_dict[n_num][key] = self._values[elem_tag][idx * self._entityDim + i]
|
|
202
|
+
self.nodes_dict[n_num]['e'] = self._data_element_tags[elem_tag]
|
|
203
|
+
|
|
204
|
+
def _parse(self):
|
|
205
|
+
"""
|
|
206
|
+
Call all parsing functions in the right sequence.
|
|
207
|
+
"""
|
|
208
|
+
self._mesh_format()
|
|
209
|
+
self._physical_names()
|
|
210
|
+
self._nodes()
|
|
211
|
+
self._elements_node_data() # this one needs to be called before _elements method.
|
|
212
|
+
self._elements()
|
|
213
|
+
self.__element_for_node()
|
|
214
|
+
self._node_values_dict()
|