capytaine 2.1__cp39-cp39-win_amd64.whl → 2.2.1__cp39-cp39-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.
- capytaine/__about__.py +1 -1
- capytaine/__init__.py +10 -7
- capytaine/bem/engines.py +2 -2
- capytaine/bem/problems_and_results.py +17 -9
- capytaine/bem/solver.py +71 -28
- capytaine/bodies/bodies.py +133 -24
- capytaine/green_functions/delhommeau.py +103 -51
- capytaine/green_functions/libs/Delhommeau_float32.cp39-win_amd64.dll.a +0 -0
- capytaine/green_functions/libs/Delhommeau_float32.cp39-win_amd64.pyd +0 -0
- capytaine/green_functions/libs/Delhommeau_float64.cp39-win_amd64.dll.a +0 -0
- capytaine/green_functions/libs/Delhommeau_float64.cp39-win_amd64.pyd +0 -0
- capytaine/io/mesh_loaders.py +49 -24
- capytaine/io/meshio.py +4 -1
- capytaine/io/xarray.py +17 -7
- capytaine/matrices/block.py +4 -2
- capytaine/matrices/linear_solvers.py +2 -3
- capytaine/matrices/low_rank.py +3 -1
- capytaine/meshes/clipper.py +3 -3
- capytaine/meshes/collections.py +13 -2
- capytaine/meshes/meshes.py +128 -4
- capytaine/meshes/predefined/cylinders.py +2 -2
- capytaine/meshes/properties.py +77 -0
- capytaine/post_pro/rao.py +1 -1
- capytaine/tools/cache_on_disk.py +3 -1
- capytaine/tools/symbolic_multiplication.py +23 -4
- capytaine/ui/vtk/body_viewer.py +2 -0
- capytaine-2.2.1.dist-info/DELVEWHEEL +2 -0
- capytaine-2.2.1.dist-info/METADATA +754 -0
- {capytaine-2.1.dist-info → capytaine-2.2.1.dist-info}/RECORD +33 -37
- capytaine/green_functions/libs/XieDelhommeau_float32.cp39-win_amd64.dll.a +0 -0
- capytaine/green_functions/libs/XieDelhommeau_float32.cp39-win_amd64.pyd +0 -0
- capytaine/green_functions/libs/XieDelhommeau_float64.cp39-win_amd64.dll.a +0 -0
- capytaine/green_functions/libs/XieDelhommeau_float64.cp39-win_amd64.pyd +0 -0
- capytaine-2.1.dist-info/DELVEWHEEL +0 -2
- capytaine-2.1.dist-info/METADATA +0 -756
- {capytaine-2.1.dist-info → capytaine-2.2.1.dist-info}/LICENSE +0 -0
- {capytaine-2.1.dist-info → capytaine-2.2.1.dist-info}/WHEEL +0 -0
- {capytaine-2.1.dist-info → capytaine-2.2.1.dist-info}/entry_points.txt +0 -0
- capytaine.libs/{.load-order-capytaine-2.1 → .load-order-capytaine-2.2.1} +2 -2
capytaine/__about__.py
CHANGED
|
@@ -5,7 +5,7 @@ __all__ = ["__title__", "__description__", "__version__", "__author__", "__uri__
|
|
|
5
5
|
__title__ = "capytaine"
|
|
6
6
|
__description__ = """Python BEM solver for linear potential flow, based on Nemoh"""
|
|
7
7
|
|
|
8
|
-
__version__ = "2.1"
|
|
8
|
+
__version__ = "2.2.1"
|
|
9
9
|
|
|
10
10
|
__author__ = "Matthieu Ancellin"
|
|
11
11
|
__uri__ = "https://github.com/capytaine/capytaine"
|
capytaine/__init__.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
# start delvewheel patch
|
|
6
|
-
def
|
|
6
|
+
def _delvewheel_patch_1_9_0():
|
|
7
7
|
import ctypes
|
|
8
8
|
import os
|
|
9
9
|
import platform
|
|
@@ -14,19 +14,22 @@ def _delvewheel_patch_1_5_4():
|
|
|
14
14
|
if os.path.isdir(libs_dir):
|
|
15
15
|
os.add_dll_directory(libs_dir)
|
|
16
16
|
else:
|
|
17
|
-
load_order_filepath = os.path.join(libs_dir, '.load-order-capytaine-2.1')
|
|
17
|
+
load_order_filepath = os.path.join(libs_dir, '.load-order-capytaine-2.2.1')
|
|
18
18
|
if os.path.isfile(load_order_filepath):
|
|
19
|
-
|
|
19
|
+
import ctypes.wintypes
|
|
20
|
+
with open(os.path.join(libs_dir, '.load-order-capytaine-2.2.1')) as file:
|
|
20
21
|
load_order = file.read().split()
|
|
22
|
+
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
|
|
23
|
+
kernel32.LoadLibraryExW.restype = ctypes.wintypes.HMODULE
|
|
24
|
+
kernel32.LoadLibraryExW.argtypes = ctypes.wintypes.LPCWSTR, ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD
|
|
21
25
|
for lib in load_order:
|
|
22
26
|
lib_path = os.path.join(os.path.join(libs_dir, lib))
|
|
23
|
-
|
|
24
|
-
if os.path.isfile(lib_path) and not kernel32.LoadLibraryExW(ctypes.c_wchar_p(lib_path), None, 0x00000008):
|
|
27
|
+
if os.path.isfile(lib_path) and not kernel32.LoadLibraryExW(lib_path, None, 8):
|
|
25
28
|
raise OSError('Error loading {}; {}'.format(lib, ctypes.FormatError(ctypes.get_last_error())))
|
|
26
29
|
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
del
|
|
31
|
+
_delvewheel_patch_1_9_0()
|
|
32
|
+
del _delvewheel_patch_1_9_0
|
|
30
33
|
# end delvewheel patch
|
|
31
34
|
|
|
32
35
|
from .__about__ import (
|
capytaine/bem/engines.py
CHANGED
|
@@ -123,10 +123,10 @@ class BasicMatrixEngine(MatrixEngine):
|
|
|
123
123
|
|
|
124
124
|
S_a, V_a = self.build_matrices(
|
|
125
125
|
mesh1[0], mesh2[0], free_surface, water_depth, wavenumber,
|
|
126
|
-
green_function)
|
|
126
|
+
green_function, adjoint_double_layer=adjoint_double_layer)
|
|
127
127
|
S_b, V_b = self.build_matrices(
|
|
128
128
|
mesh1[0], mesh2[1], free_surface, water_depth, wavenumber,
|
|
129
|
-
green_function)
|
|
129
|
+
green_function, adjoint_double_layer=adjoint_double_layer)
|
|
130
130
|
|
|
131
131
|
return BlockSymmetricToeplitzMatrix([[S_a, S_b]]), BlockSymmetricToeplitzMatrix([[V_a, V_b]])
|
|
132
132
|
|
|
@@ -193,7 +193,7 @@ class LinearPotentialFlowProblem:
|
|
|
193
193
|
or len(self.body.mesh.faces) == 0):
|
|
194
194
|
raise ValueError(f"The mesh of the body {self.body.__short_str__()} is empty.")
|
|
195
195
|
|
|
196
|
-
panels_above_fs = self.body.mesh.faces_centers[:, 2] >= self.free_surface
|
|
196
|
+
panels_above_fs = self.body.mesh.faces_centers[:, 2] >= self.free_surface + 1e-8
|
|
197
197
|
panels_below_sb = self.body.mesh.faces_centers[:, 2] <= -self.water_depth
|
|
198
198
|
if (any(panels_above_fs) or any(panels_below_sb)):
|
|
199
199
|
|
|
@@ -218,7 +218,7 @@ class LinearPotentialFlowProblem:
|
|
|
218
218
|
if len(self.boundary_condition.shape) != 1:
|
|
219
219
|
raise ValueError(f"Expected a 1-dimensional array as boundary_condition. Provided boundary condition's shape: {self.boundary_condition.shape}.")
|
|
220
220
|
|
|
221
|
-
if self.boundary_condition.shape[0] != self.body.
|
|
221
|
+
if self.boundary_condition.shape[0] != self.body.mesh_including_lid.nb_faces:
|
|
222
222
|
raise ValueError(
|
|
223
223
|
f"The shape of the boundary condition ({self.boundary_condition.shape})"
|
|
224
224
|
f"does not match the number of faces of the mesh ({self.body.mesh.nb_faces})."
|
|
@@ -256,7 +256,7 @@ class LinearPotentialFlowProblem:
|
|
|
256
256
|
def __str__(self):
|
|
257
257
|
"""Do not display default values in str(problem)."""
|
|
258
258
|
parameters = [f"body={self.body.__short_str__() if self.body is not None else None}",
|
|
259
|
-
f"{self.provided_freq_type}={self.__getattribute__(self.provided_freq_type):.3f}",
|
|
259
|
+
f"{self.provided_freq_type}={float(self.__getattribute__(self.provided_freq_type)):.3f}",
|
|
260
260
|
f"water_depth={self.water_depth}"]
|
|
261
261
|
|
|
262
262
|
if not self.forward_speed == _default_parameters['forward_speed']:
|
|
@@ -345,7 +345,7 @@ class DiffractionProblem(LinearPotentialFlowProblem):
|
|
|
345
345
|
forward_speed=forward_speed, rho=rho, g=g)
|
|
346
346
|
|
|
347
347
|
if float(self.omega) in {0.0, np.inf}:
|
|
348
|
-
raise NotImplementedError(
|
|
348
|
+
raise NotImplementedError("DiffractionProblem does not support zero or infinite frequency.")
|
|
349
349
|
|
|
350
350
|
if self.body is not None:
|
|
351
351
|
|
|
@@ -356,6 +356,9 @@ class DiffractionProblem(LinearPotentialFlowProblem):
|
|
|
356
356
|
# Note that even with forward speed, this is computed based on the
|
|
357
357
|
# frequency and not the encounter frequency.
|
|
358
358
|
|
|
359
|
+
if self.body.lid_mesh is not None:
|
|
360
|
+
self.boundary_condition = np.concatenate([self.boundary_condition, np.zeros(self.body.lid_mesh.nb_faces)])
|
|
361
|
+
|
|
359
362
|
if len(self.body.dofs) == 0:
|
|
360
363
|
LOG.warning(f"The body {self.body.name} used in diffraction problem has no dofs!")
|
|
361
364
|
|
|
@@ -398,10 +401,9 @@ class RadiationProblem(LinearPotentialFlowProblem):
|
|
|
398
401
|
self.radiating_dof = next(iter(self.body.dofs))
|
|
399
402
|
|
|
400
403
|
if self.radiating_dof not in self.body.dofs:
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
raise ValueError("Unrecognized degree of freedom name.")
|
|
404
|
+
raise ValueError(f"In {self}:\n"
|
|
405
|
+
f"the radiating dof {repr(self.radiating_dof)} is not one of the degrees of freedom of the body.\n"
|
|
406
|
+
f"The dofs of the body are {list(self.body.dofs.keys())}")
|
|
405
407
|
|
|
406
408
|
dof = self.body.dofs[self.radiating_dof]
|
|
407
409
|
|
|
@@ -422,6 +424,9 @@ class RadiationProblem(LinearPotentialFlowProblem):
|
|
|
422
424
|
)
|
|
423
425
|
self.boundary_condition += self.forward_speed * ddofdx_dot_n
|
|
424
426
|
|
|
427
|
+
if self.body.lid_mesh is not None:
|
|
428
|
+
self.boundary_condition = np.concatenate([self.boundary_condition, np.zeros(self.body.lid_mesh.nb_faces)])
|
|
429
|
+
|
|
425
430
|
|
|
426
431
|
def _astuple(self):
|
|
427
432
|
return super()._astuple() + (self.radiating_dof,)
|
|
@@ -524,7 +529,10 @@ class RadiationResult(LinearPotentialFlowResult):
|
|
|
524
529
|
|
|
525
530
|
@property
|
|
526
531
|
def radiation_damping(self):
|
|
527
|
-
|
|
532
|
+
if float(self.encounter_omega) in {0.0, np.inf} and self.forward_speed == 0.0:
|
|
533
|
+
return {dof: 0.0 for dof in self.forces.keys()}
|
|
534
|
+
else:
|
|
535
|
+
return {dof: float(np.imag(force)/self.encounter_omega) for (dof, force) in self.forces.items()}
|
|
528
536
|
|
|
529
537
|
# Aliases for backward compatibility
|
|
530
538
|
added_masses = added_mass
|
capytaine/bem/solver.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# Copyright (C) 2017-
|
|
2
|
-
# See LICENSE file at <https://github.com/
|
|
1
|
+
# Copyright (C) 2017-2024 Matthieu Ancellin
|
|
2
|
+
# See LICENSE file at <https://github.com/capytaine/capytaine>
|
|
3
3
|
"""Solver for the BEM problem.
|
|
4
4
|
|
|
5
5
|
.. code-block:: python
|
|
@@ -83,8 +83,9 @@ class BEMSolver:
|
|
|
83
83
|
keep_details: bool, optional
|
|
84
84
|
if True, store the sources and the potential on the floating body in the output object
|
|
85
85
|
(default: True)
|
|
86
|
-
_check_wavelength: bool, optional
|
|
87
|
-
|
|
86
|
+
_check_wavelength: bool, optional (default: True)
|
|
87
|
+
If True, the frequencies are compared to the mesh resolution and
|
|
88
|
+
the estimated first irregular frequency to warn the user.
|
|
88
89
|
|
|
89
90
|
Returns
|
|
90
91
|
-------
|
|
@@ -93,7 +94,9 @@ class BEMSolver:
|
|
|
93
94
|
"""
|
|
94
95
|
LOG.info("Solve %s.", problem)
|
|
95
96
|
|
|
96
|
-
if _check_wavelength:
|
|
97
|
+
if _check_wavelength:
|
|
98
|
+
self._check_wavelength_and_mesh_resolution([problem])
|
|
99
|
+
self._check_wavelength_and_irregular_frequencies([problem])
|
|
97
100
|
|
|
98
101
|
if problem.forward_speed != 0.0:
|
|
99
102
|
omega, wavenumber = problem.encounter_omega, problem.encounter_wavenumber
|
|
@@ -106,7 +109,7 @@ class BEMSolver:
|
|
|
106
109
|
raise NotImplementedError("Direct solver is not able to solve problems with forward speed.")
|
|
107
110
|
|
|
108
111
|
S, D = self.engine.build_matrices(
|
|
109
|
-
problem.body.
|
|
112
|
+
problem.body.mesh_including_lid, problem.body.mesh_including_lid,
|
|
110
113
|
problem.free_surface, problem.water_depth, wavenumber,
|
|
111
114
|
self.green_function, adjoint_double_layer=False
|
|
112
115
|
)
|
|
@@ -116,7 +119,7 @@ class BEMSolver:
|
|
|
116
119
|
sources = None
|
|
117
120
|
else:
|
|
118
121
|
S, K = self.engine.build_matrices(
|
|
119
|
-
problem.body.
|
|
122
|
+
problem.body.mesh_including_lid, problem.body.mesh_including_lid,
|
|
120
123
|
problem.free_surface, problem.water_depth, wavenumber,
|
|
121
124
|
self.green_function, adjoint_double_layer=True
|
|
122
125
|
)
|
|
@@ -127,10 +130,11 @@ class BEMSolver:
|
|
|
127
130
|
if problem.forward_speed != 0.0:
|
|
128
131
|
result = problem.make_results_container(sources=sources)
|
|
129
132
|
# Temporary result object to compute the ∇Φ term
|
|
130
|
-
nabla_phi = self._compute_potential_gradient(problem.body.
|
|
133
|
+
nabla_phi = self._compute_potential_gradient(problem.body.mesh_including_lid, result)
|
|
131
134
|
pressure += problem.rho * problem.forward_speed * nabla_phi[:, 0]
|
|
132
135
|
|
|
133
|
-
|
|
136
|
+
pressure_on_hull = pressure[:problem.body.mesh.nb_faces] # Discards pressure on lid if any
|
|
137
|
+
forces = problem.body.integrate_pressure(pressure_on_hull)
|
|
134
138
|
|
|
135
139
|
if not keep_details:
|
|
136
140
|
result = problem.make_results_container(forces)
|
|
@@ -156,13 +160,18 @@ class BEMSolver:
|
|
|
156
160
|
By defaults: do not use joblib and solve sequentially.
|
|
157
161
|
progress_bar: bool, optional (default: True)
|
|
158
162
|
Display a progress bar while solving
|
|
163
|
+
_check_wavelength: bool, optional (default: True)
|
|
164
|
+
If True, the frequencies are compared to the mesh resolution and
|
|
165
|
+
the estimated first irregular frequency to warn the user.
|
|
159
166
|
|
|
160
167
|
Returns
|
|
161
168
|
-------
|
|
162
169
|
list of LinearPotentialFlowResult
|
|
163
170
|
the solved problems
|
|
164
171
|
"""
|
|
165
|
-
if _check_wavelength:
|
|
172
|
+
if _check_wavelength:
|
|
173
|
+
self._check_wavelength_and_mesh_resolution(problems)
|
|
174
|
+
self._check_wavelength_and_irregular_frequencies(problems)
|
|
166
175
|
|
|
167
176
|
if n_jobs == 1: # force sequential resolution
|
|
168
177
|
problems = sorted(problems)
|
|
@@ -184,33 +193,64 @@ class BEMSolver:
|
|
|
184
193
|
return results
|
|
185
194
|
|
|
186
195
|
@staticmethod
|
|
187
|
-
def
|
|
196
|
+
def _check_wavelength_and_mesh_resolution(problems):
|
|
188
197
|
"""Display a warning if some of the problems have a mesh resolution
|
|
189
198
|
that might not be sufficient for the given wavelength."""
|
|
199
|
+
LOG.debug("Check wavelength with mesh resolution.")
|
|
190
200
|
risky_problems = [pb for pb in problems
|
|
191
|
-
if pb.wavelength < pb.body.minimal_computable_wavelength]
|
|
201
|
+
if 0.0 < pb.wavelength < pb.body.minimal_computable_wavelength]
|
|
192
202
|
nb_risky_problems = len(risky_problems)
|
|
193
203
|
if nb_risky_problems == 1:
|
|
194
204
|
pb = risky_problems[0]
|
|
195
205
|
freq_type = risky_problems[0].provided_freq_type
|
|
196
206
|
freq = pb.__getattribute__(freq_type)
|
|
197
207
|
LOG.warning(f"Mesh resolution for {pb}:\n"
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
208
|
+
f"The resolution of the mesh of the body {pb.body.__short_str__()} might "
|
|
209
|
+
f"be insufficient for {freq_type}={freq}.\n"
|
|
210
|
+
"This warning appears because the largest panel of this mesh "
|
|
211
|
+
f"has radius {pb.body.mesh.faces_radiuses.max():.3f} > wavelength/8."
|
|
212
|
+
)
|
|
203
213
|
elif nb_risky_problems > 1:
|
|
204
214
|
freq_type = risky_problems[0].provided_freq_type
|
|
205
215
|
freqs = np.array([float(pb.__getattribute__(freq_type)) for pb in risky_problems])
|
|
206
216
|
LOG.warning(f"Mesh resolution for {nb_risky_problems} problems:\n"
|
|
207
|
-
|
|
217
|
+
"The resolution of the mesh might be insufficient "
|
|
208
218
|
f"for {freq_type} ranging from {freqs.min():.3f} to {freqs.max():.3f}.\n"
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
219
|
+
"This warning appears when the largest panel of this mesh "
|
|
220
|
+
"has radius > wavelength/8."
|
|
221
|
+
)
|
|
212
222
|
|
|
213
|
-
|
|
223
|
+
@staticmethod
|
|
224
|
+
def _check_wavelength_and_irregular_frequencies(problems):
|
|
225
|
+
"""Display a warning if some of the problems might encounter irregular frequencies."""
|
|
226
|
+
LOG.debug("Check wavelength with estimated irregular frequency.")
|
|
227
|
+
risky_problems = [pb for pb in problems
|
|
228
|
+
if pb.body.first_irregular_frequency_estimate(g=pb.g) < pb.omega < np.inf]
|
|
229
|
+
nb_risky_problems = len(risky_problems)
|
|
230
|
+
if nb_risky_problems >= 1:
|
|
231
|
+
if any(pb.body.lid_mesh is None for pb in problems):
|
|
232
|
+
recommendation = "Setting a lid for the floating body is recommended."
|
|
233
|
+
else:
|
|
234
|
+
recommendation = "The lid might need to be closer to the free surface."
|
|
235
|
+
if nb_risky_problems == 1:
|
|
236
|
+
pb = risky_problems[0]
|
|
237
|
+
freq_type = risky_problems[0].provided_freq_type
|
|
238
|
+
freq = pb.__getattribute__(freq_type)
|
|
239
|
+
LOG.warning(f"Irregular frequencies for {pb}:\n"
|
|
240
|
+
f"The body {pb.body.__short_str__()} might display irregular frequencies "
|
|
241
|
+
f"for {freq_type}={freq}.\n"
|
|
242
|
+
+ recommendation
|
|
243
|
+
)
|
|
244
|
+
elif nb_risky_problems > 1:
|
|
245
|
+
freq_type = risky_problems[0].provided_freq_type
|
|
246
|
+
freqs = np.array([float(pb.__getattribute__(freq_type)) for pb in risky_problems])
|
|
247
|
+
LOG.warning(f"Irregular frequencies for {nb_risky_problems} problems:\n"
|
|
248
|
+
"Irregular frequencies might be encountered "
|
|
249
|
+
f"for {freq_type} ranging from {freqs.min():.3f} to {freqs.max():.3f}.\n"
|
|
250
|
+
+ recommendation
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
def fill_dataset(self, dataset, bodies, *, method='indirect', n_jobs=1, _check_wavelength=True, **kwargs):
|
|
214
254
|
"""Solve a set of problems defined by the coordinates of an xarray dataset.
|
|
215
255
|
|
|
216
256
|
Parameters
|
|
@@ -227,6 +267,9 @@ class BEMSolver:
|
|
|
227
267
|
By defaults: do not use joblib and solve sequentially.
|
|
228
268
|
progress_bar: bool, optional (default: True)
|
|
229
269
|
Display a progress bar while solving
|
|
270
|
+
_check_wavelength: bool, optional (default: True)
|
|
271
|
+
If True, the frequencies are compared to the mesh resolution and
|
|
272
|
+
the estimated first irregular frequency to warn the user.
|
|
230
273
|
|
|
231
274
|
Returns
|
|
232
275
|
-------
|
|
@@ -236,12 +279,12 @@ class BEMSolver:
|
|
|
236
279
|
**self.exportable_settings}
|
|
237
280
|
problems = problems_from_dataset(dataset, bodies)
|
|
238
281
|
if 'theta' in dataset.coords:
|
|
239
|
-
results = self.solve_all(problems, keep_details=True, method=method, n_jobs=n_jobs)
|
|
282
|
+
results = self.solve_all(problems, keep_details=True, method=method, n_jobs=n_jobs, _check_wavelength=_check_wavelength)
|
|
240
283
|
kochin = kochin_data_array(results, dataset.coords['theta'])
|
|
241
284
|
dataset = assemble_dataset(results, attrs=attrs, **kwargs)
|
|
242
285
|
dataset.update(kochin)
|
|
243
286
|
else:
|
|
244
|
-
results = self.solve_all(problems, keep_details=False, method=method, n_jobs=n_jobs)
|
|
287
|
+
results = self.solve_all(problems, keep_details=False, method=method, n_jobs=n_jobs, _check_wavelength=_check_wavelength)
|
|
245
288
|
dataset = assemble_dataset(results, attrs=attrs, **kwargs)
|
|
246
289
|
return dataset
|
|
247
290
|
|
|
@@ -271,7 +314,7 @@ class BEMSolver:
|
|
|
271
314
|
They probably have not been stored by the solver because the option keep_details=True have not been set or the direct method has been used.
|
|
272
315
|
Please re-run the resolution with the indirect method and keep_details=True.""")
|
|
273
316
|
|
|
274
|
-
S, _ = self.green_function.evaluate(points, result.body.
|
|
317
|
+
S, _ = self.green_function.evaluate(points, result.body.mesh_including_lid, result.free_surface, result.water_depth, result.encounter_wavenumber)
|
|
275
318
|
potential = S @ result.sources # Sum the contributions of all panels in the mesh
|
|
276
319
|
return potential.reshape(output_shape)
|
|
277
320
|
|
|
@@ -283,7 +326,7 @@ class BEMSolver:
|
|
|
283
326
|
They probably have not been stored by the solver because the option keep_details=True have not been set.
|
|
284
327
|
Please re-run the resolution with this option.""")
|
|
285
328
|
|
|
286
|
-
_, gradG = self.green_function.evaluate(points, result.body.
|
|
329
|
+
_, gradG = self.green_function.evaluate(points, result.body.mesh_including_lid, result.free_surface, result.water_depth, result.encounter_wavenumber,
|
|
287
330
|
early_dot_product=False)
|
|
288
331
|
velocities = np.einsum('ijk,j->ik', gradG, result.sources) # Sum the contributions of all panels in the mesh
|
|
289
332
|
return velocities.reshape((*output_shape, 3))
|
|
@@ -409,7 +452,7 @@ class BEMSolver:
|
|
|
409
452
|
if chunk_size > mesh.nb_faces:
|
|
410
453
|
S = self.engine.build_S_matrix(
|
|
411
454
|
mesh,
|
|
412
|
-
result.body.
|
|
455
|
+
result.body.mesh_including_lid,
|
|
413
456
|
result.free_surface, result.water_depth, result.wavenumber,
|
|
414
457
|
self.green_function
|
|
415
458
|
)
|
|
@@ -421,7 +464,7 @@ class BEMSolver:
|
|
|
421
464
|
faces_to_extract = list(range(i, min(i+chunk_size, mesh.nb_faces)))
|
|
422
465
|
S = self.engine.build_S_matrix(
|
|
423
466
|
mesh.extract_faces(faces_to_extract),
|
|
424
|
-
result.body.
|
|
467
|
+
result.body.mesh_including_lid,
|
|
425
468
|
result.free_surface, result.water_depth, result.wavenumber,
|
|
426
469
|
self.green_function
|
|
427
470
|
)
|