wawi 0.0.16__py3-none-any.whl → 0.0.18__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.
- wawi/__init__.py +1 -1
- wawi/fe.py +259 -12
- wawi/general.py +538 -70
- wawi/identification.py +33 -11
- wawi/io.py +206 -3
- wawi/modal.py +384 -6
- wawi/model/_model.py +1 -1
- wawi/plot.py +403 -107
- wawi/prob.py +28 -0
- wawi/random.py +218 -2
- wawi/signal.py +111 -3
- wawi/structural.py +317 -59
- wawi/time_domain.py +122 -1
- wawi/tools.py +23 -0
- wawi/wave.py +668 -123
- wawi/wind.py +775 -32
- wawi/wind_code.py +26 -0
- {wawi-0.0.16.dist-info → wawi-0.0.18.dist-info}/METADATA +42 -4
- wawi-0.0.18.dist-info/RECORD +38 -0
- {wawi-0.0.16.dist-info → wawi-0.0.18.dist-info}/WHEEL +1 -1
- wawi-0.0.16.dist-info/RECORD +0 -38
- {wawi-0.0.16.dist-info → wawi-0.0.18.dist-info}/licenses/LICENSE +0 -0
- {wawi-0.0.16.dist-info → wawi-0.0.18.dist-info}/top_level.txt +0 -0
wawi/structural.py
CHANGED
@@ -10,20 +10,31 @@ from scipy.interpolate import interp1d
|
|
10
10
|
#%% General
|
11
11
|
def dry_modalmats(f, m, rayleigh={'stiffness':0, 'mass':0}, xi0=0):
|
12
12
|
"""
|
13
|
-
Construct dry modal matrices.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
13
|
+
Construct dry modal mass, damping, and stiffness matrices.
|
14
|
+
|
15
|
+
Parameters
|
16
|
+
----------
|
17
|
+
f : array_like
|
18
|
+
Natural frequencies (Hz).
|
19
|
+
m : array_like
|
20
|
+
Modal masses (kg).
|
21
|
+
rayleigh : dict, optional
|
22
|
+
Dictionary with keys 'stiffness' and 'mass' for Rayleigh damping coefficients.
|
23
|
+
xi0 : float, optional
|
24
|
+
Constant modal critical damping ratio value (added on top of Rayleigh damping).
|
25
|
+
|
26
|
+
Returns
|
27
|
+
-------
|
28
|
+
Mdry : ndarray
|
29
|
+
Modal mass matrix.
|
30
|
+
Cdry : ndarray
|
31
|
+
Modal damping matrix.
|
32
|
+
Kdry : ndarray
|
33
|
+
Modal stiffness matrix.
|
34
|
+
|
35
|
+
Notes
|
36
|
+
-----
|
37
|
+
Docstring is generated or modified using GitHub Copilot.
|
27
38
|
"""
|
28
39
|
w = (f*2*np.pi)
|
29
40
|
k = np.multiply(w**2, m)
|
@@ -38,19 +49,26 @@ def dry_modalmats(f, m, rayleigh={'stiffness':0, 'mass':0}, xi0=0):
|
|
38
49
|
|
39
50
|
def wet_physmat(pontoon_types, angles, mat):
|
40
51
|
"""
|
41
|
-
Construct frequency dependent physical matrix.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
+
Construct frequency dependent physical matrix for pontoons.
|
53
|
+
|
54
|
+
Parameters
|
55
|
+
----------
|
56
|
+
pontoon_types : list of int
|
57
|
+
List with one element per pontoon, indicating the pontoon type (index of Mh and Ch).
|
58
|
+
angles : list of float
|
59
|
+
List of angles of pontoons (in radians).
|
60
|
+
mat : list of ndarray
|
61
|
+
List of 3D numpy matrices (6 x 6 x Nfreq), with Npontoons entries.
|
62
|
+
|
63
|
+
Returns
|
64
|
+
-------
|
65
|
+
mat_tot : ndarray
|
66
|
+
Frequency dependent modal matrix (Nmod x Nmod x Nfreq).
|
67
|
+
|
68
|
+
Notes
|
69
|
+
-----
|
70
|
+
Docstring is generated or modified using GitHub Copilot.
|
52
71
|
"""
|
53
|
-
|
54
72
|
Nponts = len(angles)
|
55
73
|
|
56
74
|
if len(np.shape(mat[0])) == 3:
|
@@ -77,6 +95,29 @@ def wet_physmat(pontoon_types, angles, mat):
|
|
77
95
|
return mat_global
|
78
96
|
|
79
97
|
def frf_fun(M, C, K, inverse=False):
|
98
|
+
"""
|
99
|
+
Return a function that computes the frequency response function (FRF) or its inverse.
|
100
|
+
|
101
|
+
Parameters
|
102
|
+
----------
|
103
|
+
M : callable
|
104
|
+
Function returning mass matrix for a given frequency.
|
105
|
+
C : callable
|
106
|
+
Function returning damping matrix for a given frequency.
|
107
|
+
K : callable
|
108
|
+
Function returning stiffness matrix for a given frequency.
|
109
|
+
inverse : bool, optional
|
110
|
+
If True, return the inverse FRF (default is False).
|
111
|
+
|
112
|
+
Returns
|
113
|
+
-------
|
114
|
+
function
|
115
|
+
Function that computes the FRF or its inverse for a given frequency.
|
116
|
+
|
117
|
+
Notes
|
118
|
+
-----
|
119
|
+
Docstring is generated or modified using GitHub Copilot.
|
120
|
+
"""
|
80
121
|
if inverse:
|
81
122
|
return lambda omega_k: -omega_k**2*M(omega_k) + omega_k*1j*C(omega_k) + K(omega_k)
|
82
123
|
else:
|
@@ -86,19 +127,28 @@ def frf(M, C, K, w, inverse=False):
|
|
86
127
|
"""
|
87
128
|
Establish frequency response function from M, C and K matrices (all may be frequency dependent).
|
88
129
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
130
|
+
Parameters
|
131
|
+
----------
|
132
|
+
M : ndarray
|
133
|
+
Mass matrix (Ndofs x Ndofs x Nfreq or Ndofs x Ndofs).
|
134
|
+
C : ndarray
|
135
|
+
Damping matrix (Ndofs x Ndofs x Nfreq or Ndofs x Ndofs).
|
136
|
+
K : ndarray
|
137
|
+
Stiffness matrix (Ndofs x Ndofs x Nfreq or Ndofs x Ndofs).
|
138
|
+
w : array_like
|
139
|
+
Frequency axis.
|
140
|
+
inverse : bool, optional
|
141
|
+
If True, return the inverse FRF (default is False).
|
142
|
+
|
143
|
+
Returns
|
144
|
+
-------
|
145
|
+
H : ndarray
|
146
|
+
Frequency response function matrix (Ndofs x Ndofs x Nfreq).
|
147
|
+
|
148
|
+
Notes
|
149
|
+
-----
|
150
|
+
Docstring is generated or modified using GitHub Copilot.
|
100
151
|
"""
|
101
|
-
|
102
152
|
n_dofs = np.shape(K)[0]
|
103
153
|
n_freqs = len(w)
|
104
154
|
|
@@ -126,18 +176,22 @@ def frf(M, C, K, w, inverse=False):
|
|
126
176
|
|
127
177
|
def sum_frfs(*args):
|
128
178
|
"""
|
129
|
-
Sum frequency response function matrices
|
179
|
+
Sum frequency response function matrices by summing the inverses and reinverting.
|
130
180
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
Returns:
|
136
|
-
H: frequency response function matrix (Ndofs x Ndofs x Nfreq)
|
181
|
+
Parameters
|
182
|
+
----------
|
183
|
+
*args : ndarray
|
184
|
+
Frequency response function matrices (Ndofs x Ndofs x Nfreq).
|
137
185
|
|
138
|
-
|
139
|
-
|
186
|
+
Returns
|
187
|
+
-------
|
188
|
+
H : ndarray
|
189
|
+
Frequency response function matrix (Ndofs x Ndofs x Nfreq).
|
140
190
|
|
191
|
+
Notes
|
192
|
+
-----
|
193
|
+
Docstring is generated or modified using GitHub Copilot.
|
194
|
+
"""
|
141
195
|
Hinv = np.zeros(np.shape(args[0]))
|
142
196
|
|
143
197
|
for Hi in args:
|
@@ -149,7 +203,25 @@ def sum_frfs(*args):
|
|
149
203
|
|
150
204
|
|
151
205
|
def mat3d_sel(mat, k):
|
152
|
-
|
206
|
+
"""
|
207
|
+
Select the k-th slice from a 3D matrix, or return the matrix if 2D.
|
208
|
+
|
209
|
+
Parameters
|
210
|
+
----------
|
211
|
+
mat : ndarray
|
212
|
+
2D or 3D matrix.
|
213
|
+
k : int
|
214
|
+
Index of the slice to select.
|
215
|
+
|
216
|
+
Returns
|
217
|
+
-------
|
218
|
+
matsel : ndarray
|
219
|
+
Selected matrix slice.
|
220
|
+
|
221
|
+
Notes
|
222
|
+
-----
|
223
|
+
Docstring is generated or modified using GitHub Copilot.
|
224
|
+
"""
|
153
225
|
if len(np.shape(mat)) == 3:
|
154
226
|
matsel = mat[:, :, k]
|
155
227
|
else:
|
@@ -160,18 +232,26 @@ def mat3d_sel(mat, k):
|
|
160
232
|
|
161
233
|
def phys2modal(mat_global, phi_pontoons, inverse=False):
|
162
234
|
"""
|
163
|
-
Transform frequency dependent physical matrix to modal matrix.
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
235
|
+
Transform frequency dependent physical matrix to modal matrix or vice versa.
|
236
|
+
|
237
|
+
Parameters
|
238
|
+
----------
|
239
|
+
mat_global : ndarray
|
240
|
+
Global system matrix (6*Nponts x 6*Nponts x Nfreq or 6*Nponts x 6*Nponts).
|
241
|
+
phi_pontoons : ndarray
|
242
|
+
Modal transformation matrix (DOFs referring to pontoons only).
|
243
|
+
inverse : bool, optional
|
244
|
+
If True, transform from modal to physical (default is False).
|
245
|
+
|
246
|
+
Returns
|
247
|
+
-------
|
248
|
+
mat_modal : ndarray
|
249
|
+
Frequency dependent modal matrix (Nmod x Nmod x Nfreq).
|
250
|
+
|
251
|
+
Notes
|
252
|
+
-----
|
253
|
+
Docstring is generated or modified using GitHub Copilot.
|
173
254
|
"""
|
174
|
-
|
175
255
|
if inverse is True:
|
176
256
|
phi_pontoons = np.transpose(phi_pontoons) # Transpose phi matrix if inverse transformation
|
177
257
|
|
@@ -190,6 +270,31 @@ def phys2modal(mat_global, phi_pontoons, inverse=False):
|
|
190
270
|
|
191
271
|
#%% Assembly
|
192
272
|
def assemble_hydro_matrices_full(pontoons, omega):
|
273
|
+
"""
|
274
|
+
Assemble full hydrodynamic mass, damping, and stiffness matrices for all pontoons.
|
275
|
+
|
276
|
+
Parameters
|
277
|
+
----------
|
278
|
+
pontoons : list
|
279
|
+
List of pontoon objects.
|
280
|
+
omega : array_like
|
281
|
+
Frequency axis.
|
282
|
+
|
283
|
+
Returns
|
284
|
+
-------
|
285
|
+
Mh : ndarray
|
286
|
+
Hydrodynamic mass matrix.
|
287
|
+
Ch : ndarray
|
288
|
+
Hydrodynamic damping matrix.
|
289
|
+
Kh : ndarray
|
290
|
+
Hydrodynamic stiffness matrix.
|
291
|
+
node_labels : list
|
292
|
+
List of node labels for each pontoon.
|
293
|
+
|
294
|
+
Notes
|
295
|
+
-----
|
296
|
+
Docstring is generated or modified using GitHub Copilot.
|
297
|
+
"""
|
193
298
|
node_labels = [pontoon.node for pontoon in pontoons]
|
194
299
|
n_dofs = len(pontoons)*6
|
195
300
|
n_freqs = len(omega)
|
@@ -212,6 +317,27 @@ def assemble_hydro_matrices_full(pontoons, omega):
|
|
212
317
|
|
213
318
|
#%% General, model set up
|
214
319
|
def rayleigh(alpha, beta, omega):
|
320
|
+
"""
|
321
|
+
Compute Rayleigh damping ratio for a given frequency axis.
|
322
|
+
|
323
|
+
Parameters
|
324
|
+
----------
|
325
|
+
alpha : float
|
326
|
+
Mass proportional damping coefficient.
|
327
|
+
beta : float
|
328
|
+
Stiffness proportional damping coefficient.
|
329
|
+
omega : array_like
|
330
|
+
Frequency axis.
|
331
|
+
|
332
|
+
Returns
|
333
|
+
-------
|
334
|
+
xi : ndarray
|
335
|
+
Damping ratio for each frequency.
|
336
|
+
|
337
|
+
Notes
|
338
|
+
-----
|
339
|
+
Docstring is generated or modified using GitHub Copilot.
|
340
|
+
"""
|
215
341
|
ix_zero = np.where(omega==0)
|
216
342
|
|
217
343
|
xi = alpha * (1/(2*omega)) + beta*(omega/2)
|
@@ -220,6 +346,27 @@ def rayleigh(alpha, beta, omega):
|
|
220
346
|
return xi
|
221
347
|
|
222
348
|
def rayleigh_damping_fit(xi, omega_1, omega_2):
|
349
|
+
"""
|
350
|
+
Fit Rayleigh damping coefficients for given target damping and frequencies.
|
351
|
+
|
352
|
+
Parameters
|
353
|
+
----------
|
354
|
+
xi : float
|
355
|
+
Target damping ratio.
|
356
|
+
omega_1 : float
|
357
|
+
First frequency (rad/s).
|
358
|
+
omega_2 : float
|
359
|
+
Second frequency (rad/s).
|
360
|
+
|
361
|
+
Returns
|
362
|
+
-------
|
363
|
+
rayleigh_coeff : dict
|
364
|
+
Dictionary with 'mass' and 'stiffness' Rayleigh coefficients.
|
365
|
+
|
366
|
+
Notes
|
367
|
+
-----
|
368
|
+
Docstring is generated or modified using GitHub Copilot.
|
369
|
+
"""
|
223
370
|
rayleigh_coeff = dict()
|
224
371
|
rayleigh_coeff['mass'] = 2*xi*(omega_1*omega_2)/(omega_1+omega_2)
|
225
372
|
rayleigh_coeff['stiffness'] = 2*xi/(omega_1+omega_2)
|
@@ -228,6 +375,25 @@ def rayleigh_damping_fit(xi, omega_1, omega_2):
|
|
228
375
|
|
229
376
|
#%% Simulation
|
230
377
|
def freqsim_fun(Sqq, H):
|
378
|
+
"""
|
379
|
+
Return a function that computes the response spectral density matrix.
|
380
|
+
|
381
|
+
Parameters
|
382
|
+
----------
|
383
|
+
Sqq : callable
|
384
|
+
Function returning input spectral density matrix for a given frequency.
|
385
|
+
H : callable
|
386
|
+
Function returning frequency response matrix for a given frequency.
|
387
|
+
|
388
|
+
Returns
|
389
|
+
-------
|
390
|
+
function
|
391
|
+
Function that computes the response spectral density matrix for a given frequency.
|
392
|
+
|
393
|
+
Notes
|
394
|
+
-----
|
395
|
+
Docstring is generated or modified using GitHub Copilot.
|
396
|
+
"""
|
231
397
|
def response(omega):
|
232
398
|
return H(omega) @ Sqq(omega) @ H(omega).conj().T
|
233
399
|
|
@@ -235,6 +401,25 @@ def freqsim_fun(Sqq, H):
|
|
235
401
|
|
236
402
|
|
237
403
|
def freqsim(Sqq, H):
|
404
|
+
"""
|
405
|
+
Compute the response spectral density matrix for all frequencies.
|
406
|
+
|
407
|
+
Parameters
|
408
|
+
----------
|
409
|
+
Sqq : ndarray
|
410
|
+
Input spectral density matrix (Ndofs x Ndofs x Nfreq).
|
411
|
+
H : ndarray
|
412
|
+
Frequency response matrix (Ndofs x Ndofs x Nfreq).
|
413
|
+
|
414
|
+
Returns
|
415
|
+
-------
|
416
|
+
Srr : ndarray
|
417
|
+
Response spectral density matrix (Ndofs x Ndofs x Nfreq).
|
418
|
+
|
419
|
+
Notes
|
420
|
+
-----
|
421
|
+
Docstring is generated or modified using GitHub Copilot.
|
422
|
+
"""
|
238
423
|
n_freqs = np.shape(Sqq)[2]
|
239
424
|
Srr = np.zeros(np.shape(Sqq)).astype('complex')
|
240
425
|
|
@@ -245,6 +430,29 @@ def freqsim(Sqq, H):
|
|
245
430
|
|
246
431
|
|
247
432
|
def var_from_modal(omega, S, phi, only_diagonal=True):
|
433
|
+
"""
|
434
|
+
Compute variance from modal spectral density.
|
435
|
+
|
436
|
+
Parameters
|
437
|
+
----------
|
438
|
+
omega : array_like
|
439
|
+
Frequency axis.
|
440
|
+
S : ndarray
|
441
|
+
Modal spectral density matrix (Nmod x Nmod x Nfreq).
|
442
|
+
phi : ndarray
|
443
|
+
Modal transformation matrix.
|
444
|
+
only_diagonal : bool, optional
|
445
|
+
If True, return only the diagonal elements (default is True).
|
446
|
+
|
447
|
+
Returns
|
448
|
+
-------
|
449
|
+
var : ndarray
|
450
|
+
Variance matrix or its diagonal.
|
451
|
+
|
452
|
+
Notes
|
453
|
+
-----
|
454
|
+
Docstring is generated or modified using GitHub Copilot.
|
455
|
+
"""
|
248
456
|
var = phi @ np.real(np.trapz(S, omega, axis=2)) @ phi.T
|
249
457
|
|
250
458
|
if only_diagonal==True:
|
@@ -253,6 +461,31 @@ def var_from_modal(omega, S, phi, only_diagonal=True):
|
|
253
461
|
return var
|
254
462
|
|
255
463
|
def peakfactor_from_modal(omega, S, phi, T, only_diagonal=True):
|
464
|
+
"""
|
465
|
+
Compute peak factor from modal spectral density.
|
466
|
+
|
467
|
+
Parameters
|
468
|
+
----------
|
469
|
+
omega : array_like
|
470
|
+
Frequency axis.
|
471
|
+
S : ndarray
|
472
|
+
Modal spectral density matrix (Nmod x Nmod x Nfreq).
|
473
|
+
phi : ndarray
|
474
|
+
Modal transformation matrix.
|
475
|
+
T : float
|
476
|
+
Duration for peak factor calculation.
|
477
|
+
only_diagonal : bool, optional
|
478
|
+
If True, return only the diagonal elements (default is True).
|
479
|
+
|
480
|
+
Returns
|
481
|
+
-------
|
482
|
+
kp : ndarray
|
483
|
+
Peak factor matrix or its diagonal.
|
484
|
+
|
485
|
+
Notes
|
486
|
+
-----
|
487
|
+
Docstring is generated or modified using GitHub Copilot.
|
488
|
+
"""
|
256
489
|
m0 = phi @ np.real(np.trapz(S, omega, axis=2)) @ phi.T
|
257
490
|
m2 = phi @ np.real(np.trapz(S*omega**2, omega, axis=2)) @ phi.T
|
258
491
|
v0 = 1/(2*np.pi) * np.sqrt(m2/m0)
|
@@ -264,6 +497,31 @@ def peakfactor_from_modal(omega, S, phi, T, only_diagonal=True):
|
|
264
497
|
return kp
|
265
498
|
|
266
499
|
def expmax_from_modal(omega, S, phi, T, only_diagonal=True):
|
500
|
+
"""
|
501
|
+
Compute expected maximum from modal spectral density.
|
502
|
+
|
503
|
+
Parameters
|
504
|
+
----------
|
505
|
+
omega : array_like
|
506
|
+
Frequency axis.
|
507
|
+
S : ndarray
|
508
|
+
Modal spectral density matrix (Nmod x Nmod x Nfreq).
|
509
|
+
phi : ndarray
|
510
|
+
Modal transformation matrix.
|
511
|
+
T : float
|
512
|
+
Duration for expected maximum calculation.
|
513
|
+
only_diagonal : bool, optional
|
514
|
+
If True, return only the diagonal elements (default is True).
|
515
|
+
|
516
|
+
Returns
|
517
|
+
-------
|
518
|
+
expmax : ndarray
|
519
|
+
Expected maximum matrix or its diagonal.
|
520
|
+
|
521
|
+
Notes
|
522
|
+
-----
|
523
|
+
Docstring is generated or modified using GitHub Copilot.
|
524
|
+
"""
|
267
525
|
m0 = phi @ np.real(np.trapz(S, omega, axis=2)) @ phi.T
|
268
526
|
m2 = phi @ np.real(np.trapz(S*omega**2, omega, axis=2)) @ phi.T
|
269
527
|
v0 = 1/(2*np.pi) * np.sqrt(m2/m0)
|
wawi/time_domain.py
CHANGED
@@ -3,6 +3,26 @@ from scipy.interpolate import interp1d
|
|
3
3
|
from scipy.linalg import block_diag, cholesky
|
4
4
|
|
5
5
|
def band_truncate_3d(M3d, n):
|
6
|
+
"""
|
7
|
+
Truncate the bands of a 3D matrix M3d along the first two dimensions.
|
8
|
+
|
9
|
+
Parameters
|
10
|
+
----------
|
11
|
+
M3d : np.ndarray
|
12
|
+
A 3D numpy array of shape (n, n, m) representing the spectral density matrices for `m` frequency bins.
|
13
|
+
n : int
|
14
|
+
The number of bands to keep in the truncation.
|
15
|
+
|
16
|
+
Returns
|
17
|
+
-------
|
18
|
+
M3d : np.ndarray
|
19
|
+
A 3D numpy array of the same shape as `M3d`, where each slice is band-truncated.
|
20
|
+
|
21
|
+
Notes
|
22
|
+
-----
|
23
|
+
Docstring is generated by GitHub Copilot.
|
24
|
+
|
25
|
+
"""
|
6
26
|
for k in range(M3d.shape[2]):
|
7
27
|
M3d[:,:,k] = band_truncate(M3d[:,:,k], n=n)
|
8
28
|
|
@@ -10,6 +30,26 @@ def band_truncate_3d(M3d, n):
|
|
10
30
|
|
11
31
|
|
12
32
|
def band_truncate(M, n=1):
|
33
|
+
"""
|
34
|
+
Truncate the bands of a 2D matrix M along the first two dimensions.
|
35
|
+
|
36
|
+
Parameters
|
37
|
+
----------
|
38
|
+
M : np.ndarray
|
39
|
+
A 2D numpy array of shape (n, n) representing the spectral density matrix.
|
40
|
+
n : int
|
41
|
+
The number of bands to keep in the truncation.
|
42
|
+
|
43
|
+
Returns
|
44
|
+
-------
|
45
|
+
M : np.ndarray
|
46
|
+
A 2D numpy array of the same shape as `M`, where each slice is band-truncated.
|
47
|
+
|
48
|
+
Notes
|
49
|
+
-----
|
50
|
+
Docstring is generated by GitHub Copilot.
|
51
|
+
|
52
|
+
"""
|
13
53
|
if n is None:
|
14
54
|
n = M.shape[0]
|
15
55
|
|
@@ -24,6 +64,31 @@ def band_truncate(M, n=1):
|
|
24
64
|
return Mt
|
25
65
|
|
26
66
|
def fft_time(omega, t0=0, n_fft=None):
|
67
|
+
"""
|
68
|
+
Generate a time vector for FFT based on the frequency vector `omega`.
|
69
|
+
|
70
|
+
Parameters
|
71
|
+
----------
|
72
|
+
omega : np.ndarray
|
73
|
+
A 1D numpy array representing the frequency vector in rad/s.
|
74
|
+
t0 : float, optional
|
75
|
+
|
76
|
+
The starting time for the time vector. Default is 0.
|
77
|
+
n_fft : int, optional
|
78
|
+
|
79
|
+
The number of points in the FFT. If not provided, it is set to the length of `omega`.
|
80
|
+
|
81
|
+
Returns
|
82
|
+
-------
|
83
|
+
t : np.ndarray
|
84
|
+
A 1D numpy array representing the time vector corresponding to the frequency vector `omega`.
|
85
|
+
|
86
|
+
Notes
|
87
|
+
-----
|
88
|
+
Docstring is generated by GitHub Copilot.
|
89
|
+
|
90
|
+
"""
|
91
|
+
|
27
92
|
if n_fft is None:
|
28
93
|
n_fft = len(omega)
|
29
94
|
domega = omega[1] - omega[0]
|
@@ -32,6 +97,39 @@ def fft_time(omega, t0=0, n_fft=None):
|
|
32
97
|
return t
|
33
98
|
|
34
99
|
def spectrum_to_process(S, reg_factor=None, zero_limit=None):
|
100
|
+
"""
|
101
|
+
Convert a spectral density matrix to its Cholesky factor process.
|
102
|
+
This function takes a 3D array representing a spectral density matrix `S` and computes its
|
103
|
+
Cholesky factor for each frequency slice. Optional regularization can be applied to ensure positive definiteness,
|
104
|
+
and a zero limit can be set to skip decomposition for near-zero matrices.
|
105
|
+
|
106
|
+
Parameters
|
107
|
+
----------
|
108
|
+
S : np.ndarray
|
109
|
+
A 3D array of shape (n, n, m) representing the spectral density matrices for `m` frequency bins.
|
110
|
+
reg_factor : float, optional
|
111
|
+
Regularization factor to be added to the diagonal of each frequency slice of `S` to ensure positive definiteness.
|
112
|
+
zero_limit : float, optional
|
113
|
+
Threshold below which the Cholesky decomposition is skipped for a frequency slice.
|
114
|
+
|
115
|
+
Returns
|
116
|
+
-------
|
117
|
+
B : np.ndarray
|
118
|
+
A 3D array of the same shape as `S`, where each slice is the lower-triangular Cholesky factor of the corresponding slice in `S`.
|
119
|
+
|
120
|
+
Raises
|
121
|
+
------
|
122
|
+
ValueError
|
123
|
+
If regularization causes the norm of `S` to increase by more than 10%.
|
124
|
+
|
125
|
+
Notes
|
126
|
+
-----
|
127
|
+
- The function modifies `S` in-place if regularization is applied.
|
128
|
+
- Cholesky decomposition is only performed for slices where the maximum absolute value exceeds `zero_limit`.
|
129
|
+
|
130
|
+
Docstring is generated by GitHub Copilot.
|
131
|
+
"""
|
132
|
+
|
35
133
|
B = S*0 # copy S to chol factor
|
36
134
|
norm_pre = np.linalg.norm(S)
|
37
135
|
if reg_factor is not None:
|
@@ -53,7 +151,7 @@ def simulate_mdof(S, omega, fs=None, tmax=None, reg_factor=None, zero_limit=1e-1
|
|
53
151
|
component_scaling=None, print_status=False):
|
54
152
|
|
55
153
|
'''
|
56
|
-
Simulate time series from given cross-spectral density matrix.
|
154
|
+
Simulate time series from given cross-spectral density matrix, using FFT.
|
57
155
|
|
58
156
|
Parameters
|
59
157
|
----------------
|
@@ -152,6 +250,29 @@ def simulate_mdof(S, omega, fs=None, tmax=None, reg_factor=None, zero_limit=1e-1
|
|
152
250
|
|
153
251
|
|
154
252
|
def simulate_mdof_direct(S, omega, reg_factor=None):
|
253
|
+
"""
|
254
|
+
Simulate time series from given cross-spectral density matrix, using direct summation.
|
255
|
+
|
256
|
+
Parameters
|
257
|
+
----------------
|
258
|
+
S : float
|
259
|
+
cross-spectral density matrix (Ndofs x Ndofs x Nfreqs) as complex numpy array
|
260
|
+
omega : float
|
261
|
+
numpy array defining frequencies in rad/s
|
262
|
+
reg_factor : float, optional
|
263
|
+
to help the Cholesky decomposition to achieve a numerical solution,
|
264
|
+
a diagonal matrix with the norm of all frequency components of the matrix S scaled by the given factor
|
265
|
+
- if no value is given (--> None imposed), no regularization is conducted;
|
266
|
+
used as input to function `spectrum_to_process` which decomposes the spectral density
|
267
|
+
|
268
|
+
Returns
|
269
|
+
----------------
|
270
|
+
p : float
|
271
|
+
time history
|
272
|
+
t : float
|
273
|
+
numpy array with time axis values corresponding to `p`
|
274
|
+
|
275
|
+
"""
|
155
276
|
B = spectrum_to_process(S, reg_factor)
|
156
277
|
|
157
278
|
# Summation
|
wawi/tools.py
CHANGED
@@ -1,6 +1,29 @@
|
|
1
1
|
import numpy as np
|
2
2
|
|
3
3
|
def print_progress(t, tmax, length=20, sym='=', postfix='', startstop_sym=' '):
|
4
|
+
"""
|
5
|
+
Print a progress bar to the console.
|
6
|
+
|
7
|
+
Parameters
|
8
|
+
----------
|
9
|
+
t : int or float
|
10
|
+
Current progress value.
|
11
|
+
tmax : int or float
|
12
|
+
Maximum progress value.
|
13
|
+
length : int, optional
|
14
|
+
Length of the progress bar (default is 20).
|
15
|
+
sym : str, optional
|
16
|
+
Symbol used to represent progress (default is '=').
|
17
|
+
postfix : str, optional
|
18
|
+
String to append at the end of the progress bar (default is '').
|
19
|
+
startstop_sym : str, optional
|
20
|
+
Symbol to use at the start and end of the progress bar (default is ' ').
|
21
|
+
|
22
|
+
Returns
|
23
|
+
-------
|
24
|
+
None
|
25
|
+
This function prints the progress bar to the console.
|
26
|
+
"""
|
4
27
|
progress = t/tmax
|
5
28
|
n_syms = np.floor(progress*length).astype(int)
|
6
29
|
string = "\r[%s%-"+ str(length*len(sym)) +"s%s] %3.0f%%" + postfix
|