wawi 0.0.9__py3-none-any.whl → 0.0.12__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.

Potentially problematic release.


This version of wawi might be problematic. Click here for more details.

@@ -42,25 +42,29 @@ with open('element.json', 'w') as f:
42
42
  phi_full_disp = wawi.ext.abq.get_nodal_phi(step_obj, nodes, flatten_components=True, field_outputs=['UT', 'UR'])
43
43
 
44
44
  #%% Get pontoon data
45
- node_matrix_pontoons = wawi.ext.abq.get_element_matrices(region_hydro, obj=part)
45
+ pontoon_sets = ['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7']
46
+ pontoon_types = ['p17', 'p26', 'p345', 'p345', 'p345', 'p26', 'p17']
47
+ rotations = np.array([13.944407004001892, 9.2962713360012632, 4.6481356680006325, 0.0,
48
+ -4.6481356680006334, -9.2962713360012632, -13.944407004001883])
49
+
50
+ node_matrix_pontoons = np.vstack([wawi.ext.abq.get_element_matrices(db.rootAssembly.nodeSets[pset], obj=part) for pset in pontoon_sets])
46
51
  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
52
 
50
53
  # 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
54
  pontoon_data = OrderedDict()
56
55
 
57
56
  for ix, node in enumerate(node_labels_pontoons):
58
- key = 'P'+str (ix+1)
57
+ key = pontoon_sets[ix]
59
58
  pontoon_data[key] = dict(coordinates=node_matrix_pontoons[ix, 1:].tolist(),
60
59
  node=node,
61
60
  rotation=rotations[ix],
62
61
  pontoon_type=pontoon_types[ix])
63
62
 
63
+
64
+ nodes_pontoons = wawi.ext.abq.create_list_of_nodes(part, node_labels_pontoons)
65
+ phi_h = wawi.ext.abq.get_nodal_phi(step_obj, nodes_pontoons, flatten_components=True, field_outputs=['UT', 'UR'])
66
+
67
+
64
68
  with open('pontoon.json', 'w') as f:
65
69
  json.dump(pontoon_data, f)
66
70
 
@@ -0,0 +1,47 @@
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 database object (ODB)
14
+ db = wawi.ext.abq.get_db('odb')
15
+
16
+ #%% Definitions
17
+ frequency_step = 'Step-11' # define set name to extract modal properties from
18
+ part = db.rootAssembly.instances['PART-1-1'] # define part
19
+ step_obj = db.steps[frequency_step]
20
+
21
+ part.ElementSet('ALL', part.elements) # get all elements (for full element and node matrix)
22
+
23
+ #%% Grab regions
24
+ region_full = part.elementSets['ALL']
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
+ nodes = wawi.ext.abq.create_list_of_nodes(part, node_labels)
33
+
34
+ # Export element definitions as json
35
+ el_data = dict(node_matrix=node_matrix.tolist(),
36
+ element_matrix=element_matrix.tolist())
37
+
38
+ with open('element.json', 'w') as f:
39
+ json.dump(el_data, f)
40
+
41
+ phi_full_disp = wawi.ext.abq.get_nodal_phi(step_obj, nodes, flatten_components=True, field_outputs=['U', 'UR'])
42
+
43
+ ## ------------------- EXPORT MODES ----------------
44
+ modal_data = dict(omega_n=(fn*2*np.pi).tolist(), m=m.tolist(), phi=dict(full=phi_full_disp.tolist()))
45
+
46
+ with open('modal.json', 'w') as f:
47
+ json.dump(modal_data, f)
@@ -3,10 +3,10 @@ import pytest
3
3
  import numpy as np
4
4
  from math import isclose
5
5
 
6
- # use the local wawi (Github folder) instead of the installed version (remove this when using the installed version)
7
- import sys
8
- import os
9
- sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
6
+ # use the local wawi
7
+ #import sys
8
+ #import os
9
+ #sys.path.insert(0, r'C:\Users\aksef\OneDrive - Multiconsult\project\wawi\wawi_keep')
10
10
 
11
11
  # import functions
12
12
  from wawi.io import import_folder
@@ -108,7 +108,6 @@ def test_mean_speed_45():
108
108
  # PSD response
109
109
  S_exp = np.transpose(np.array( [ [0.0167, -0.007j], [0.007j, 0.00293] ] ))
110
110
 
111
-
112
111
  model = import_folder(model_folder)
113
112
  model.aero.windstate = iabse_11a_windstate(V)
114
113
 
@@ -121,11 +120,11 @@ def test_mean_speed_45():
121
120
  omega = np.array([0.001, f])*np.pi*2
122
121
  HH = eval_3d_fun(model.get_frf_fun(opt = 1), omega)
123
122
 
124
- model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
123
+ model.aero.sections['girder0'].admittance = lambda fred: np.full((4, 3), davenport(fred))
125
124
  model.run_freqsim(omega,
126
125
  include_selfexcited=['aero'],
127
126
  include_action=['aero'],
128
- print_progress=False, merge_aero_sections=True)
127
+ print_progress=False)
129
128
 
130
129
  global_dof_ix = np.array([2,3])
131
130
  S = model.get_result_psd(key='full',
@@ -170,12 +169,14 @@ def test_response_spectra(Vbuff, RS_vert_exp, RS_tors_exp):
170
169
  model.aero.windstate = iabse_11a_windstate(Vbuff)
171
170
  model.modal_dry.xi0 = .3e-2
172
171
  model.aero.sections['girder0'].ADs = ADs(**flatplate_ads())
173
- model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
172
+ model.aero.sections['girder0'].admittance = lambda fred: np.full((4, 3), davenport(fred))
174
173
 
175
174
  model.run_freqsim(omega_axis,
176
175
  include_selfexcited=['aero'],
177
176
  include_action=['aero'],
178
- print_progress=False, merge_aero_sections=True)
177
+ print_progress=False,
178
+ #merge_aero_sections=True
179
+ )
179
180
 
180
181
  global_dof_ix = np.array([2,3])
181
182
  S = model.get_result_psd(key='full',
@@ -204,12 +205,12 @@ def test_RMS_response(Vbuff, RMS_vert_exp, RMS_tors_exp):
204
205
  model.aero.windstate = iabse_11a_windstate(Vbuff)
205
206
  model.modal_dry.xi0 = .3e-2
206
207
  model.aero.sections['girder0'].ADs = ADs(**flatplate_ads())
207
- model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
208
+ model.aero.sections['girder0'].admittance = lambda fred: np.full((4, 3), davenport(fred))
208
209
 
209
210
  model.run_freqsim(omega_axis,
210
211
  include_selfexcited=['aero'],
211
212
  include_action=['aero'],
212
- print_progress=False, merge_aero_sections=True)
213
+ print_progress=False)
213
214
 
214
215
  stds = model.get_result_std(key = 'full')
215
216
 
@@ -5,9 +5,9 @@ from math import isclose
5
5
  import dill
6
6
 
7
7
  # use the local wawi (Github folder) instead of the installed version (remove this when using the installed version)
8
- import sys
9
- import os
10
- sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
8
+ #import sys
9
+ #import os
10
+ #sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
11
11
 
12
12
  # import functions
13
13
  from wawi.io import import_folder
@@ -166,11 +166,11 @@ def test_mean_speed_45():
166
166
  omega = np.array([0.001, f])*np.pi*2
167
167
  HH = eval_3d_fun(model.get_frf_fun(opt = 1), omega)
168
168
 
169
- model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
169
+ model.aero.sections['girder0'].admittance = lambda fred: np.full((4, 3), davenport(fred))
170
170
  model.run_freqsim(omega,
171
171
  include_selfexcited=['aero'],
172
172
  include_action=['aero'],
173
- print_progress=False, merge_aero_sections=True)
173
+ print_progress=False)
174
174
 
175
175
  global_dof_ix = np.array([1,2,3])
176
176
  S = model.get_result_psd(key='full',
@@ -225,13 +225,13 @@ def test_response_spectra(Vbuff, RS_horz_exp, RS_vert_exp, RS_tors_exp):
225
225
  AD_funs = dill.load(file)
226
226
  AD_s = AD_dict(AD_funs)
227
227
  model.aero.sections['girder0'].ADs = ADs(**AD_s)
228
- model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
228
+ model.aero.sections['girder0'].admittance = lambda fred: np.full((4, 3), davenport(fred))
229
229
 
230
230
  # run analysis
231
231
  model.run_freqsim(omega_axis,
232
232
  include_selfexcited=['aero'],
233
233
  include_action=['aero'],
234
- print_progress=False, merge_aero_sections=True)
234
+ print_progress=False)
235
235
 
236
236
  # extract PSD
237
237
  global_dof_ix = np.array([1,2,3])
@@ -265,13 +265,13 @@ def test_RMS_response(Vbuff, RMS_horz_exp, RMS_vert_exp, RMS_tors_exp):
265
265
  AD_funs = dill.load(file)
266
266
  AD_s = AD_dict(AD_funs)
267
267
  model.aero.sections['girder0'].ADs = ADs(**AD_s)
268
- model.aero.sections['girder0'].Admittance = lambda fred: np.full((4, 3), davenport(fred))
268
+ model.aero.sections['girder0'].admittance = lambda fred: np.full((4, 3), davenport(fred))
269
269
 
270
270
  # run analysis
271
271
  model.run_freqsim(omega_axis,
272
272
  include_selfexcited=['aero'],
273
273
  include_action=['aero'],
274
- print_progress=False, merge_aero_sections=True)
274
+ print_progress=False)
275
275
 
276
276
  # RMS responses
277
277
  stds = model.get_result_std(key = 'full')
@@ -4,9 +4,9 @@ from math import isclose
4
4
  import dill
5
5
 
6
6
  # use the local wawi (Github folder) instead of the installed version (remove this when using the installed version)
7
- import sys
8
- import os
9
- sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
7
+ #import sys
8
+ #import os
9
+ #sys.path.insert(0, os.path.abspath('C:\\Users\\aksef\\Documents\\GitHub\\wawi'))
10
10
 
11
11
  from wawi.io import import_folder
12
12
  from wawi.model import Windstate
@@ -184,14 +184,14 @@ def test_RS_spectra():
184
184
  model.aero.windstate = iabse_2a_windstate(V)
185
185
  # admittance
186
186
  for key in model.aero.sections:
187
- model.aero.sections[key].Admittance = lambda fred: np.full((4, 3), davenport(fred))
187
+ model.aero.sections[key].admittance = lambda fred: np.full((4, 3), davenport(fred))
188
188
 
189
189
  # run analysis
190
190
  model.run_freqsim(omega,
191
191
  include_selfexcited=['aero'],
192
192
  include_action=['aero'],
193
- print_progress=False, merge_aero_sections=True,
194
- ensure_at_peaks=False) # keep the given frequency axis
193
+ print_progress=False,
194
+ ensure_at_peaks=False) # keep the given frequency axis
195
195
 
196
196
 
197
197
  # extract PSD - at the midpsan
@@ -237,7 +237,7 @@ def test_RMS_response(Vbuff, RMS_horz_exp1, RMS_vert_exp1, RMS_tors_exp1, RMS_ho
237
237
  model.aero.windstate = iabse_2a_windstate(Vbuff)
238
238
  # admittance
239
239
  for key in model.aero.sections:
240
- model.aero.sections[key].Admittance = lambda fred: np.full((4, 3), davenport(fred))
240
+ model.aero.sections[key].admittance = lambda fred: np.full((4, 3), davenport(fred))
241
241
 
242
242
  #model.run_eig(w_initial=model.modal_dry.omega_n.tolist(), freq_kind=True, itmax=100) # alters integration
243
243
 
@@ -245,7 +245,7 @@ def test_RMS_response(Vbuff, RMS_horz_exp1, RMS_vert_exp1, RMS_tors_exp1, RMS_ho
245
245
  model.run_freqsim(omega,
246
246
  include_selfexcited=['aero'],
247
247
  include_action=['aero'],
248
- print_progress=False, merge_aero_sections=True)
248
+ print_progress=False)
249
249
  # RMS responses
250
250
  stds = model.get_result_std(key = 'full')
251
251
  # global dofs
wawi/__init__.py CHANGED
@@ -1,7 +1,9 @@
1
- __version__ = "0.0.9"
1
+ '''
2
+ .. include:: ./../README.md
3
+ '''
4
+ __pdoc__ = {'wawi.ext.abq': False}
2
5
 
3
- __pdoc__ = dict()
4
- __pdoc__['wawi.abq'] = False
6
+ __version__ = "0.0.12"
5
7
 
6
8
  # Other packages
7
9
  import numpy as np
wawi/io.py CHANGED
@@ -336,7 +336,7 @@ def load_model(model_path, save_if_nonexistent=False, sort_nodes_by_x=True):
336
336
 
337
337
  def import_wadam_hydro_transfer(wadam_file):
338
338
  '''
339
- Import WADAM output file.
339
+ Import WADAM LIS output file.
340
340
 
341
341
  Parameters
342
342
  -----------
wawi/modal.py CHANGED
@@ -192,7 +192,7 @@ def iteig(K, C, M, omega=None, omega_ref=0, input_functions=True, itmax=None, to
192
192
  q[:, m] = phi[:,0]
193
193
 
194
194
  if print_progress:
195
- pp(m+2,2*ndofs, sym='>', postfix=' finished with iterative modal analysis.')
195
+ pp(m+2,2*ndofs+1, sym='>', postfix=' finished with iterative modal analysis.')
196
196
 
197
197
  if print_progress:
198
198
  print(' ')
@@ -323,7 +323,7 @@ def iteig_freq(K, C, M, omega=None, itmax=15, reference_omega=0, input_functions
323
323
  q[:, m] = qi[:, m]
324
324
 
325
325
  if print_progress:
326
- pp(m+2,2*ndofs, sym='>', postfix=' finished with iterative modal analysis.')
326
+ pp(m+2 ,2*ndofs+1, sym='>', postfix=' finished with iterative modal analysis.')
327
327
 
328
328
  if print_progress:
329
329
  print(' ')
wawi/model/_model.py CHANGED
@@ -16,6 +16,8 @@ from wawi.structural import freqsim
16
16
  from wawi.tools import print_progress as pp
17
17
  from wawi.wave import stochastic_linearize, waveaction_fft, harmonic_linearize
18
18
  from wawi.wind import windaction, windaction_static
19
+ # from wawi.io import import_folder
20
+
19
21
  import dill
20
22
 
21
23
 
@@ -266,6 +268,17 @@ class Model:
266
268
 
267
269
  self.Cquad_lin = 0.0
268
270
 
271
+ # Not used due to circular referencing.
272
+ # @staticmethod
273
+ # def from_folder(*args, **kwargs):
274
+ # '''
275
+ # Alternative constructor. Passes all inputs to `wawi.io.import_folder`.
276
+ # '''
277
+
278
+ # model = import_folder(*args, **kwargs)
279
+
280
+ # return model
281
+
269
282
 
270
283
  @staticmethod #alternative constructor
271
284
  def from_wwi(path):
@@ -568,7 +581,7 @@ class Model:
568
581
  pl.add_point_labels(np.vstack([wind_origin]), [f'U={self.aero.windstate.U0:.2f} m/s from heading {self.aero.windstate.direction:.1f} deg (CW)'])
569
582
 
570
583
  # Plot wave arrow
571
- if plot_wave_direction and self.hydro.seastate is not None:
584
+ if plot_wave_direction and self.hydro is not None and self.hydro.seastate is not None:
572
585
  if self.hydro.seastate.homogeneous:
573
586
  if wave_origin=='center':
574
587
  wave_origin = origin*1
@@ -673,6 +686,8 @@ class Model:
673
686
  return phi_tot
674
687
 
675
688
  def get_result_psd(self, key='hydro', index=None, convert_to=None, modes=None):
689
+ # index: applied after transformation to requested csys (convert_to)
690
+
676
691
  ix, ix_3d = self.get_mode_ix(modes)
677
692
 
678
693
  if key is not None:
@@ -1321,4 +1336,22 @@ class Model:
1321
1336
  if opt == 0:
1322
1337
  return frf
1323
1338
  else:
1324
- return imp
1339
+ return imp
1340
+
1341
+ def get_node_ix(self, nodelabel):
1342
+ ix = np.where(self.eldef.get_node_labels()==nodelabel)[0]
1343
+ if len(ix)>0:
1344
+ ix = int(ix[0])
1345
+ else:
1346
+ ix = None
1347
+
1348
+ return ix
1349
+
1350
+ def get_node_ixs(self, nodelabels):
1351
+ return [self.get_node_ix(nodelabel) for nodelabel in nodelabels]
1352
+
1353
+ def get_aerosection_phi_and_x(self, key):
1354
+ ixs = self.aero.phi_ixs[key]
1355
+ x = np.vstack([node.coordinates for node in self.aero.eldef[key].nodes])
1356
+
1357
+ return ixs, x
wawi/time_domain.py CHANGED
@@ -52,6 +52,51 @@ def simulate_mdof(S, omega, fs=None, tmax=None, reg_factor=None, zero_limit=1e-1
52
52
  phase_angles=None, return_phase_angles=False, interpolation_kind='linear',
53
53
  component_scaling=None, print_status=False):
54
54
 
55
+ '''
56
+ Simulate time series from given cross-spectral density matrix.
57
+
58
+ Parameters
59
+ ----------------
60
+ S : float
61
+ cross-spectral density matrix (Ndofs x Ndofs x Nfreqs) as complex numpy array
62
+ omega : float
63
+ numpy array defining frequencies in rad/s
64
+ fs : float, optional
65
+ sampling frequency in Hz; if not given, the value is defined as two times the maximum of `omega`
66
+ tmax : float, optional
67
+ duration of realization in seconds
68
+ reg_factor : float, optional
69
+ to help the Cholesky decomposition to achieve a numerical solution,
70
+ a diagonal matrix with the norm of all frequency components of the matrix S scaled by the given factor
71
+ - if no value is given (--> None imposed), no regularization is conducted;
72
+ used as input to function `spectrum_to_process` which decomposes the spectral density
73
+ zero_limit : float, optional
74
+ frequency components where the norm of S is below this limit is set to zero
75
+ if no value is given (--> None imposed), no zero limit is applied;
76
+ used as input to function `spectrum_to_process` which decomposes the spectral density
77
+ phase_angles : float, optional
78
+ if previously conducted simulations are to be recreated, they can by inputting the phase angles
79
+ (to get the phase angles from simulation, see `return_phase_angles` input parameter)
80
+ return_phase_angles : bool, default=False
81
+ whether or not to return phase angle enabling recreation of the simulation
82
+ interpolation_kind : optional, default='linear'
83
+ interpolation type used for interpolation (to ensure that we get defined duration and sampling) prior to ifft
84
+ component_scaling : float, optional
85
+ values to use for scaling of components prior to decomposition (and thereafter rescale afterwards);
86
+ can help if some components are much smaller than others; size should match number of DOFs in S
87
+ print_status : False, optional
88
+ whether or not to print status messages
89
+
90
+ Returns
91
+ ----------------
92
+ p : float
93
+ time history
94
+ t : float
95
+ numpy array with time axis values corresponding to `p`
96
+ alpha : float
97
+ phase angles, only returned if `return_phase_angles` is True
98
+ '''
99
+
55
100
  if omega[0] !=0:
56
101
  omega = np.insert(omega, 0, 0)
57
102
  S = np.dstack([0*S[:,:,0], S])
wawi/wind.py CHANGED
@@ -6,7 +6,7 @@ from scipy.special import jv as besselj, yv as bessely
6
6
  from .general import rodrot, blkdiag
7
7
  from .plot import plot_ads
8
8
 
9
- conv_text='''
9
+ conv_text = r'''
10
10
  -----------------------------------------------------
11
11
  | |
12
12
  | ~ ~ ~~~ ~ ~~ ~ /^^^^^^^^^^^^\ 88ooo... . . . |
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: wawi
3
- Version: 0.0.9
3
+ Version: 0.0.12
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
@@ -43,6 +43,7 @@ Requires-Dist: trame
43
43
  Requires-Dist: ipywidgets
44
44
  Requires-Dist: pyvistaqt
45
45
  Requires-Dist: beefpy
46
+ Dynamic: license-file
46
47
 
47
48
  ![WAWI logo](https://raw.githubusercontent.com/knutankv/wawi/main/wawi-logo-animated.svg)
48
49
  =======================
@@ -133,6 +134,13 @@ Examples
133
134
  =======================
134
135
  Examples are provided as Jupyter Notebooks in the [examples folder](https://github.com/knutankv/wawi/tree/main/examples).
135
136
 
137
+ The examples are structured in the following folders based on their topic:
138
+
139
+ * **0 Model generation and setup** - *Describing how a model is defined, either using input files together with the function `wawi.io.import_folder` or using the classes available in the `wawi.model` module directly (in the latter case, the open source Python library BEEF is used to create the required parameters directly in the notebook).*
140
+ * **1 Modal analysis** - *Describing how to set up iterative (and incremental) modal analyses to represent the contributions from aerodynamics and hydrodynamices. Also, an example showing how to set up a multi-modal flutter analysis is given.*
141
+ * **2 Response prediction** - *Describing how to conduct response analyses using WAWI. This includes assigning wind states, sea states, and the necessary commands to run a frequency domain analysis. Furthermore, more advanced topics such as wave-current interaction, inhomogeneous waves and stochastic linearization to represent quadratic drag damping are given in separate examples. Three models are considered: (i) a simple curved floating bridge, (ii) a single beam, (iii) a suspension bridge.*
142
+ * **3 Software interfacing** - *Describing how to export necessary data from other software (limited to Abaqus for now) to construct a WAWI model.*
143
+
136
144
  References
137
145
  =======================
138
146
 
@@ -1,28 +1,27 @@
1
- examples/3 Software interfacing/Abaqus model export/bergsoysund-export.py,sha256=-1jrDNmevOcB1IV0iLOiW0z-QiNkOv8GkGk-7K8CcK0,2606
2
- examples/3 Software interfacing/Abaqus model export/test.py,sha256=kAmol3XZQ2jkO2qujEQrqx38Q24LbzrYZzqE5ng5-E8,2188
3
- tests/test_IABSE_step11a.py,sha256=guRsaP9gpERvSp0Ui3hO-WH764BcIe6Qx8vC4QVTAoU,8013
4
- tests/test_IABSE_step11c.py,sha256=U_NcL6BAmnQG7MSjkr8KYk9hH8ZPdZgg17pM9ugUBzo,10412
5
- tests/test_IABSE_step2a.py,sha256=L5AyTOJZ_sPmcmW_4h-sQfRwvVW71LZkXc1yz33DABM,10203
1
+ examples/3 Software interfacing/Abaqus model export/bergsoysund-export.py,sha256=3HSV009z5oqIUgM6B7xucUpGeh2f8SzC9FSiyP0zd7A,2760
2
+ examples/3 Software interfacing/Abaqus model export/hardanger-export.py,sha256=YiqS-TxnkydwVHE7k-57nP6CDsxqSXgWR3f8UytAubY,1603
3
+ tests/test_IABSE_step11a.py,sha256=zTWOxR78F0PNhNqiqodEcL65vdJXyMP78nkJumhy-RA,7915
4
+ tests/test_IABSE_step11c.py,sha256=TfxPlP70dhujKlSYbA-Gj4U-EJmYZ3jt6yjvX9wSXcA,10337
5
+ tests/test_IABSE_step2a.py,sha256=9pAd1em2IEY4k5N-jAigV3VGup0QsbUxnwSiziuMbUg,10134
6
6
  tests/test_wind.py,sha256=r4rx6f8Tn-u4fn4gGPBMrL_JJQ2SVHGQiQ9sQuMQCPo,1707
7
- wawi/__init__.py,sha256=nOz20Bt2hcYkKQG7fG0ogBRbLfEZbIgvU1iZjjjHNZ4,158
7
+ wawi/__init__.py,sha256=7vUvWFZzW67YG3yHPiBO_bsphhLLgEF4N7wdUkJeEq8,183
8
8
  wawi/fe.py,sha256=22QKI1GlfsG7o_TpFXaKJfzmbO2_2zdIMaoJmaIZdmY,4001
9
9
  wawi/general.py,sha256=xHRoDkcchrL6Y7pTUqGsjBHh8YBLvX9dYcNXXCjQap8,13787
10
10
  wawi/identification.py,sha256=bVB6EVRR6J39OO9ckuzNJ6f0FwIo4cLqfYgrsIN89TE,1748
11
- wawi/io.py,sha256=NrziwlebaZUEdu8nWKNXKExHNZZKMzJ0gSHciBTJ4As,25323
12
- wawi/modal.py,sha256=WjNGFsk0C3tYRy18Q9WNRCatmGJtq1JSv0WrkGV02Eo,20247
11
+ wawi/io.py,sha256=cr8XLF7bwpTCxpZ84YjOyWjc5uuu-JjGv8vY9UKH-HI,25327
12
+ wawi/modal.py,sha256=L1Rs_YVEADOmsQL-hJ43eb8Nt5VpYuB1VHOjYK2O9X0,20252
13
13
  wawi/plot.py,sha256=jllJcjZxTBqjzBoT4k9jLXVUnie8oqNr8371IJvCd3c,19791
14
14
  wawi/prob.py,sha256=0nCdKdwkNf4M6sHyCZuYlt06gD0NmqRNfl4KesgySWA,215
15
15
  wawi/random.py,sha256=MHPpyTlRJSJFkCmeTAmw4Q5K1BPoFVb0Nxg0jDhkuIM,871
16
16
  wawi/signal.py,sha256=9HJs7VUhXOccuYPo12A0IUVoBIAJ2e_9F3rL-q3JuP4,1179
17
17
  wawi/structural.py,sha256=t25ohH4uBbzUJ7Hqn_kUfYhxcikZkRp8da-9dn7aEbw,8341
18
- wawi/time_domain.py,sha256=Oe-jviwDtBgpSmA7ZVmKEqQ5tdvsekXwOakYO1qUsN4,3841
18
+ wawi/time_domain.py,sha256=q8-H2xceP-2BmtOfbRQqYhD1JSb0z7jGq-dL_MzAX40,6122
19
19
  wawi/tools.py,sha256=-hFBvf0qK4AMn2MQRhrOitDMMMKm2QuRkVfbPBefEkQ,332
20
20
  wawi/wave.py,sha256=hhKg3KhKMBhOoCI7g8PFOGUbYgVhDyGmnYdBEdJ8mkY,16064
21
- wawi/wind.py,sha256=1rUqiEdMaUrhprs87TBdX24l1uDCOINaYkBChMLYWso,38208
21
+ wawi/wind.py,sha256=VHy07IbrCJxlqR0Z5O5WRc9YE4jb-MqFbULPiXhj0NA,38211
22
22
  wawi/wind_code.py,sha256=8OKLPpqc84obNNKBoYb2NunKjcn6a3i_pAWpIFEwg4Q,223
23
23
  wawi/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  wawi/ext/abq.py,sha256=Wo-Zzb6b3lr_z7cNKTW-NdYJuVeAwZgwzlGhF_5Jym0,8905
25
- wawi/ext/abq_legacy.py,sha256=WVhoPjRAru98NxYqpKp9_G8wwfJiLO4X4xFc-CvI0j4,16494
26
25
  wawi/ext/ansys.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
26
  wawi/ext/orcaflex.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
27
  wawi/ext/sofistik.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -30,10 +29,10 @@ wawi/model/__init__.py,sha256=u6B-dugP76LBkOUVMs0KAoQ81PeRHwFL0M8MbNeAaJA,218
30
29
  wawi/model/_aero.py,sha256=tvWMjMoVi9ZVBc3NZ_s-wSofbEk1cc5jf5s-Swv2RxQ,9337
31
30
  wawi/model/_dry.py,sha256=KpmFlSinoY6DrSyc3Y0M8w1-cCC7VCFep-uzcqZsHz4,3940
32
31
  wawi/model/_hydro.py,sha256=1tUj19OgvEjItNtBxXuPHf0zWtKv_ioTrOcgl9Ov3dg,26960
33
- wawi/model/_model.py,sha256=qmQRASu3E3iRqxzAeT3wUxonuADbCxreXiERR9KHwb0,52090
32
+ wawi/model/_model.py,sha256=ynZkyoU00crTAlu7sN0CmJsn-J8vwK7BDbMCh0pb-hI,53061
34
33
  wawi/model/_screening.py,sha256=NRYkKq928z2lqMSUTpbQLls04td_9R_4dhkjU3Gv1oQ,3716
35
- wawi-0.0.9.dist-info/LICENSE,sha256=bH1aWhrNbbPLrYnVFRaoYYzcUr-figHjry-kGB7Tc54,1076
36
- wawi-0.0.9.dist-info/METADATA,sha256=zoyYWdj03UGEOq7jt7XqUgd0XdV-KmEzI99lBmNJ6cE,5197
37
- wawi-0.0.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
38
- wawi-0.0.9.dist-info/top_level.txt,sha256=Nk5G_ZwgZRCb9ZMWZdr1M3QIskX6kCnlqeMl67N3zg8,20
39
- wawi-0.0.9.dist-info/RECORD,,
34
+ wawi-0.0.12.dist-info/licenses/LICENSE,sha256=bH1aWhrNbbPLrYnVFRaoYYzcUr-figHjry-kGB7Tc54,1076
35
+ wawi-0.0.12.dist-info/METADATA,sha256=lXTUPijzmyd6QOJ2LmCPJaF7H_NWkysiOZkJkhlKqlU,6530
36
+ wawi-0.0.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
37
+ wawi-0.0.12.dist-info/top_level.txt,sha256=Nk5G_ZwgZRCb9ZMWZdr1M3QIskX6kCnlqeMl67N3zg8,20
38
+ wawi-0.0.12.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,67 +0,0 @@
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)
wawi/ext/abq_legacy.py DELETED
@@ -1,462 +0,0 @@
1
- import numpy as np
2
- import pdb
3
-
4
- from abaqus import *
5
- from abaqus import session
6
- from abaqusConstants import *
7
- import __main__
8
- import section
9
- import regionToolset
10
- import displayGroupMdbToolset as dgm
11
- import step
12
- import part
13
- import material
14
- import assembly
15
- import interaction
16
- import load
17
- import mesh
18
- import optimization
19
- import job
20
- import sketch
21
- import visualization
22
- import xyPlot
23
- import displayGroupOdbToolset as dgo
24
- import connectorBehavior
25
- import symbolicConstants
26
- import odbAccess
27
- import shutil
28
-
29
- import regionToolset
30
-
31
- import csv
32
- from copy import deepcopy
33
-
34
- import numpy as np
35
- import os
36
-
37
- from wawi.general import merge_tr_phi
38
-
39
-
40
- def export_wawi(odb_path, path):
41
- pass
42
-
43
- def get_modal_parameters(frequency_step):
44
- '''
45
- Output the modal parameters from frequency step of current output database.
46
-
47
- Parameters
48
- -------------
49
- frequency_step : str
50
- name of step containing the modal results (frequency step)
51
-
52
- Returns
53
- --------------
54
- f : float
55
- numpy array with undamped natural frequencies in Hz of all modes computed
56
- m : float
57
- numpy array with modal mass for all modes computed
58
- '''
59
-
60
- odb = get_db('odb')
61
- history_region_key = odb.steps[frequency_step].historyRegions.keys()[0]
62
-
63
- ftemp = odb.steps[frequency_step].historyRegions[history_region_key].historyOutputs['EIGFREQ'].data
64
- f = np.array([x[1] for x in ftemp])
65
-
66
- if 'GM' in odb.steps[frequency_step].historyRegions[history_region_key].historyOutputs.keys():
67
- mtemp = odb.steps[frequency_step].historyRegions[history_region_key].historyOutputs['GM'].data
68
- m = np.array([x[1] for x in mtemp])
69
- else:
70
- m = np.ones(np.shape(f)) #if no GM field is available, mass normalization is assumed used on eigenvalues
71
- return f, m
72
-
73
- def session_is_odb():
74
- """
75
- Check if current session is ODB.
76
-
77
- Returns:
78
- is_odb: boolean indicating if the session is odb or not
79
- """
80
- is_odb =(('session' in locals() or 'session' in globals()) and
81
- session.viewports['Viewport: 1'].displayedObject is not None and
82
- hasattr(session.viewports['Viewport: 1'].displayedObject, 'jobData'))
83
-
84
- return is_odb
85
-
86
- def get_db(db_type):
87
- """
88
- Return the current database (either a model or an odb object).
89
-
90
- If a model db is wanted and no model is active, the model in the mdb is selected regardless,
91
- as long as there is only one model open in the mdb. If no database fits the requirements, None is returned.
92
-
93
- Args:
94
- db_type: 'odb' or 'model'
95
- Returns:
96
- db: database
97
-
98
- NTNU / Knut Andreas Kvaale, 2018
99
- """
100
- if db_type is 'model' or db_type is 'mdb':
101
- if not session_is_odb():
102
- db = mdb.models[session.viewports['Viewport: 1'].displayedObject.modelName]
103
- elif len(mdb.models.keys()) is 1:
104
- db = mdb.models[mdb.models.keys()[0]]
105
- elif len(mdb.models.keys()) > 1:
106
- raise AttributeError('No model is not active, and more than one model is available in model database. Impossible to select correct.')
107
- else:
108
- db = None
109
- else:
110
- if session_is_odb():
111
- db = session.viewports[session.currentViewportName].displayedObject
112
- else:
113
- db = None
114
-
115
- return db
116
-
117
-
118
- def modeshapes_from_region(regionobjs, frequency_step, field_outputs):
119
- """
120
- Get modes (shape, frequency and modal mass) from "Frequency step" (eigenvalue analysis) in active Abaqus ODB.
121
-
122
- """
123
- odb = get_db('odb')
124
-
125
- if odb.steps[frequency_step].domain != MODAL: #MODAL is a variable in abaqusConstants
126
- raise TypeError('Type of input step is not modal!')
127
-
128
- Nmodes = len(odb.steps[frequency_step].frames)-1
129
- phi = [None]*len(field_outputs)
130
-
131
- for iout, field_output in enumerate(field_outputs):
132
- Ndofs, point_ranges, dof_ranges = count_region(regionobjs, field_output, odb.steps[frequency_step].frames[0])
133
- phio = np.zeros([np.sum(Ndofs), Nmodes])
134
- foobj0 = odb.steps[frequency_step].frames[0].fieldOutputs[field_output]
135
-
136
- for ix, regionobj in enumerate(regionobjs):
137
- current_dof_range = np.arange(dof_ranges[ix], dof_ranges[ix+1])
138
-
139
- for mode in range(0, Nmodes):
140
- foobj = odb.steps[frequency_step].frames[mode+1].fieldOutputs[field_output]
141
- phio[:, mode] = np.reshape((np.array([v.data for v in foobj.getSubset(region=regionobj).values])), [np.sum(Ndofs)])
142
-
143
- phi[iout] = phio
144
-
145
- return phi
146
-
147
- def str2region(instance_name, setnames, region_type, db_type, *args):
148
- """
149
- Construct a region object from a string defining the set name or a region object.
150
-
151
- Args:
152
- instance_name: string defining the set name (either node or element set) or a region object
153
- setnames: name of set asked for
154
- region_type: type of set ('elements' or 'nodes')
155
- db_type: 'odb' or 'model'
156
- Optional args:
157
- db: database object, either mdb.model[...] or session.openOdb(...) - will get from viewport 1 if not given
158
- Returns:
159
- regionobjs: region objects
160
-
161
- """
162
-
163
- is_assembly = instance_name is None
164
-
165
- set_type = settype(region_type, db_type)
166
- standard_sets = {'nodes': [' ALL NODES'], 'elements': [' ALL ELEMENTS']}
167
-
168
- if setnames is None:
169
- setnames = standard_sets[region_type]
170
-
171
- if len(args)==1: # a db has been input
172
- db = args[0]
173
- isodb = hasattr(db,'jobData') #check if the input db is reffering to result/odb or model
174
-
175
- else:
176
- db = get_db(db_type)
177
-
178
- if db is None:
179
- raise TypeError('The database is empty. Please input a database object, or input parameters that matches one. Remember that odbs have to be active to get the db automatically!')
180
-
181
- if is_assembly: # Instance name is given
182
- regroot = db.rootAssembly
183
- else:
184
- regroot = db.rootAssembly.instances[instance_name]
185
-
186
- regionobjs = [None] * np.size(setnames)
187
-
188
- for ix,thisname in enumerate(setnames):
189
- regionobjs[ix] = getattr(regroot, set_type)[thisname]
190
-
191
- return regionobjs
192
-
193
-
194
- def settype(region_type, db_type):
195
- """
196
- Define the string used to get set based on region type and database type.
197
-
198
- Args:
199
- region_type: 'element' or 'node'
200
- db_type: 'odb' or 'mdb'
201
- Returns:
202
- set_string: string used to obtain set data from database object (odb or mdb)
203
-
204
- """
205
- if db_type is 'odb':
206
- if 'element' in region_type.lower():
207
- set_string = 'elementSets'
208
- elif 'node' in region_type.lower():
209
- set_string = 'nodeSets'
210
- else:
211
- raise TypeError('Wrong input!')
212
- elif db_type == 'mdb' or db_type == 'model':
213
- set_string = 'sets'
214
-
215
- return set_string
216
-
217
- def count_region(regionobjs, field_output, frame):
218
- """
219
- Count the number of DOFs and points in the specified region objects for given field output and frame object.
220
-
221
- Args:
222
- regionobjs: list of region objects to query
223
- field_output: string specifying field output
224
- frame: frame object (from where fieldOutputs field is accessible)
225
- Returns:
226
- Ndofs: number of DOFs for each region (list)
227
- point_ranges: point/node ranges for each region (list of lists)
228
- dof_ranges: dof ranges for each region (list of lists)
229
- """
230
- odb = get_db('odb')
231
-
232
- Npoints = [len(frame.fieldOutputs[field_output].getSubset(region=regionobj).values) for regionobj in regionobjs]
233
- Ndofs = np.dot(Npoints, len(frame.fieldOutputs[field_output].componentLabels))
234
-
235
- dof_ranges = np.cumsum(np.append([0], Ndofs))
236
- point_ranges = np.cumsum(np.append([0], Npoints))
237
-
238
- return Ndofs, point_ranges, dof_ranges
239
-
240
-
241
- def wind_set_data(set_strings, frequency_step, instance, db_type, field_outputs, mode_type='nodes', use_node_region_acronym=False):
242
- # use_node_region_acronym: if True, a node set with identical name as the element set given in set_strings is picked and the nodes assumed to correspond to the element. If not the case, the element set is used to establish the nodes (and thus phi)
243
- wind_element_regions = str2region(instance, set_strings, 'elements', db_type) # index 0 is girder, index 1 is columns
244
-
245
- if use_node_region_acronym:
246
- wind_node_regions = str2region(instance, set_strings, 'nodes', db_type)
247
-
248
- element_labels = [None]*len(set_strings)
249
- element_node_indices = [None]*len(set_strings)
250
- node_labels = [None]*len(set_strings)
251
- node_coordinates = [None]*len(set_strings)
252
- phi_ae = [None]*len(set_strings)
253
-
254
- for set_ix, set_string in enumerate(set_strings):
255
- element_labels[set_ix], element_node_indices[set_ix], nl, nc = region2elnodes_legacy(wind_element_regions[set_ix])
256
- if use_node_region_acronym:
257
- nl, nc = region2nodes(wind_node_regions[set_ix])
258
-
259
- node_labels[set_ix] = nl
260
- node_coordinates[set_ix] = nc
261
-
262
- # Establish modal transformation matrix, phi
263
- if mode_type=='nodes':
264
- for set_ix, set_string in enumerate(set_strings):
265
- phi_ae_temp = modeshapes_from_nodelist(node_labels[set_ix], frequency_step, field_outputs)
266
- phi_ae[set_ix] = merge_tr_phi(phi_ae_temp[0][0], phi_ae_temp[0][1])
267
- elif mode_type=='elements':
268
- for set_ix, set_string in enumerate(set_strings):
269
- phi_ae_temp, integration_points = modeshapes_from_elementlist(element_labels[set_ix], frequency_step, field_outputs)
270
- phi_ae[set_ix] = merge_tr_phi(phi_ae_temp[0], phi_ae_temp[1])
271
-
272
- return element_labels, element_node_indices, node_labels, node_coordinates, phi_ae
273
-
274
-
275
- def region2elnodes_legacy(regionobjs, avoid_central_nodes=True):
276
- """
277
- Give node labels (indices) for each node in specified element set.
278
-
279
- Args:
280
- regionobjs: region objects to query for node labels
281
-
282
- Returns:
283
- element_labels: the labels (indices) of the elements in list
284
- element_node_indices: the labels (indices) of the ndoes in each element; list of lists
285
- node_labels: all the nodes labels (indices) in a flattened list
286
- node_coordinates: node coordinates for each element (list of lists)
287
-
288
- """
289
-
290
- objstr = regionobjs.__repr__()
291
- instance_name = objstr.split(".instances['")[1].split("'].")[0]
292
-
293
- if '.odb' in objstr:
294
- db = get_db('odb')
295
- dbtype = 'odb'
296
- else:
297
- db = get_db('mdb')
298
- dbtype = 'mdb'
299
-
300
- # Get the elements object root
301
- if len(np.shape(regionobjs.elements))>1:
302
- elements = regionobjs.elements[0]
303
- else:
304
- elements = regionobjs.elements
305
-
306
- # Get all element labels and corresponding connectivity (node labels)
307
- element_labels = np.array([element.label for element in elements])
308
-
309
- # Instance object
310
- instance = db.rootAssembly.instances[instance_name]
311
-
312
- # Full arrays labels and coordinates
313
- all_node_labels = np.array([node.label for node in instance.nodes]).flatten([-1])
314
- all_node_coords = np.array([node.coordinates for node in instance.nodes])
315
-
316
- # Nodes belonging to all the elements
317
- if dbtype is 'odb':
318
- element_node_labels = [element.connectivity for element in elements]
319
- else:
320
- element_node_labels = [[all_node_labels[ix] for ix in element.connectivity] for element in elements]
321
-
322
- if avoid_central_nodes:
323
- element_node_labels = [[node_lb[0], node_lb[-1]] for node_lb in element_node_labels]
324
-
325
- node_labels = np.unique(np.array(element_node_labels).flatten())
326
-
327
- nodeixs = np.array([np.where(all_node_labels==node)[0] for node in node_labels]).flatten()
328
- node_coordinates = all_node_coords[nodeixs, :]
329
- element_node_indices = np.array([np.array([np.where(node_labels==node_label) for node_label in node_labels_for_element]).flatten() for node_labels_for_element in element_node_labels])
330
-
331
- return element_labels, element_node_indices, node_labels, node_coordinates
332
-
333
-
334
- def region2nodes(regionobj, sortfun=None):
335
- """
336
- Give node labels (indices) of nodes in specified node set(s).
337
-
338
- Args:
339
- regionobj: region object to query for node labels
340
-
341
- Optional args:
342
- sortfun: function with three inputs (1: x, 2: y, 3:z) to sort nodes by
343
- examples: sortfun = lambda x, y, z: -np.arctan2(y,x)
344
- sortfun = lambda x, y, z: x
345
-
346
- Returns:
347
- node_labels: list with nodelabels
348
-
349
- NTNU / Knut Andreas Kvaale, 2018
350
- """
351
-
352
- set_name = regionobj.__repr__().split("ets[")[1].split("'")[1]
353
-
354
- if len(np.shape(regionobj.nodes))>1:
355
- nodes = regionobj.nodes[0]
356
- else:
357
- nodes = regionobj.nodes
358
-
359
- node_labels = np.array([node.label for node in nodes])
360
- node_coordinates = np.array([node.coordinates for node in nodes])
361
-
362
- if sortfun != None:
363
- vals = sortfun(x=node_coordinates[:,0], y=node_coordinates[:,1], z=node_coordinates[:,2])
364
- sort_ix = np.argsort(vals)
365
- node_labels = node_labels[:, sort_ix]
366
- node_coordinates = node_coordinates[sort_ix, :]
367
-
368
- return node_labels, node_coordinates
369
-
370
- def modeshapes_from_nodelist(node_labels, frequency_step, field_outputs):
371
- """
372
- Get mode shapes from "Frequency step" (eigenvalue analysis) in active Abaqus ODB.
373
-
374
- Args:
375
- node_labels:
376
- frequency_step:
377
- field_outputs:
378
- Returns:
379
- phi: mode shape transformation matrix, ordered as NumPy matrices in list for each specified outputs
380
-
381
- """
382
- odb = get_db('odb')
383
-
384
- if odb.steps[frequency_step].domain != MODAL: #MODAL is a variable in abaqusConstants
385
- raise TypeError('Type of input step is not modal!')
386
-
387
- Nnodes = len(node_labels)
388
- Nmodes = len(odb.steps[frequency_step].frames) - 1
389
- phi = [None]*len(field_outputs)
390
- basedisp = [None]*len(field_outputs)
391
-
392
- for iout, field_output in enumerate(field_outputs):
393
- foobj0 = odb.steps[frequency_step].frames[0].fieldOutputs[field_output]
394
-
395
- Ndofs = len(foobj0.values[0].data)
396
- phio = np.zeros([Ndofs*Nnodes, Nmodes])
397
-
398
- # Get correct data indices to get correct order (as given in node_labels)
399
- all_nodes = [value.nodeLabel for value in foobj0.values]
400
- data_indices = [None]*Nnodes
401
-
402
- for ix, node in enumerate(node_labels):
403
- data_indices[ix] = all_nodes.index(node)
404
-
405
- basedisp[iout] = np.array([foobj0.values[data_ix].data for data_ix in data_indices]).flatten()
406
-
407
- for mode in range(0, Nmodes):
408
- foobj = odb.steps[frequency_step].frames[mode+1].fieldOutputs[field_output]
409
- phio[:, mode] = np.array([foobj.values[data_ix].data for data_ix in data_indices]).flatten()
410
-
411
- phi[iout] = phio
412
-
413
- return phi, basedisp
414
-
415
-
416
- def modeshapes_from_elementlist(element_labels, frequency_step, field_outputs):
417
- """
418
- Get mode shape from "Frequency step" (eigenvalue analysis) in active Abaqus ODB.
419
-
420
- Args:
421
- node_labels:
422
- frequency_step:
423
- field_outputs:
424
- Returns:
425
- phi: mode shape transformation matrix, ordered as NumPy matrices in list for each specified outputs
426
-
427
- """
428
- odb = get_db('odb')
429
-
430
- if odb.steps[frequency_step].domain != MODAL: #MODAL is a variable in abaqusConstants
431
- raise TypeError('Type of input step is not modal!')
432
-
433
-
434
- Nmodes = len(odb.steps[frequency_step].frames) - 1
435
- phi = [None]*len(field_outputs)
436
- integration_points = [None]*len(field_outputs)
437
-
438
- for iout, field_output in enumerate(field_outputs):
439
- foobj0 = odb.steps[frequency_step].frames[0].fieldOutputs[field_output]
440
- Ndofs = len(foobj0.values[0].data)
441
-
442
- # Get correct data indices to get correct order (as given in node_labels)
443
- all_elements = [value.elementLabel for value in foobj0.values]
444
- all_integration_points = [value.integrationPoint for value in foobj0.values]
445
-
446
- Nintpoints = len(element_labels) # number of integration points (same element label might appear multiple times if multiple integration points in element)
447
- phio = np.zeros([Ndofs*Nintpoints, Nmodes])
448
-
449
- data_indices = [None]*Nintpoints
450
-
451
- for ix, element in enumerate(element_labels):
452
- data_indices[ix] = all_elements.index(element)
453
-
454
- for mode in range(0, Nmodes):
455
- foobj = odb.steps[frequency_step].frames[mode+1].fieldOutputs[field_output]
456
- phio[:, mode] = np.array([foobj.values[data_ix].data for data_ix in data_indices]).flatten()
457
-
458
- integration_points[iout] = [all_integration_points[ix] for ix in data_indices]
459
- phi[iout] = phio
460
-
461
-
462
- return phi, integration_points