capytaine 2.2__cp310-cp310-win_amd64.whl → 2.3__cp310-cp310-win_amd64.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.
Files changed (54) hide show
  1. capytaine/__about__.py +1 -1
  2. capytaine/__init__.py +6 -6
  3. capytaine/bem/airy_waves.py +7 -2
  4. capytaine/bem/engines.py +2 -2
  5. capytaine/bem/problems_and_results.py +82 -35
  6. capytaine/bem/solver.py +138 -41
  7. capytaine/bodies/bodies.py +40 -12
  8. capytaine/bodies/predefined/rectangles.py +2 -0
  9. capytaine/green_functions/FinGreen3D/.gitignore +1 -0
  10. capytaine/green_functions/FinGreen3D/FinGreen3D.f90 +3589 -0
  11. capytaine/green_functions/FinGreen3D/LICENSE +165 -0
  12. capytaine/green_functions/FinGreen3D/Makefile +16 -0
  13. capytaine/green_functions/FinGreen3D/README.md +24 -0
  14. capytaine/green_functions/FinGreen3D/test_program.f90 +39 -0
  15. capytaine/green_functions/LiangWuNoblesse/.gitignore +1 -0
  16. capytaine/green_functions/LiangWuNoblesse/LICENSE +504 -0
  17. capytaine/green_functions/LiangWuNoblesse/LiangWuNoblesseWaveTerm.f90 +751 -0
  18. capytaine/green_functions/LiangWuNoblesse/Makefile +18 -0
  19. capytaine/green_functions/LiangWuNoblesse/README.md +2 -0
  20. capytaine/green_functions/LiangWuNoblesse/test_program.f90 +28 -0
  21. capytaine/green_functions/abstract_green_function.py +55 -3
  22. capytaine/green_functions/delhommeau.py +186 -115
  23. capytaine/green_functions/hams.py +204 -0
  24. capytaine/green_functions/libs/Delhommeau_float32.cp310-win_amd64.dll.a +0 -0
  25. capytaine/green_functions/libs/Delhommeau_float32.cp310-win_amd64.pyd +0 -0
  26. capytaine/green_functions/libs/Delhommeau_float64.cp310-win_amd64.dll.a +0 -0
  27. capytaine/green_functions/libs/Delhommeau_float64.cp310-win_amd64.pyd +0 -0
  28. capytaine/io/bemio.py +14 -2
  29. capytaine/io/mesh_loaders.py +2 -1
  30. capytaine/io/wamit.py +479 -0
  31. capytaine/io/xarray.py +252 -100
  32. capytaine/matrices/block.py +4 -2
  33. capytaine/matrices/linear_solvers.py +1 -1
  34. capytaine/matrices/low_rank.py +3 -1
  35. capytaine/meshes/clipper.py +4 -3
  36. capytaine/meshes/collections.py +11 -1
  37. capytaine/meshes/mesh_like_protocol.py +37 -0
  38. capytaine/meshes/meshes.py +22 -9
  39. capytaine/meshes/properties.py +58 -24
  40. capytaine/meshes/symmetric.py +11 -2
  41. capytaine/post_pro/kochin.py +4 -4
  42. capytaine/tools/lists_of_points.py +3 -3
  43. capytaine/tools/prony_decomposition.py +60 -4
  44. capytaine/tools/symbolic_multiplication.py +30 -2
  45. capytaine/tools/timer.py +64 -0
  46. capytaine-2.3.dist-info/DELVEWHEEL +2 -0
  47. capytaine-2.3.dist-info/METADATA +761 -0
  48. capytaine-2.3.dist-info/RECORD +97 -0
  49. capytaine-2.2.dist-info/DELVEWHEEL +0 -2
  50. capytaine-2.2.dist-info/METADATA +0 -751
  51. capytaine-2.2.dist-info/RECORD +0 -81
  52. {capytaine-2.2.dist-info → capytaine-2.3.dist-info}/LICENSE +0 -0
  53. {capytaine-2.2.dist-info → capytaine-2.3.dist-info}/WHEEL +0 -0
  54. {capytaine-2.2.dist-info → capytaine-2.3.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,204 @@
1
+ from importlib import import_module
2
+ from scipy.optimize import brentq
3
+ import numpy as np
4
+
5
+ from capytaine.green_functions.abstract_green_function import AbstractGreenFunction, GreenFunctionEvaluationError
6
+
7
+
8
+ class LiangWuNoblesseGF(AbstractGreenFunction):
9
+ """Wrapper for the Fortran implementation of the infinite depth Green function of [Liang, Wu, Noblesse, 2018].
10
+
11
+ Uses the same implementation as Delhommeau() for the Rankine and reflected Rankine terms.
12
+
13
+ """
14
+ floating_point_precision = "float64"
15
+
16
+ fortran_core = import_module("capytaine.green_functions.libs.Delhommeau_float64")
17
+ tabulation_grid_shape_index = fortran_core.constants.liang_wu_noblesse
18
+ exportable_settings = {'green_function': "LiangWuNoblesseGF"}
19
+
20
+ # Dummy arrays that won't actually be used by the fortran code.
21
+ prony_decomposition = np.zeros((1, 1))
22
+ dispersion_relation_roots = np.empty(1)
23
+ finite_depth_method_index = -9999
24
+ tabulation_nb_integration_points = 1
25
+ tabulated_r_range = np.empty(1)
26
+ tabulated_z_range = np.empty(1)
27
+ tabulated_integrals = np.empty(1)
28
+ dummy_param = -999
29
+
30
+ def __str__(self):
31
+ return "LiangWuNoblesseGF()"
32
+
33
+ def __repr__(self):
34
+ return "LiangWuNoblesseGF()"
35
+
36
+ def _repr_pretty_(self, p, cycle):
37
+ p.text(self.__repr__())
38
+
39
+ def evaluate(self,
40
+ mesh1, mesh2,
41
+ free_surface=0.0, water_depth=np.inf, wavenumber=1.0,
42
+ adjoint_double_layer=True, early_dot_product=True
43
+ ):
44
+
45
+ if free_surface == np.inf or water_depth < np.inf:
46
+ raise NotImplementedError("LiangWuNoblesseGF() is only implemented for infinite depth with a free surface")
47
+
48
+ if wavenumber == np.inf:
49
+ gf_singularities_index = self.fortran_core.constants.high_freq
50
+ else:
51
+ gf_singularities_index = self.fortran_core.constants.low_freq
52
+
53
+ collocation_points, early_dot_product_normals = \
54
+ self._get_colocation_points_and_normals(mesh1, mesh2, adjoint_double_layer)
55
+
56
+ S, K = self._init_matrices(
57
+ (collocation_points.shape[0], mesh2.nb_faces), early_dot_product=early_dot_product
58
+ )
59
+
60
+ self.fortran_core.matrices.build_matrices(
61
+ collocation_points, early_dot_product_normals,
62
+ mesh2.vertices, mesh2.faces + 1,
63
+ mesh2.faces_centers, mesh2.faces_normals,
64
+ mesh2.faces_areas, mesh2.faces_radiuses,
65
+ *mesh2.quadrature_points,
66
+ wavenumber, np.inf,
67
+ self.tabulation_nb_integration_points, self.tabulation_grid_shape_index,
68
+ self.tabulated_r_range, self.tabulated_z_range, self.tabulated_integrals,
69
+ self.dummy_param, self.prony_decomposition, self.dispersion_relation_roots,
70
+ gf_singularities_index, adjoint_double_layer,
71
+ S, K
72
+ )
73
+
74
+ if mesh1 is mesh2:
75
+ self.fortran_core.matrices.add_diagonal_term(
76
+ mesh2.faces_centers, early_dot_product_normals, free_surface, K,
77
+ )
78
+
79
+ if np.any(np.isnan(S)) or np.any(np.isnan(K)):
80
+ raise GreenFunctionEvaluationError(
81
+ "Green function returned a NaN in the interaction matrix.\n"
82
+ "It could be due to overlapping panels.")
83
+
84
+ if early_dot_product:
85
+ K = K.reshape((collocation_points.shape[0], mesh2.nb_faces))
86
+
87
+ return S, K
88
+
89
+
90
+ class FinGreen3D(AbstractGreenFunction):
91
+ """Wrapper for the Fortran implementation of the finite depth Green function of [Liu et al.].
92
+
93
+ Uses the same implementation as Delhommeau() for the Rankine and reflected Rankine terms.
94
+
95
+ """
96
+ floating_point_precision = "float64"
97
+
98
+ fortran_core = import_module("capytaine.green_functions.libs.Delhommeau_float64")
99
+ finite_depth_method_index = fortran_core.constants.fingreen3d_method
100
+ gf_singularities_index = fortran_core.constants.low_freq
101
+
102
+ # Dummy arrays that won't actually be used by the fortran code.
103
+ prony_decomposition = np.zeros((1, 1))
104
+ tabulation_nb_integration_points = 1
105
+ tabulated_r_range = np.empty(1)
106
+ tabulated_z_range = np.empty(1)
107
+ tabulated_integrals = np.empty(1)
108
+ dummy_param = -999
109
+
110
+ def __init__(self, *, nb_dispersion_roots=200):
111
+ self.nb_dispersion_roots = nb_dispersion_roots
112
+ self.exportable_settings = {
113
+ 'green_function': "FinGreen3D",
114
+ 'nb_dispersion_roots': nb_dispersion_roots
115
+ }
116
+
117
+ def __str__(self):
118
+ return f"FinGreen3D(nb_dispersion_roots={self.nb_dispersion_roots})"
119
+
120
+ def __repr__(self):
121
+ return f"FinGreen3D(nb_dispersion_roots={self.nb_dispersion_roots})"
122
+
123
+ def _repr_pretty_(self, p, cycle):
124
+ p.text(self.__repr__())
125
+
126
+ def compute_dispersion_relation_roots(self, nk, wavenumber, depth):
127
+ omega2_h_over_g = wavenumber*np.tanh(wavenumber*depth)*depth
128
+ def root(i_root):
129
+ return brentq(lambda y: omega2_h_over_g + y*np.tan(y), (2*i_root+1)*np.pi/2 + 1e-10, (2*i_root+2)*np.pi/2 - 1e-10)/depth
130
+ return np.array([wavenumber] + [root(i_root) for i_root in range(nk-1)])
131
+
132
+ def evaluate(self, mesh1, mesh2, free_surface, water_depth, wavenumber, adjoint_double_layer=True, early_dot_product=True):
133
+
134
+ if free_surface == np.inf or water_depth == np.inf:
135
+ raise NotImplementedError("FinGreen3D is only implemented for finite depth with a free surface.")
136
+ if wavenumber == 0.0 or wavenumber == np.inf:
137
+ raise NotImplementedError("FinGreen3D is only implemented for non-zero and non-infinite frequencies")
138
+
139
+ dispersion_relation_roots = self.compute_dispersion_relation_roots(
140
+ self.nb_dispersion_roots,
141
+ wavenumber,
142
+ water_depth
143
+ )
144
+
145
+ collocation_points, early_dot_product_normals = \
146
+ self._get_colocation_points_and_normals(mesh1, mesh2, adjoint_double_layer)
147
+
148
+ S, K = self._init_matrices(
149
+ (collocation_points.shape[0], mesh2.nb_faces), early_dot_product=early_dot_product
150
+ )
151
+
152
+ self.fortran_core.matrices.build_matrices(
153
+ collocation_points, early_dot_product_normals,
154
+ mesh2.vertices, mesh2.faces + 1,
155
+ mesh2.faces_centers, mesh2.faces_normals,
156
+ mesh2.faces_areas, mesh2.faces_radiuses,
157
+ *mesh2.quadrature_points,
158
+ wavenumber, water_depth,
159
+ self.tabulation_nb_integration_points, self.dummy_param,
160
+ self.tabulated_r_range, self.tabulated_z_range, self.tabulated_integrals,
161
+ self.finite_depth_method_index, self.prony_decomposition, dispersion_relation_roots,
162
+ self.gf_singularities_index, adjoint_double_layer,
163
+ S, K
164
+ )
165
+
166
+ if mesh1 is mesh2:
167
+ self.fortran_core.matrices.add_diagonal_term(
168
+ mesh2.faces_centers, early_dot_product_normals, free_surface, K,
169
+ )
170
+
171
+ if np.any(np.isnan(S)) or np.any(np.isnan(K)):
172
+ raise GreenFunctionEvaluationError(
173
+ "Green function returned a NaN in the interaction matrix.\n"
174
+ "It could be due to overlapping panels.")
175
+
176
+ if early_dot_product:
177
+ K = K.reshape((collocation_points.shape[0], mesh2.nb_faces))
178
+
179
+ return S, K
180
+
181
+
182
+ class HAMS_GF(AbstractGreenFunction):
183
+ floating_point_precision = "float64"
184
+
185
+ exportable_settings = {'green_function': "HAMS_GF"}
186
+
187
+ def __init__(self):
188
+ self.infinite_depth_gf = LiangWuNoblesseGF()
189
+ self.finite_depth_gf = FinGreen3D(nb_dispersion_roots=200)
190
+
191
+ def __str__(self):
192
+ return "HAMS_GF()"
193
+
194
+ def __repr__(self):
195
+ return "HAMS_GF()"
196
+
197
+ def _repr_pretty_(self, p, cycle):
198
+ p.text(self.__repr__())
199
+
200
+ def evaluate(self, mesh1, mesh2, free_surface, water_depth, wavenumber, adjoint_double_layer=True, early_dot_product=True):
201
+ if water_depth == np.inf:
202
+ return self.infinite_depth_gf.evaluate(mesh1, mesh2, free_surface, water_depth, wavenumber, adjoint_double_layer, early_dot_product)
203
+ else:
204
+ return self.finite_depth_gf.evaluate(mesh1, mesh2, free_surface, water_depth, wavenumber, adjoint_double_layer, early_dot_product)
capytaine/io/bemio.py CHANGED
@@ -37,8 +37,7 @@ def dataframe_from_bemio(bemio_obj, wavenumber, wavelength):
37
37
  if bemio_obj.body[i].water_depth == 'infinite':
38
38
  bemio_obj.body[i].water_depth = np.inf
39
39
 
40
- if bemio_obj.body[i].bem_code == 'WAMIT': # WAMIT coefficients need to be dimensionalized
41
- from_wamit = True
40
+ from_wamit = (bemio_obj.body[i].bem_code == 'WAMIT') # WAMIT coefficients need to be dimensionalized
42
41
 
43
42
  for omega_idx, omega in enumerate(np.sort(bemio_obj.body[i].w)):
44
43
 
@@ -48,10 +47,13 @@ def dataframe_from_bemio(bemio_obj, wavenumber, wavelength):
48
47
  temp_dict['body_name'] = bemio_obj.body[i].name
49
48
  temp_dict['water_depth'] = bemio_obj.body[i].water_depth
50
49
  temp_dict['omega'] = omega
50
+ temp_dict['freq'] = omega/(2*np.pi)
51
51
  temp_dict['period'] = 2*np.pi/omega
52
52
  temp_dict['rho'] = rho
53
53
  temp_dict['g'] = g
54
+ temp_dict['kind'] = "DiffractionResult"
54
55
  temp_dict['forward_speed'] = 0.0
56
+ temp_dict['free_surface'] = 0.0
55
57
  temp_dict['wave_direction'] = np.radians(dir)
56
58
  temp_dict['influenced_dof'] = dofs
57
59
 
@@ -102,8 +104,11 @@ def dataframe_from_bemio(bemio_obj, wavenumber, wavelength):
102
104
  temp_dict['body_name'] = bemio_obj.body[i].name
103
105
  temp_dict['water_depth'] = bemio_obj.body[i].water_depth
104
106
  temp_dict['omega'] = omega
107
+ temp_dict['freq'] = omega/(2*np.pi)
105
108
  temp_dict['rho'] = rho
106
109
  temp_dict['g'] = g
110
+ temp_dict['kind'] = "RadiationResult"
111
+ temp_dict['free_surface'] = 0.0
107
112
  temp_dict['forward_speed'] = 0.0
108
113
  temp_dict['wave_direction'] = 0.0
109
114
  temp_dict['influenced_dof'] = dofs
@@ -138,4 +143,11 @@ def dataframe_from_bemio(bemio_obj, wavenumber, wavelength):
138
143
  ])
139
144
  df = df.astype({'added_mass': np.float64, 'radiation_damping': np.float64, 'diffraction_force': np.complex128, 'Froude_Krylov_force': np.complex128})
140
145
 
146
+ all_dofs_in_order = ['Surge', 'Sway', 'Heave', 'Roll', 'Pitch', 'Yaw']
147
+ inf_dof_cat = pd.CategoricalDtype(categories=all_dofs_in_order)
148
+ df["influenced_dof"] = df["influenced_dof"].astype(inf_dof_cat)
149
+ if 'added_mass' in df.columns:
150
+ rad_dof_cat = pd.CategoricalDtype(categories=all_dofs_in_order)
151
+ df["radiating_dof"] = df["radiating_dof"].astype(rad_dof_cat)
152
+
141
153
  return df
@@ -721,6 +721,7 @@ def load_GDF(filename, name=None):
721
721
  npan = int(gdf_file.readline().split()[0])
722
722
  faces_vertices = np.genfromtxt(gdf_file)
723
723
 
724
+ faces_vertices = faces_vertices.reshape(-1, 3)
724
725
  vertices, indices = np.unique(faces_vertices, axis=0, return_inverse=True)
725
726
  faces = indices.reshape(-1, 4)
726
727
 
@@ -913,7 +914,7 @@ def load_MED(filename, name=None):
913
914
  if nb_quadrangles == 0:
914
915
  quadrangles = np.zeros((0, 4), dtype=int)
915
916
 
916
- faces = np.row_stack([triangles, quadrangles])
917
+ faces = np.vstack([triangles, quadrangles])
917
918
 
918
919
  return Mesh(vertices, faces, name=name)
919
920