wawi 0.0.13__py3-none-any.whl → 0.0.17__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/identification.py CHANGED
@@ -1,23 +1,26 @@
1
1
  import numpy as np
2
2
  from scipy.optimize import fsolve
3
3
 
4
- def get_combinations(n_p,n_q=None):
4
+ def get_combinations(n_p, n_q=None):
5
5
  '''
6
6
  Establish all combinations of n indices.
7
7
 
8
8
  Parameters
9
- ------------
9
+ ----------
10
10
  n_p : int
11
- number of indices
11
+ Number of indices.
12
12
  n_q : None, optional
13
- if integer is given, this is used - otherwise standard value None makes n_q = n_p
13
+ If integer is given, this is used - otherwise standard value None makes n_q = n_p.
14
14
 
15
15
  Returns
16
- ------------
17
- combos : int
18
- numpy array of all combinations (2-by-n_comb)
19
- '''
16
+ -------
17
+ combos : list of list of int
18
+ List of all unique index combinations (2-by-n_comb).
20
19
 
20
+ Notes
21
+ -----
22
+ Docstring generated using GitHub Copilot.
23
+ '''
21
24
  p = np.arange(n_p)
22
25
  if n_q is None:
23
26
  q = p
@@ -25,8 +28,8 @@ def get_combinations(n_p,n_q=None):
25
28
  combos = []
26
29
  for pi in p:
27
30
  for qi in q:
28
- combo = list(np.sort([pi,qi]))
29
- if (pi!=qi) and (combo not in combos):
31
+ combo = list(np.sort([pi, qi]))
32
+ if (pi != qi) and (combo not in combos):
30
33
  combos.append(combo)
31
34
 
32
35
  return combos
@@ -34,6 +37,26 @@ def get_combinations(n_p,n_q=None):
34
37
  def wave_number_id(Sx, x, k0, Sref=None):
35
38
  '''
36
39
  Experimental function to establish wave number nonparametrically from cross spectral density.
40
+
41
+ Parameters
42
+ ----------
43
+ Sx : ndarray
44
+ Cross spectral density matrix, shape (n_channels, n_channels, n_freq).
45
+ x : ndarray
46
+ Array of spatial positions, shape (n_channels,).
47
+ k0 : float
48
+ Initial guess for wave number (not used in current implementation).
49
+ Sref : None, optional
50
+ Reference spectral density (not used in current implementation).
51
+
52
+ Returns
53
+ -------
54
+ k : ndarray
55
+ Estimated wave numbers for each frequency, shape (n_freq,).
56
+
57
+ Notes
58
+ -----
59
+ Docstring generated using GitHub Copilot.
37
60
  '''
38
61
  k = np.zeros(Sx.shape[2])
39
62
  n_freq = Sx.shape[2]
@@ -58,7 +81,6 @@ def wave_number_id(Sx, x, k0, Sref=None):
58
81
  lnGamma[ix] = np.log(Sx[dof1, dof2, n]/S)
59
82
  k_all[ix] = 1j/dx * lnGamma[ix]
60
83
 
61
- # k[n] = (b[np.newaxis,:] @ np.linalg.pinv(lnGamma[np.newaxis,:]))[0][0]
62
84
  k[n] = np.mean(k_all)
63
85
 
64
86
 
wawi/io.py CHANGED
@@ -11,7 +11,7 @@ from wawi.model import ModalDry, PontoonType, Node, Model, Aero, AeroSection
11
11
  def import_folder(model_folder, pontoon_stl='pontoon.stl', aero_sections='aero_sections.json',
12
12
  modal='modal.json', pontoon='pontoon.json', eldef='element.json', orientations='orientations.json',
13
13
  drag_elements='drag_elements.json', pontoon_types='pontoon_types.json',
14
- sort_nodes_by_x=True, interpolation_kind='quadratic'):
14
+ sort_nodes_by_x=True, interpolation_kind='linear'):
15
15
 
16
16
  '''
17
17
  Import folder containing files defining a WAWI model.
@@ -48,9 +48,212 @@ def import_folder(model_folder, pontoon_stl='pontoon.stl', aero_sections='aero_s
48
48
 
49
49
  Notes
50
50
  ---------------
51
- TODO: Add info here describing the structure and contents of all files.
52
-
53
- See `importing-folder.ipynb` for a full example.
51
+ Often, it is more convenient to define all (or many) of the model parameters in input files rather than in scripts. To simplify this process, a support function `wawi.io.import_folder` is provided in WAWI. An example of how to use the function is given in the example [Folder import of models.ipynb](./examples/0 Model generation and setup/JSON definition and folder import/Folder import of models.ipynb)
52
+
53
+ This imports all files in the specified folder. The file names of the relevant files in the provided path are defined as inputs to the function (default values in parentheses):
54
+
55
+ - modal ('modal.json')
56
+ - pontoon('pontoon.json')
57
+ - pontoon_types ('pontoon_types.json')
58
+ - pontoon_stl ('pontoon.stl')
59
+ - eldef ('element.json')
60
+ - aero_sections ('aero_sections.json')
61
+ - orientations ('orientations.json')
62
+ - drag_elements ('drag_elements.json')
63
+
64
+ Modal definition (modal)
65
+ ^^^^^^^^^^^^^^^^^^^^^^^^
66
+ The first file, 'modal.json', defines the dry modes of the structure under consideration. It includes the following fields:
67
+
68
+ ```json
69
+ {
70
+ "local": false,
71
+ "phi": {
72
+ "full": [[...]],
73
+ "hydro": [[...]],
74
+ "girder": [[...]],
75
+ "girder_forces": [[...]]
76
+ },
77
+ "m": [...],
78
+ "omega_n": [...]
79
+ }
80
+ ```
81
+
82
+ The `local` parameter defines if the modal transformation matrices (mode shapes) are given in local or global coordinate system. Typically, a global system is more convenient, but both types should work fine in WAWI. The `phi` parameter gives a dictionary defining collections of mode shapes (or modal transformation matrices). The values should be list of lists (inner list is a row) describing the modal transformation matrix of a given key. The matrices have dimensions dofs-by-modes. The keys 'full' and 'hydro' are defaults in WAWI for the full model (used for plotting and convenient for aerodynamic analysis) and pontoon loading, respectively (they can be modified, but sticking with the defaults is a good choice). Furthermore, at least two of the following modal parameters must be given: `m` (modal mass) and `omega_n` (undamped natural frequencies in rad/s) or `m` and `k` (modal stiffness). All of these are 1d lists with length matching the number of columns in all entries in `phi`.
83
+
84
+ Pontoon and pontoon types (pontoon, pontoon_types, pontoon_stl)
85
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
86
+ All pontoon-related definitions are given by the files `pontoon.json`, `pontoon_types.json` and `pontoon.stl`.
87
+
88
+ Firstly, `pontoon.json` defines pontoon coordinates, orientations and pontoon type definition, as follows:
89
+
90
+ ```json
91
+ {
92
+ "P1": {
93
+ "coordinates": [0.0, 0.0, 0.0],
94
+ "pontoon_type": "ptype_1",
95
+ "rotation": 0,
96
+ "node": 1
97
+ },
98
+ "P2": {
99
+ "coordinates": [100.0, 0.0, 0.0],
100
+ "pontoon_type": "ptype_1",
101
+ "rotation": 12.5,
102
+ "node": 2
103
+ }
104
+ }
105
+ ```
106
+
107
+ This defines two pontoons (named P1 and P2), places them at coordinates (0,0,0) and (100.0, 0, 0) with orientation (0 deg and 12.5 deg), assigns pontoon type from files "ptype_1.npz". Also, the `node` parameter connects the pontoons to nodes 1 and 2, which should be present in the node matrix of the full system (see `node_matrix` in `element.json`). When a pontoon is connected to a node, the pontoon is automatically plotted together with the elements when using the plotting methods of the model (both rotation and location of the node is used). Also, the coordinates of the pontoon is overwritten by the coordinates of the node. Only the x and y coordinates of the pontoon matters for the computation, as the resulting wave excitation from irregular wave fields is dependent on the horizontal coordinates. The pontoon type definition is an npz-file containing the following numpy nd arrays:
108
+
109
+ * Added mass: 'M' (6 x 6 x len(omega))
110
+ * Radiation/added damping: 'C' (6 x 6 x len(omega))
111
+ * Linear hydrodynamic transfer function matrix: 'Q' (6 x len(theta_Q) x len(omega_Q))
112
+ * omega (for mass and damping): 'omega'
113
+ * theta for transfer: 'theta_Q'
114
+ * omega for transfer: 'omega_Q'
115
+
116
+ Second, the file `pontoon_types.json` is usually not needed. It is merely added to enable adding additional properties to the pontoon types, not present in the npz-files. Currently, this is limited to drag coefficients and drag areas for inclusion of linearized drag effects (stochastic linearization). It could look something like this (drag terms ordered as relevant to x, y and z-directions, respectively):
117
+
118
+ ```json
119
+ {
120
+ "ptype_1": {
121
+ "Cd": [1.0, 1.0, 2.0],
122
+ "area": [1.0, 2.0, 2.0]
123
+ },
124
+
125
+ "ptype_2": {
126
+ "Cd": [0.5, 0.4, 0.8],
127
+ "area": [1.0, 2.0, 2.0]
128
+ }
129
+ }
130
+ ```
131
+
132
+ If instead a wildcard name is used, these properties are used for all pontoons:
133
+
134
+ ```json
135
+ {
136
+ "*": {
137
+ "Cd": [1.0, 1.0, 2.0],
138
+ "area": [1.0, 2.0, 2.0]
139
+ }
140
+ }
141
+ ```
142
+
143
+ Finally, the `pontoon.stl` file is simply a step file containing the mesh used to visualize pontoons together with the elements in the plotting methods.
144
+
145
+ Element definition (eldef)
146
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
147
+ The file `element.json` defines the elements of the model (for aerodynamic analysis and plotting). It must contain the keys 'element_matrix' and 'node_matrix', and can also contain the fields 'sections' and 'section_assignments'. The two first are list of lists where the innermost lists are rows. These follow the typical convention in input files; rows of the node matrix consist of node label, x-coordinate, y-coordinate and z-coordinate, whereas the rows of the element matrix consist of the element label, label of the first node and label of the second node.
148
+
149
+ The two latter properties of the files are not used inside WAWI directly (unless using drag elements, see below), but are used for the definition of the elements in the BEEF environment. It can therefore be useful for if the user for instance wants to calculate the stresses in an element, as all relevant properties are present inside the `eldef` attribute of the `model` object. The `sections` property is assumed self-explanatory from the json example provided. The `section_assignment` property is built up with a list of strings where each entry corresponds to the same-index row of the element matrix.
150
+
151
+ ```json
152
+ {
153
+ "element_matrix": [[...]],
154
+ "node_matrix":[[...]],
155
+
156
+ "sections":
157
+ {
158
+ "girder":
159
+ {"E": 210000000000.0,
160
+ "Iz": 0.09285714285714286,
161
+ "Iy": 0.09285714285714286,
162
+ "A": 0.0052928571428571426,
163
+ "poisson": 0.3,
164
+ "J": 0.10714285714285714,
165
+ "m": 45.6272019496974},
166
+
167
+ "column":
168
+ {"E": 210000000000.0,
169
+ "Iz": 0.09285714285714286,
170
+ "Iy": 0.09285714285714286,
171
+ "A": 0.0052928571428571426,
172
+ "poisson": 0.3,
173
+ "J": 0.10714285714285714,
174
+ "m": 45.6272019496974}
175
+ },
176
+
177
+ "section_assignments": ["girder", "girder", "girder", "column", "column"]
178
+ }
179
+ ```
180
+
181
+ Aerodynamic sections (aero_sections, orientations)
182
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
183
+ Aerodynamic sections relate aerodynamic properties to the elements defined in the section above. Two definitions are required, and are given in the files
184
+ `aero_sections.json` and `orientations.json`.
185
+
186
+ First, the aerodynamic sections are defined in the `aero_sections.json`-file, as follows:
187
+
188
+ ```json
189
+ {
190
+ "girder":
191
+ {
192
+ "B":26.8,
193
+ "D":3.715,
194
+
195
+ "Cd":0.679,
196
+ "dCd":-1.022,
197
+ "Cl":-0.3896,
198
+ "dCl":4.0116,
199
+ "Cm":-0.0700,
200
+ "dCm":1.0122,
201
+
202
+ "elements": [1000, 1001, 1002, 1003, ...]
203
+ },
204
+
205
+ "column":
206
+ {
207
+ "B":3,
208
+ "D":3,
209
+
210
+ "Cd":0.679,
211
+ "dCd":-1.022,
212
+ "Cl":-0.3896,
213
+ "dCl":4.0116,
214
+ "Cm":-0.0700,
215
+ "dCm":1.0122,
216
+
217
+ "elements": [2001, 2002, 2003, 2004, 2005, ...]
218
+ }
219
+ }
220
+ ```
221
+
222
+ Here, two aerodynamic sections are defined. This includes definitions of width (B), height (D), static wind coefficients (Cd, dCd, Cl, dCl, Cm, and dCm - see `wawi.model.aero.AeroSection` for details on this) and a list of elements to apply the sections to.
223
+
224
+ For aerodynamic analysis, the orientations of the elements are crucial. These are defined in the second file (`orientations.json`). The following structure is used for this:
225
+
226
+ ```json
227
+ {
228
+ "girder": {
229
+ "e3": [0,0,1],
230
+ "elements": [1000, 1001, 1002, 1003, ...]
231
+ },
232
+ "column": {
233
+ "e2": [0,1,0],
234
+ "elements": [2001, 2002, 2003, 2004, 2005, ...]
235
+ }
236
+ }
237
+ ```
238
+
239
+ In the above snippet, two definitions of orientations are given. Note that the keys here are not used for anything (and are not related to the `aero_sections.json` keys); they are merely included to make it convenient for the user to maintain a structured model setup. The orientation is given by either `e2` or `e3`, indicating if the y/drag or z/lift of the element is defined. Note also that these definitions are assumed approximate; the procedure inside WAWI consists of taking a cross product between the supplied unit vector and the axial direction of the element, which gives a proper perpendicular vector. The last perpendicular vector is thereafter based on a secondary cross product between the calculated perpendicular unit vector and the longitudinal vector. Finally, a list of elements to assign the orientation to is provided. The resulting orientation is conveniently plotted in the model using `model.plot(tmat_on=['undeformed'], tmat_scaling=100)` (adjust `scaling` to make sense for your problem).
240
+
241
+ Drag elements (drag_elements)
242
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
243
+ To accommodate the possibility for floating bridges to have mooring lines with significant quadratic drag damping, an additional file for defining these properties is supported. Note that this, as for the drag of the pontoons, is only solved in a linearized sense using (approximate) stochastic linearization techniques. The `drag_elements.json` file is defined as follows:
244
+
245
+ ```json
246
+ {
247
+ "mooring_wire":
248
+ { "sections": "MooringWire",
249
+ "zrange": [-1e4, 0.0],
250
+ "rho": 1025.0,
251
+ "Cd": [0.1, 1.2, 1.2],
252
+ "D": 0.146}
253
+ }
254
+ ```
255
+
256
+ For the drag element group named "mooring_wire" above, all elements present in the elements assigned with the relevant section assignment(s) in `element.json` (either list of several strings or single string defined with property `sections`) and that have a z-coordinate inside the provided `zrange` will be given quadratic drag damping according to the specified density (`rho`), drag coefficients in local x, y and z-direction (`Cd`) and diameter (`D`).
54
257
  '''
55
258
 
56
259
 
@@ -148,7 +351,7 @@ def import_folder(model_folder, pontoon_stl='pontoon.stl', aero_sections='aero_s
148
351
  ptypes[name] = PontoonType.from_numeric(interpolation_kind=interpolation_kind, A=P['M'], B=P['C'],
149
352
  omega=P['omega'], Q=P['Q'], theta=P['theta_Q'], omegaQ=P['omega_Q'], label=name,
150
353
  stl_path=f'{model_folder}/{pontoon_stl}', **{**ACd, **pontoon_type_settings[name]})
151
-
354
+
152
355
 
153
356
  # Modal dry object
154
357
  if 'xi0' in modal: