wawi 0.0.11__py3-none-any.whl → 0.0.13__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.
- examples/3 Software interfacing/Abaqus model export/bergsoysund-export.py +12 -8
- examples/3 Software interfacing/Abaqus model export/hardanger-export.py +47 -0
- tests/test_IABSE_step11a.py +12 -11
- tests/test_IABSE_step11c.py +9 -9
- tests/test_IABSE_step2a.py +8 -8
- wawi/__init__.py +1 -1
- wawi/io.py +1 -1
- wawi/modal.py +3 -2
- wawi/model/_hydro.py +13 -10
- wawi/model/_model.py +35 -8
- wawi/wave.py +0 -1
- {wawi-0.0.11.dist-info → wawi-0.0.13.dist-info}/METADATA +7 -2
- {wawi-0.0.11.dist-info → wawi-0.0.13.dist-info}/RECORD +16 -16
- {wawi-0.0.11.dist-info → wawi-0.0.13.dist-info}/WHEEL +1 -1
- examples/3 Software interfacing/Abaqus model export/test.py +0 -67
- {wawi-0.0.11.dist-info → wawi-0.0.13.dist-info}/licenses/LICENSE +0 -0
- {wawi-0.0.11.dist-info → wawi-0.0.13.dist-info}/top_level.txt +0 -0
@@ -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
|
-
|
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 =
|
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)
|
tests/test_IABSE_step11a.py
CHANGED
@@ -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
|
7
|
-
import sys
|
8
|
-
import os
|
9
|
-
sys.path.insert(0,
|
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'].
|
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
|
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'].
|
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,
|
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'].
|
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
|
213
|
+
print_progress=False)
|
213
214
|
|
214
215
|
stds = model.get_result_std(key = 'full')
|
215
216
|
|
tests/test_IABSE_step11c.py
CHANGED
@@ -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'].
|
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
|
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'].
|
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
|
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'].
|
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
|
274
|
+
print_progress=False)
|
275
275
|
|
276
276
|
# RMS responses
|
277
277
|
stds = model.get_result_std(key = 'full')
|
tests/test_IABSE_step2a.py
CHANGED
@@ -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].
|
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,
|
194
|
-
|
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].
|
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
|
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
wawi/io.py
CHANGED
@@ -39,7 +39,7 @@ def import_folder(model_folder, pontoon_stl='pontoon.stl', aero_sections='aero_s
|
|
39
39
|
sort_nodes_by_x : True, optional
|
40
40
|
whether or not to sort the nodes of eldef by their x-coordinate
|
41
41
|
interpolation_kind : {'quadratic', 'linear', ...}
|
42
|
-
interpolation kind used for hydrodynamic transfer function
|
42
|
+
interpolation kind used for hydrodynamic transfer function and hydrodynamic system matrices
|
43
43
|
|
44
44
|
Returns
|
45
45
|
---------------
|
wawi/modal.py
CHANGED
@@ -155,6 +155,7 @@ def iteig(K, C, M, omega=None, omega_ref=0, input_functions=True, itmax=None, to
|
|
155
155
|
lambdai = lambdai[m]
|
156
156
|
|
157
157
|
w = abs(np.imag(lambdai))
|
158
|
+
|
158
159
|
if mean_w:
|
159
160
|
w = (wprev+w)/2
|
160
161
|
|
@@ -192,7 +193,7 @@ def iteig(K, C, M, omega=None, omega_ref=0, input_functions=True, itmax=None, to
|
|
192
193
|
q[:, m] = phi[:,0]
|
193
194
|
|
194
195
|
if print_progress:
|
195
|
-
pp(m+2,2*ndofs, sym='>', postfix=' finished with iterative modal analysis.')
|
196
|
+
pp(m+2,2*ndofs+1, sym='>', postfix=' finished with iterative modal analysis.')
|
196
197
|
|
197
198
|
if print_progress:
|
198
199
|
print(' ')
|
@@ -323,7 +324,7 @@ def iteig_freq(K, C, M, omega=None, itmax=15, reference_omega=0, input_functions
|
|
323
324
|
q[:, m] = qi[:, m]
|
324
325
|
|
325
326
|
if print_progress:
|
326
|
-
pp(m+2,2*ndofs, sym='>', postfix=' finished with iterative modal analysis.')
|
327
|
+
pp(m+2 ,2*ndofs+1, sym='>', postfix=' finished with iterative modal analysis.')
|
327
328
|
|
328
329
|
if print_progress:
|
329
330
|
print(' ')
|
wawi/model/_hydro.py
CHANGED
@@ -480,7 +480,7 @@ SEASTATE CLASS
|
|
480
480
|
'''
|
481
481
|
|
482
482
|
class Seastate:
|
483
|
-
def __init__(self, Tp, Hs, gamma, theta0, s, depth=None, origin=None, ranges=None,
|
483
|
+
def __init__(self, Tp, Hs, gamma, theta0, s=np.inf, depth=None, origin=None, ranges=None,
|
484
484
|
options={}, pontoon_options={}, name=None, plot_label=None, centered_dirdist=True,
|
485
485
|
U=None, thetaU=None, use_robust_D=True, angle_unit='deg'):
|
486
486
|
|
@@ -529,7 +529,7 @@ class Seastate:
|
|
529
529
|
|
530
530
|
self.x0 = self.origin[0]
|
531
531
|
self.y0 = self.origin[1]
|
532
|
-
self.options = {'keep_coherence': True}
|
532
|
+
self.options = {'keep_coherence': True} #default options
|
533
533
|
self.options.update(**options)
|
534
534
|
|
535
535
|
self.pontoon_options = {'current_affects_Q': True, 'current_affects_k': True}
|
@@ -616,9 +616,12 @@ thetaU (current)={self.thetaU*180/np.pi:.1f}deg
|
|
616
616
|
if return_phases:
|
617
617
|
eta, t, phase = output
|
618
618
|
return eta, t, phase
|
619
|
-
|
619
|
+
elif time_history:
|
620
620
|
eta, t = output
|
621
621
|
return eta, t
|
622
|
+
else:
|
623
|
+
return output
|
624
|
+
|
622
625
|
|
623
626
|
|
624
627
|
@staticmethod
|
@@ -821,7 +824,7 @@ class PontoonType:
|
|
821
824
|
|
822
825
|
|
823
826
|
@classmethod
|
824
|
-
def from_numeric(cls, interpolation_kind='linear', A=None, M0=None, B=None, Kh=None,
|
827
|
+
def from_numeric(cls, interpolation_kind='linear', fill_value_added='extrapolate', A=None, M0=None, B=None, Kh=None,
|
825
828
|
omega=None, Q=None, theta=None, omegaQ=None, **kwargs):
|
826
829
|
|
827
830
|
if omegaQ is None:
|
@@ -834,12 +837,12 @@ class PontoonType:
|
|
834
837
|
A = np.zeros([M0.shape + [len(omega)]])
|
835
838
|
elif M0 is None:
|
836
839
|
M0 = A[:,:,0]*0
|
837
|
-
M = interp1d(omega, (A.T+M0.T).T, axis=2, fill_value=
|
840
|
+
M = interp1d(omega, (A.T+M0.T).T, axis=2, fill_value=fill_value_added, kind=interpolation_kind)
|
838
841
|
|
839
842
|
if B is None:
|
840
843
|
C = None
|
841
844
|
else:
|
842
|
-
C = interp1d(omega, B, axis=2, fill_value=
|
845
|
+
C = interp1d(omega, B, axis=2, fill_value=fill_value_added, kind=interpolation_kind)
|
843
846
|
|
844
847
|
if Kh is not None:
|
845
848
|
K = lambda omega: Kh
|
@@ -853,7 +856,7 @@ class PontoonType:
|
|
853
856
|
|
854
857
|
|
855
858
|
@classmethod
|
856
|
-
def from_wadam(cls, path, interpolation_kind='linear',
|
859
|
+
def from_wadam(cls, path, interpolation_kind='linear', fill_value_added='extrapolate',
|
857
860
|
include=['added mass', 'added damping', 'restoring stiffness', 'inertia'], **kwargs):
|
858
861
|
|
859
862
|
from wawi.io import import_wadam_mat, import_wadam_hydro_transfer
|
@@ -873,10 +876,10 @@ class PontoonType:
|
|
873
876
|
if 'inertia' not in include:
|
874
877
|
M0 = M0*0
|
875
878
|
|
876
|
-
M = interp1d(omega, (A.T+M0.T).T, axis=2, fill_value=
|
877
|
-
C = interp1d(omega, B, axis=2, fill_value=
|
879
|
+
M = interp1d(omega, (A.T+M0.T).T, axis=2, fill_value=fill_value_added, kind=interpolation_kind)
|
880
|
+
C = interp1d(omega, B, axis=2, fill_value=fill_value_added, kind=interpolation_kind)
|
878
881
|
K = lambda omega: Kh
|
879
882
|
|
880
|
-
Q = interp1d(omega_Q, Q, fill_value=
|
883
|
+
Q = interp1d(omega_Q, Q, fill_value=0.0, kind=interpolation_kind, axis=2)
|
881
884
|
|
882
885
|
return cls(M=M, C=C, K=K, Q=Q, original_omega=omega, theta=theta, **kwargs)
|
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
|
@@ -1030,7 +1043,7 @@ class Model:
|
|
1030
1043
|
|
1031
1044
|
|
1032
1045
|
def get_waveaction(self, omega_k, max_rel_error=0.01,
|
1033
|
-
theta_interpolation='linear', theta_int=None):
|
1046
|
+
theta_interpolation='linear', theta_int=None, transform_by_phi=True):
|
1034
1047
|
|
1035
1048
|
if theta_int is None and self.theta_int is None:
|
1036
1049
|
theta_int = self.get_theta_int(omega_k, max_rel_error=max_rel_error)
|
@@ -1056,8 +1069,11 @@ class Model:
|
|
1056
1069
|
|
1057
1070
|
if not self.hydro.seastate.options['keep_coherence']:
|
1058
1071
|
Sqq0 = block_diag(*[Sqq0[i*6:(i+1)*6, i*6:(i+1)*6] for i in range(int(Sqq0.shape[0]/6))])
|
1059
|
-
|
1060
|
-
|
1072
|
+
|
1073
|
+
if transform_by_phi:
|
1074
|
+
return self.hydro.phi.T @ Sqq0 @ self.hydro.phi
|
1075
|
+
else:
|
1076
|
+
return Sqq0
|
1061
1077
|
|
1062
1078
|
|
1063
1079
|
def evaluate_windaction(self, omega=None, aero_sections=None, print_progress=True, static=False, **kwargs):
|
@@ -1131,15 +1147,20 @@ class Model:
|
|
1131
1147
|
|
1132
1148
|
|
1133
1149
|
def evaluate_waveaction(self, omega, max_rel_error=0.01, print_progress=True, theta_int=None,
|
1134
|
-
theta_interpolation='quadratic', **kwargs):
|
1150
|
+
theta_interpolation='quadratic', transform_by_phi=True, **kwargs):
|
1135
1151
|
|
1136
1152
|
if theta_int is None:
|
1137
1153
|
theta_int = self.theta_int
|
1138
1154
|
|
1139
|
-
|
1155
|
+
if transform_by_phi:
|
1156
|
+
ndofs = self.hydro.phi.shape[1]
|
1157
|
+
else:
|
1158
|
+
ndofs = self.hydro.phi.shape[0]
|
1159
|
+
|
1140
1160
|
Sqq = np.zeros([ndofs, ndofs, len(omega)]).astype('complex')
|
1161
|
+
|
1141
1162
|
for k, omega_k in enumerate(omega):
|
1142
|
-
Sqq[:,:,k] = self.get_waveaction(omega_k, max_rel_error=max_rel_error, theta_int=theta_int,
|
1163
|
+
Sqq[:,:,k] = self.get_waveaction(omega_k, max_rel_error=max_rel_error, theta_int=theta_int, transform_by_phi=transform_by_phi,
|
1143
1164
|
theta_interpolation=theta_interpolation, **kwargs)
|
1144
1165
|
|
1145
1166
|
if print_progress:
|
@@ -1335,4 +1356,10 @@ class Model:
|
|
1335
1356
|
return ix
|
1336
1357
|
|
1337
1358
|
def get_node_ixs(self, nodelabels):
|
1338
|
-
return [self.get_node_ix(nodelabel) for nodelabel in nodelabels]
|
1359
|
+
return [self.get_node_ix(nodelabel) for nodelabel in nodelabels]
|
1360
|
+
|
1361
|
+
def get_aerosection_phi_and_x(self, key):
|
1362
|
+
ixs = self.aero.phi_ixs[key]
|
1363
|
+
x = np.vstack([node.coordinates for node in self.aero.eldef[key].nodes])
|
1364
|
+
|
1365
|
+
return ixs, x
|
wawi/wave.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: wawi
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.13
|
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
|
@@ -48,7 +48,7 @@ Dynamic: license-file
|
|
48
48
|

|
49
49
|
=======================
|
50
50
|
|
51
|
-
What is
|
51
|
+
What is WAWI?
|
52
52
|
=======================
|
53
53
|
WAWI is a Python toolbox for prediction of response of structures exposed to wind and wave excitation. The package is still under development in its alpha stage, and documentation and testing will be completed along the way.
|
54
54
|
|
@@ -68,6 +68,11 @@ pip install git+https://www.github.com/knutankv/wawi.git@main
|
|
68
68
|
```
|
69
69
|
|
70
70
|
|
71
|
+
How does WAWI work?
|
72
|
+
======================
|
73
|
+
By representing both aerodynamic and hydrodynamic motion-induced forces and excitation using a coordinate basis defined by the dry in-vacuum mode shapes of the structure, WAWI is able to versatily predict response based on input from any commercial FE software. The main structure used for response prediction is given in this figure:
|
74
|
+

|
75
|
+
|
71
76
|
Quick start
|
72
77
|
=======================
|
73
78
|
Assuming a premade WAWI-model is created and saved as `MyModel.wwi´, it can be imported as follows:
|
@@ -1,15 +1,15 @@
|
|
1
|
-
examples/3 Software interfacing/Abaqus model export/bergsoysund-export.py,sha256
|
2
|
-
examples/3 Software interfacing/Abaqus model export/
|
3
|
-
tests/test_IABSE_step11a.py,sha256=
|
4
|
-
tests/test_IABSE_step11c.py,sha256=
|
5
|
-
tests/test_IABSE_step2a.py,sha256=
|
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=
|
7
|
+
wawi/__init__.py,sha256=XwztcgUqHaXYX8ywshKc0BVsSVDStFgeENuVdN3PWuk,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=
|
12
|
-
wawi/modal.py,sha256=
|
11
|
+
wawi/io.py,sha256=3cPgyVGpZcne60-vXQZYXVj9e5m044XDeR3eMZ3BF7Y,25359
|
12
|
+
wawi/modal.py,sha256=SOmzjviDMBw4OwQAUq3EXo_FJyv6uoZg-fsE3fizXHk,20253
|
13
13
|
wawi/plot.py,sha256=jllJcjZxTBqjzBoT4k9jLXVUnie8oqNr8371IJvCd3c,19791
|
14
14
|
wawi/prob.py,sha256=0nCdKdwkNf4M6sHyCZuYlt06gD0NmqRNfl4KesgySWA,215
|
15
15
|
wawi/random.py,sha256=MHPpyTlRJSJFkCmeTAmw4Q5K1BPoFVb0Nxg0jDhkuIM,871
|
@@ -17,7 +17,7 @@ wawi/signal.py,sha256=9HJs7VUhXOccuYPo12A0IUVoBIAJ2e_9F3rL-q3JuP4,1179
|
|
17
17
|
wawi/structural.py,sha256=t25ohH4uBbzUJ7Hqn_kUfYhxcikZkRp8da-9dn7aEbw,8341
|
18
18
|
wawi/time_domain.py,sha256=q8-H2xceP-2BmtOfbRQqYhD1JSb0z7jGq-dL_MzAX40,6122
|
19
19
|
wawi/tools.py,sha256=-hFBvf0qK4AMn2MQRhrOitDMMMKm2QuRkVfbPBefEkQ,332
|
20
|
-
wawi/wave.py,sha256=
|
20
|
+
wawi/wave.py,sha256=Ye-5JnJJhWA1lcPQUvFTCRTzcY6LB_hu92VO8z2i01I,16059
|
21
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
|
@@ -28,11 +28,11 @@ wawi/ext/sofistik.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
wawi/model/__init__.py,sha256=u6B-dugP76LBkOUVMs0KAoQ81PeRHwFL0M8MbNeAaJA,218
|
29
29
|
wawi/model/_aero.py,sha256=tvWMjMoVi9ZVBc3NZ_s-wSofbEk1cc5jf5s-Swv2RxQ,9337
|
30
30
|
wawi/model/_dry.py,sha256=KpmFlSinoY6DrSyc3Y0M8w1-cCC7VCFep-uzcqZsHz4,3940
|
31
|
-
wawi/model/_hydro.py,sha256=
|
32
|
-
wawi/model/_model.py,sha256=
|
31
|
+
wawi/model/_hydro.py,sha256=7kzOqKou9RV1KoYXC-6oVw8gtnqfC-NfeohLFDiL-uI,27107
|
32
|
+
wawi/model/_model.py,sha256=m6UF3onrQFgsJUNDzuot2maAuJpqTxoP4hHCBHbDuMs,53322
|
33
33
|
wawi/model/_screening.py,sha256=NRYkKq928z2lqMSUTpbQLls04td_9R_4dhkjU3Gv1oQ,3716
|
34
|
-
wawi-0.0.
|
35
|
-
wawi-0.0.
|
36
|
-
wawi-0.0.
|
37
|
-
wawi-0.0.
|
38
|
-
wawi-0.0.
|
34
|
+
wawi-0.0.13.dist-info/licenses/LICENSE,sha256=bH1aWhrNbbPLrYnVFRaoYYzcUr-figHjry-kGB7Tc54,1076
|
35
|
+
wawi-0.0.13.dist-info/METADATA,sha256=aYeyNdzi5eAyQn3TvytkWoKeuWncwMNiWwBpLu_-MyI,6991
|
36
|
+
wawi-0.0.13.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
37
|
+
wawi-0.0.13.dist-info/top_level.txt,sha256=Nk5G_ZwgZRCb9ZMWZdr1M3QIskX6kCnlqeMl67N3zg8,20
|
38
|
+
wawi-0.0.13.dist-info/RECORD,,
|
@@ -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)
|
File without changes
|
File without changes
|