wawi 0.0.8__tar.gz → 0.0.9__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.
Potentially problematic release.
This version of wawi might be problematic. Click here for more details.
- {wawi-0.0.8/wawi.egg-info → wawi-0.0.9}/PKG-INFO +1 -1
- wawi-0.0.9/examples/3 Software interfacing/Abaqus model export/bergsoysund-export.py +72 -0
- wawi-0.0.9/examples/3 Software interfacing/Abaqus model export/test.py +67 -0
- {wawi-0.0.8 → wawi-0.0.9}/pyproject.toml +3 -3
- {wawi-0.0.8 → wawi-0.0.9}/wawi/__init__.py +1 -1
- wawi-0.0.9/wawi/ext/__init__.py +0 -0
- wawi-0.0.9/wawi/ext/abq.py +259 -0
- wawi-0.0.9/wawi/ext/abq_legacy.py +462 -0
- wawi-0.0.9/wawi/ext/ansys.py +0 -0
- wawi-0.0.9/wawi/ext/orcaflex.py +0 -0
- wawi-0.0.9/wawi/ext/sofistik.py +0 -0
- wawi-0.0.9/wawi/model/__init__.py +11 -0
- wawi-0.0.9/wawi/model/_aero.py +363 -0
- wawi-0.0.9/wawi/model/_dry.py +141 -0
- wawi-0.0.9/wawi/model/_hydro.py +882 -0
- wawi-0.0.9/wawi/model/_model.py +1324 -0
- wawi-0.0.9/wawi/model/_screening.py +124 -0
- {wawi-0.0.8 → wawi-0.0.9/wawi.egg-info}/PKG-INFO +1 -1
- {wawi-0.0.8 → wawi-0.0.9}/wawi.egg-info/SOURCES.txt +15 -1
- wawi-0.0.9/wawi.egg-info/top_level.txt +5 -0
- wawi-0.0.8/wawi.egg-info/top_level.txt +0 -1
- {wawi-0.0.8 → wawi-0.0.9}/LICENSE +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/README.md +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/setup.cfg +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/tests/test_IABSE_step11a.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/tests/test_IABSE_step11c.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/tests/test_IABSE_step2a.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/tests/test_wind.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/fe.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/general.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/identification.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/io.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/modal.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/plot.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/prob.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/random.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/signal.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/structural.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/time_domain.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/tools.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/wave.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/wind.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi/wind_code.py +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi.egg-info/dependency_links.txt +0 -0
- {wawi-0.0.8 → wawi-0.0.9}/wawi.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: wawi
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.9
|
4
4
|
Summary: WAve and WInd response prediction
|
5
5
|
Author-email: "Knut A. Kvåle" <knut.a.kvale@ntnu.no>, Ole Øiseth <ole.oiseth@ntnu.no>, Aksel Fenerci <aksel.fenerci@ntnu.no>, Øivind Wiig Petersen <oyvind.w.petersen@ntnu.no>
|
6
6
|
License: MIT License
|
@@ -0,0 +1,72 @@
|
|
1
|
+
from sys import path
|
2
|
+
from collections import OrderedDict
|
3
|
+
|
4
|
+
path.append('C:/Users/knutankv/git-repos/wawi/') # this is an easy quick fix to enable importing wawi package in Abaqus environment
|
5
|
+
savefolder = 'C:/Temp/'
|
6
|
+
|
7
|
+
# NOTE: Only linear beam elements are supported in relevant sets!!
|
8
|
+
|
9
|
+
import wawi.ext.abq
|
10
|
+
import json
|
11
|
+
import numpy as np
|
12
|
+
|
13
|
+
#%% Get (O) database object
|
14
|
+
db = wawi.ext.abq.get_db('odb')
|
15
|
+
|
16
|
+
#%% Definitions
|
17
|
+
frequency_step = 'Step-1'
|
18
|
+
part = db.rootAssembly.instances['TRUSSPART']
|
19
|
+
step_obj = db.steps[frequency_step]
|
20
|
+
|
21
|
+
if 'ALL' not in part.elementSets: #CREATE SET OF ALL ELEMENTS IN PART
|
22
|
+
part.ElementSet('ALL', part.elements)
|
23
|
+
|
24
|
+
#%% Grab regions
|
25
|
+
region_full = part.elementSets['ALL']
|
26
|
+
region_hydro = db.rootAssembly.nodeSets['PALL']
|
27
|
+
|
28
|
+
#%% Get modal parameters
|
29
|
+
fn, m = wawi.ext.abq.get_modal_parameters(frequency_step)
|
30
|
+
|
31
|
+
#%% Get wind elements and mode shapes
|
32
|
+
node_matrix, element_matrix = wawi.ext.abq.get_element_matrices(region_full, obj=part)
|
33
|
+
node_labels = node_matrix[:,0]
|
34
|
+
nodes = wawi.ext.abq.create_list_of_nodes(part, node_labels)
|
35
|
+
|
36
|
+
# Export element definitions as json
|
37
|
+
el_data = dict(node_matrix=node_matrix.tolist(), element_matrix=element_matrix.tolist())
|
38
|
+
|
39
|
+
with open('element.json', 'w') as f:
|
40
|
+
json.dump(el_data, f)
|
41
|
+
|
42
|
+
phi_full_disp = wawi.ext.abq.get_nodal_phi(step_obj, nodes, flatten_components=True, field_outputs=['UT', 'UR'])
|
43
|
+
|
44
|
+
#%% Get pontoon data
|
45
|
+
node_matrix_pontoons = wawi.ext.abq.get_element_matrices(region_hydro, obj=part)
|
46
|
+
node_labels_pontoons = node_matrix_pontoons[:,0]
|
47
|
+
nodes_pontoons = wawi.ext.abq.create_list_of_nodes(part, node_labels_pontoons)
|
48
|
+
phi_h = wawi.ext.abq.get_nodal_phi(step_obj, nodes_pontoons, flatten_components=True, field_outputs=['UT', 'UR'])
|
49
|
+
|
50
|
+
# Export pontoon.json
|
51
|
+
pontoon_types = ['ptype_1']*7
|
52
|
+
rotations = -np.array([13.944407004001892, 9.2962713360012632, 4.6481356680006325, 0.0,
|
53
|
+
-4.6481356680006334, -9.2962713360012632, -13.944407004001883])
|
54
|
+
|
55
|
+
pontoon_data = OrderedDict()
|
56
|
+
|
57
|
+
for ix, node in enumerate(node_labels_pontoons):
|
58
|
+
key = 'P'+str (ix+1)
|
59
|
+
pontoon_data[key] = dict(coordinates=node_matrix_pontoons[ix, 1:].tolist(),
|
60
|
+
node=node,
|
61
|
+
rotation=rotations[ix],
|
62
|
+
pontoon_type=pontoon_types[ix])
|
63
|
+
|
64
|
+
with open('pontoon.json', 'w') as f:
|
65
|
+
json.dump(pontoon_data, f)
|
66
|
+
|
67
|
+
## ------------------- EXPORT MODES ----------------
|
68
|
+
modal_data = dict(omega_n=(fn*2*np.pi).tolist(), m=m.tolist(), phi=dict(full=phi_full_disp.tolist(),
|
69
|
+
hydro=phi_h.tolist()))
|
70
|
+
|
71
|
+
with open('modal.json', 'w') as f:
|
72
|
+
json.dump(modal_data, f)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
from sys import path
|
2
|
+
from collections import OrderedDict
|
3
|
+
|
4
|
+
path.append('C:/Users/knutankv/git-repos/wawi/') # this is an easy quick fix to enable importing wawi package in Abaqus environment
|
5
|
+
savefolder = 'C:/Temp/'
|
6
|
+
|
7
|
+
import wawi.ext.abq
|
8
|
+
import json
|
9
|
+
import numpy as np
|
10
|
+
|
11
|
+
#%% Get (O) database object
|
12
|
+
db = wawi.ext.abq.get_db('odb')
|
13
|
+
|
14
|
+
#%% Definitions
|
15
|
+
frequency_step = 'Step-6'
|
16
|
+
part = db.rootAssembly.instances['BRIDGE-1']
|
17
|
+
step_obj = db.steps[frequency_step]
|
18
|
+
|
19
|
+
if 'ALL' not in part.elementSets: #CREATE SET OF ALL ELEMENTS IN PART
|
20
|
+
part.ElementSet('ALL', part.elements)
|
21
|
+
|
22
|
+
#%% Grab regions
|
23
|
+
region_full = part.elementSets['ALL']
|
24
|
+
region_hydro = part.nodeSets['SPRING']
|
25
|
+
|
26
|
+
#%% Get modal parameters
|
27
|
+
fn, m = wawi.ext.abq.get_modal_parameters(frequency_step)
|
28
|
+
|
29
|
+
#%% Get wind elements and mode shapes
|
30
|
+
node_matrix, element_matrix = wawi.ext.abq.get_element_matrices(region_full, obj=part)
|
31
|
+
node_labels = node_matrix[:,0]
|
32
|
+
|
33
|
+
# Export element definitions as json
|
34
|
+
el_data = dict(node_matrix=node_matrix.tolist(), element_matrix=element_matrix.tolist())
|
35
|
+
|
36
|
+
with open('element.json', 'w') as f:
|
37
|
+
json.dump(el_data, f)
|
38
|
+
|
39
|
+
phi_full_disp = wawi.ext.abq.get_nodal_phi(step_obj, node_labels, flatten_components=True)
|
40
|
+
|
41
|
+
#%% Get pontoon data
|
42
|
+
node_matrix_pontoons = wawi.ext.abq.get_element_matrices(region_hydro, obj=part, sort_nodes_fun=None)
|
43
|
+
node_labels = node_matrix_pontoons[:,0]
|
44
|
+
phi_h = wawi.ext.abq.get_nodal_phi(step_obj, node_labels, flatten_components=True)
|
45
|
+
|
46
|
+
# Export pontoon.json
|
47
|
+
pontoon_types = ['ptype_1']*48
|
48
|
+
rotations = np.zeros(48)
|
49
|
+
|
50
|
+
pontoon_data = OrderedDict()
|
51
|
+
|
52
|
+
for ix, node in enumerate(node_labels):
|
53
|
+
key = 'P'+str (ix+1)
|
54
|
+
pontoon_data[key] = dict(coordinates=node_matrix_pontoons[ix, 1:].tolist(),
|
55
|
+
node=node,
|
56
|
+
rotation=rotations[ix],
|
57
|
+
pontoon_type=pontoon_types[ix])
|
58
|
+
|
59
|
+
with open('pontoon.json', 'w') as f:
|
60
|
+
json.dump(pontoon_data, f)
|
61
|
+
|
62
|
+
## ------------------- EXPORT MODES ----------------
|
63
|
+
modal_data = dict(omega_n=(fn*2*np.pi).tolist(), m=m.tolist(), phi=dict(full=phi_full_disp.tolist(),
|
64
|
+
hydro=phi_h.tolist()))
|
65
|
+
|
66
|
+
with open('modal.json', 'w') as f:
|
67
|
+
json.dump(modal_data, f)
|
@@ -27,12 +27,12 @@ dependencies = ["plotly", "pandas", "numpy", "pyvista[jupyter]>=0.38.1",
|
|
27
27
|
"beefpy"]
|
28
28
|
|
29
29
|
|
30
|
-
[tool.setuptools]
|
31
|
-
packages = ["wawi"]
|
32
|
-
|
33
30
|
[tool.setuptools.dynamic]
|
34
31
|
version = {attr = "wawi.__version__"}
|
35
32
|
|
33
|
+
[tool.setuptools.packages]
|
34
|
+
find = {}
|
35
|
+
|
36
36
|
[project.urls]
|
37
37
|
repository = "https://github.com/knutankv/wawi"
|
38
38
|
documentation = "https://knutankv.github.io/wawi/"
|
File without changes
|
@@ -0,0 +1,259 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import numpy as np
|
3
|
+
import pdb
|
4
|
+
|
5
|
+
from abaqus import *
|
6
|
+
from abaqus import session
|
7
|
+
from abaqusConstants import *
|
8
|
+
import __main__
|
9
|
+
import section
|
10
|
+
import regionToolset
|
11
|
+
import displayGroupMdbToolset as dgm
|
12
|
+
import step
|
13
|
+
import part
|
14
|
+
import material
|
15
|
+
import assembly
|
16
|
+
import interaction
|
17
|
+
import load
|
18
|
+
import mesh
|
19
|
+
import optimization
|
20
|
+
import job
|
21
|
+
import sketch
|
22
|
+
import visualization
|
23
|
+
import xyPlot
|
24
|
+
import displayGroupOdbToolset as dgo
|
25
|
+
import connectorBehavior
|
26
|
+
import symbolicConstants
|
27
|
+
import odbAccess
|
28
|
+
import shutil
|
29
|
+
|
30
|
+
import regionToolset
|
31
|
+
|
32
|
+
import csv
|
33
|
+
from copy import deepcopy
|
34
|
+
|
35
|
+
|
36
|
+
def get_db(db_type):
|
37
|
+
"""
|
38
|
+
Return the current database (either a model or an odb object).
|
39
|
+
|
40
|
+
If a model db is wanted and no model is active, the model in the mdb is selected regardless,
|
41
|
+
as long as there is only one model open in the mdb. If no database fits the requirements, None is returned.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
db_type: 'odb' or 'model'
|
45
|
+
Returns:
|
46
|
+
db: database
|
47
|
+
|
48
|
+
NTNU / Knut Andreas Kvaale, 2018
|
49
|
+
"""
|
50
|
+
if db_type is 'model' or db_type is 'mdb':
|
51
|
+
if not session_is_odb():
|
52
|
+
db = mdb.models[session.viewports['Viewport: 1'].displayedObject.modelName]
|
53
|
+
elif len(mdb.models.keys()) is 1:
|
54
|
+
db = mdb.models[mdb.models.keys()[0]]
|
55
|
+
elif len(mdb.models.keys()) > 1:
|
56
|
+
raise AttributeError('No model is not active, and more than one model is available in model database. Impossible to select correct.')
|
57
|
+
else:
|
58
|
+
db = None
|
59
|
+
else:
|
60
|
+
if session_is_odb():
|
61
|
+
db = session.viewports[session.currentViewportName].displayedObject
|
62
|
+
else:
|
63
|
+
db = None
|
64
|
+
|
65
|
+
return db
|
66
|
+
|
67
|
+
def session_is_odb():
|
68
|
+
"""
|
69
|
+
Check if current session is ODB.
|
70
|
+
|
71
|
+
Returns:
|
72
|
+
is_odb: boolean indicating if the session is odb or not
|
73
|
+
"""
|
74
|
+
is_odb =(('session' in locals() or 'session' in globals()) and
|
75
|
+
session.viewports['Viewport: 1'].displayedObject is not None and
|
76
|
+
hasattr(session.viewports['Viewport: 1'].displayedObject, 'jobData'))
|
77
|
+
|
78
|
+
return is_odb
|
79
|
+
|
80
|
+
def sort_nodes(nodes, sort_nodes_fun=lambda node: node.label):
|
81
|
+
if sort_nodes_fun is not None:
|
82
|
+
sort_val = [sort_nodes_fun(node) for node in nodes]
|
83
|
+
sort_ix = np.argsort(sort_val)
|
84
|
+
nodes_new = [None] * len(nodes)
|
85
|
+
for node,ix in zip(nodes,sort_ix):
|
86
|
+
nodes_new[ix] = node
|
87
|
+
|
88
|
+
return nodes_new
|
89
|
+
else:
|
90
|
+
return nodes
|
91
|
+
|
92
|
+
def get_element_matrices(region, obj=None, sort_nodes_fun=lambda node: node.label):
|
93
|
+
|
94
|
+
if region.nodes is None: #element region
|
95
|
+
if obj is None:
|
96
|
+
raise ValueError('If region is of element type, `obj` must be given as input. This is either an `instance` object or a `rootAssembly`')
|
97
|
+
|
98
|
+
elements = region.elements
|
99
|
+
element_labels = [el.label for el in elements]
|
100
|
+
element_matrix = np.zeros([len(element_labels), 3])
|
101
|
+
|
102
|
+
node_labels = []
|
103
|
+
for ix,el in enumerate(elements):
|
104
|
+
element_matrix[ix,0] = el.label
|
105
|
+
nodes = list(el.connectivity)
|
106
|
+
if len(nodes)==3:
|
107
|
+
__ = nodes.pop(1) #remove middle node
|
108
|
+
element_matrix[ix, 1:] = nodes
|
109
|
+
|
110
|
+
for node in nodes:
|
111
|
+
if node not in node_labels:
|
112
|
+
node_labels.append(node)
|
113
|
+
|
114
|
+
nodes = [obj.getNodeFromLabel(node) for node in node_labels]
|
115
|
+
nodes = sort_nodes(nodes, sort_nodes_fun=sort_nodes_fun)
|
116
|
+
node_matrix = create_node_matrix(nodes)
|
117
|
+
return node_matrix, element_matrix
|
118
|
+
|
119
|
+
else: # node region
|
120
|
+
if type(region.nodes) is tuple:
|
121
|
+
nodes = region.nodes[0]
|
122
|
+
else:
|
123
|
+
nodes = region.nodes
|
124
|
+
nodes = sort_nodes(nodes, sort_nodes_fun=sort_nodes_fun)
|
125
|
+
node_matrix = create_node_matrix(nodes)
|
126
|
+
|
127
|
+
return node_matrix
|
128
|
+
|
129
|
+
|
130
|
+
def create_list_of_nodes(region, node_labels):
|
131
|
+
return [region.getNodeFromLabel(int(label)) for label in node_labels]
|
132
|
+
|
133
|
+
def create_list_of_elements(region, element_labels):
|
134
|
+
return [region.getElementFromLabel(int(label)) for label in element_labels]
|
135
|
+
|
136
|
+
def create_node_matrix(nodes):
|
137
|
+
labels = np.hstack([node.label for node in nodes])[:,np.newaxis]
|
138
|
+
coordinates = np.vstack([node.coordinates for node in nodes])
|
139
|
+
node_matrix = np.hstack([labels, coordinates])
|
140
|
+
|
141
|
+
return node_matrix
|
142
|
+
|
143
|
+
def get_nodal_phi(step_obj, nodes, field_outputs=['U', 'UR'], flatten_components=True, return_base_disp=False):
|
144
|
+
|
145
|
+
if step_obj.domain != MODAL: #MODAL is a variable in abaqusConstants
|
146
|
+
raise TypeError('Type of input step is not modal!')
|
147
|
+
|
148
|
+
n_nodes = len(nodes)
|
149
|
+
n_modes = len(step_obj.frames) - 1
|
150
|
+
|
151
|
+
phi = dict()
|
152
|
+
basedisp = dict()
|
153
|
+
n_dofs = dict()
|
154
|
+
|
155
|
+
for iout, field_output in enumerate(field_outputs):
|
156
|
+
foobj0 = step_obj.frames[0].fieldOutputs[field_output]
|
157
|
+
|
158
|
+
n_dofs[field_output] = len(foobj0.values[0].data)
|
159
|
+
phio = np.zeros([n_dofs[field_output]*n_nodes, n_modes])
|
160
|
+
|
161
|
+
# Get correct data indices to get correct order (as given in node_labels)
|
162
|
+
basedisp[field_output] = np.array([foobj0.getSubset(region=node).values[0].data for node in nodes]).flatten()
|
163
|
+
|
164
|
+
for mode in range(0, n_modes):
|
165
|
+
foobj = step_obj.frames[mode+1].fieldOutputs[field_output]
|
166
|
+
phio[:, mode] = np.array([foobj.getSubset(region=node).values[0].data for node in nodes]).flatten()
|
167
|
+
|
168
|
+
phi[field_output] = phio*1
|
169
|
+
|
170
|
+
if flatten_components:
|
171
|
+
phi_merged = [None]*n_modes
|
172
|
+
|
173
|
+
for mode in range(n_modes):
|
174
|
+
phi_merged[mode] = np.hstack([np.array(phi[key][:, mode]).reshape([-1,n_dofs[key]]) for key in field_outputs]).flatten()
|
175
|
+
|
176
|
+
basedisp = np.hstack([np.array(basedisp[key]).reshape([-1,n_dofs[key]]) for key in field_outputs]).flatten()
|
177
|
+
phi = np.vstack(phi_merged).T
|
178
|
+
|
179
|
+
if return_base_disp:
|
180
|
+
return phi, basedisp
|
181
|
+
else:
|
182
|
+
return phi
|
183
|
+
|
184
|
+
|
185
|
+
def get_element_phi(step_obj, elements, field_outputs=['SF', 'SM'], flatten_components=True, return_integration_points=False):
|
186
|
+
if step_obj.domain != MODAL: #MODAL is a variable in abaqusConstants
|
187
|
+
raise TypeError('Type of input step is not modal!')
|
188
|
+
|
189
|
+
n_modes = len(step_obj.frames) - 1
|
190
|
+
n_dofs = dict()
|
191
|
+
phi = dict()
|
192
|
+
integration_points = dict()
|
193
|
+
|
194
|
+
for iout, field_output in enumerate(field_outputs):
|
195
|
+
foobj0 = step_obj.frames[0].fieldOutputs[field_output]
|
196
|
+
n_dofs[field_output] = len(foobj0.values[0].data)
|
197
|
+
|
198
|
+
# Get correct data indices to get correct order (as given in node_labels)
|
199
|
+
all_integration_points = [value.integrationPoint for value in foobj0.values]
|
200
|
+
|
201
|
+
n_int = len(elements) # number of integration points (same element label might appear multiple times if multiple integration points in element)
|
202
|
+
phio = np.zeros([n_dofs[field_output]*n_int, n_modes])
|
203
|
+
|
204
|
+
data_indices = [None]*n_int
|
205
|
+
|
206
|
+
for mode in range(0, n_modes):
|
207
|
+
foobj = step_obj.frames[mode+1].fieldOutputs[field_output]
|
208
|
+
phio[:, mode] = np.array([foobj.getSubset(region=el)[0].data for el in elements]).flatten()
|
209
|
+
|
210
|
+
integration_points[field_output] = [all_integration_points[ix] for ix in data_indices]
|
211
|
+
phi[field_output] = phio*1
|
212
|
+
|
213
|
+
if flatten_components:
|
214
|
+
phi_merged = [None]*n_modes
|
215
|
+
|
216
|
+
for mode in range(n_modes):
|
217
|
+
phi_merged[mode] = np.hstack([np.array(phi[key][:, mode]).reshape([-1,n_dofs[key]]) for key in field_outputs]).flatten()
|
218
|
+
|
219
|
+
integration_points = np.hstack([np.array(integration_points[key]).reshape([-1,n_dofs[key]]) for key in field_outputs]).flatten()
|
220
|
+
phi = np.vstack(phi_merged).T
|
221
|
+
|
222
|
+
|
223
|
+
if return_integration_points:
|
224
|
+
return phi, integration_points
|
225
|
+
else:
|
226
|
+
return phi
|
227
|
+
|
228
|
+
return phi, integration_points
|
229
|
+
|
230
|
+
|
231
|
+
def get_modal_parameters(frequency_step):
|
232
|
+
'''
|
233
|
+
Output the modal parameters from frequency step of current output database.
|
234
|
+
|
235
|
+
Parameters
|
236
|
+
-------------
|
237
|
+
frequency_step : str
|
238
|
+
name of step containing the modal results (frequency step)
|
239
|
+
|
240
|
+
Returns
|
241
|
+
--------------
|
242
|
+
f : float
|
243
|
+
numpy array with undamped natural frequencies in Hz of all modes computed
|
244
|
+
m : float
|
245
|
+
numpy array with modal mass for all modes computed
|
246
|
+
'''
|
247
|
+
|
248
|
+
odb = get_db('odb')
|
249
|
+
history_region_key = odb.steps[frequency_step].historyRegions.keys()[0]
|
250
|
+
|
251
|
+
ftemp = odb.steps[frequency_step].historyRegions[history_region_key].historyOutputs['EIGFREQ'].data
|
252
|
+
f = np.array([x[1] for x in ftemp])
|
253
|
+
|
254
|
+
if 'GM' in odb.steps[frequency_step].historyRegions[history_region_key].historyOutputs.keys():
|
255
|
+
mtemp = odb.steps[frequency_step].historyRegions[history_region_key].historyOutputs['GM'].data
|
256
|
+
m = np.array([x[1] for x in mtemp])
|
257
|
+
else:
|
258
|
+
m = np.ones(np.shape(f)) #if no GM field is available, mass normalization is assumed used on eigenvalues
|
259
|
+
return f, m
|