def test_cache_matrices(): """Test how the solver caches the interaction matrices.""" params_1 = dict(free_surface=0.0, sea_bottom=-np.infty, wavenumber=1.0) params_2 = dict(free_surface=0.0, sea_bottom=-np.infty, wavenumber=2.0) # No cache solver = Nemoh(matrix_cache_size=0) S, K = solver.build_matrices(sphere.mesh, sphere.mesh, **params_1) S_again, K_again = solver.build_matrices(sphere.mesh, sphere.mesh, **params_1) assert S is not S_again assert K is not K_again # Cache solver = Nemoh(matrix_cache_size=1) S, K = solver.build_matrices(sphere.mesh, sphere.mesh, **params_1) S_again, K_again = solver.build_matrices(sphere.mesh, sphere.mesh, **params_1) _, _ = solver.build_matrices(sphere.mesh, sphere.mesh, **params_2) S_once_more, K_once_more = solver.build_matrices(sphere.mesh, sphere.mesh, **params_1) assert S is S_again assert S is not S_once_more assert K is K_again assert K is not K_once_more
def test_array_of_spheres(): radius = 1.0 resolution = 2 perimeter = 2 * np.pi * radius buoy = Sphere(radius=radius, center=(0.0, 0.0, 0.0), ntheta=int(perimeter * resolution / 2), nphi=int(perimeter * resolution), clip_free_surface=True, clever=False, name=f"buoy") buoy.add_translation_dof(name="Surge") buoy.add_translation_dof(name="Sway") buoy.add_translation_dof(name="Heave") # Corner case dumb_array = buoy.assemble_regular_array(distance=5.0, nb_bodies=(1, 1)) assert dumb_array.mesh == buoy.mesh # Main case array = buoy.assemble_regular_array(distance=4.0, nb_bodies=(3, 3)) assert isinstance(array.mesh, TranslationalSymmetricMesh) assert isinstance(array.mesh[0], TranslationalSymmetricMesh) assert array.mesh[0][0] == buoy.mesh assert len(array.dofs) == 3 * 3 * 3 assert "2_0__Heave" in array.dofs # array = buoy.assemble_regular_array(distance=4.0, nb_bodies=(3, 1)) settings = dict(cache_rankine_matrices=False, matrix_cache_size=0) nemoh_without_sym = Nemoh(hierarchical_matrices=False, **settings) nemoh_with_sym = Nemoh(hierarchical_matrices=True, **settings) fullS, fullV = nemoh_without_sym.build_matrices(array.mesh, array.mesh, 0.0, -np.infty, 1.0) S, V = nemoh_with_sym.build_matrices(array.mesh, array.mesh, 0.0, -np.infty, 1.0) assert isinstance(S, cpt.matrices.block.BlockMatrix) assert np.allclose(S.full_matrix(), fullS) assert np.allclose(V.full_matrix(), fullV) problem = RadiationProblem(body=array, omega=1.0, radiating_dof="2_0__Heave", sea_bottom=-np.infty) result = nemoh_with_sym.solve(problem) result2 = nemoh_without_sym.solve(problem) assert np.isclose(result.added_masses['2_0__Heave'], result2.added_masses['2_0__Heave'], atol=15.0) assert np.isclose(result.radiation_dampings['2_0__Heave'], result2.radiation_dampings['2_0__Heave'], atol=15.0)
def test_fill_dataset_with_kochin_functions(): solver = Nemoh() test_matrix = xr.Dataset( coords={ 'omega': [1.0], 'theta': np.linspace(0, 2 * pi, 5), 'radiating_dof': list(sphere.dofs.keys()), }) ds = solver.fill_dataset(test_matrix, [sphere]) assert 'theta' in ds.coords assert 'kochin' in ds
def test_cache_rankine_matrices(): """Test how the solver caches the Rankine part of the interaction matrices.""" params_1 = dict(free_surface=0.0, sea_bottom=-np.infty, wavenumber=1.0) # No cache of rankine matrices solver = Nemoh(matrix_cache_size=1, cache_rankine_matrices=True) Sr, Vr = solver.build_matrices_rankine(sphere.mesh, sphere.mesh, **params_1) Sr_again, Vr_again = solver.build_matrices_rankine(sphere.mesh, sphere.mesh, **params_1) assert Sr is Sr_again assert Vr is Vr_again # Cache of rankine matrices solver = Nemoh(matrix_cache_size=1, cache_rankine_matrices=False) Sr, Vr = solver.build_matrices_rankine(sphere.mesh, sphere.mesh, **params_1) Sr_again, Vr_again = solver.build_matrices_rankine(sphere.mesh, sphere.mesh, **params_1) assert Sr is not Sr_again assert Vr is not Vr_again
def test_custom_linear_solver(): """Solve a simple problem with a custom linear solver.""" problem = RadiationProblem(body=sphere, omega=1.0, sea_bottom=-np.infty) reference_solver = Nemoh(linear_solver="gmres", matrix_cache_size=0, hierarchical_matrices=False) reference_result = reference_solver.solve(problem) def my_linear_solver(A, b): """A dumb solver for testing.""" return np.linalg.inv(A) @ b my_bem_solver = Nemoh(linear_solver=my_linear_solver, matrix_cache_size=0, hierarchical_matrices=False) assert 'my_linear_solver' in my_bem_solver.exportable_settings( )['linear_solver'] result = my_bem_solver.solve(problem) assert np.isclose(reference_result.added_masses['Surge'], result.added_masses['Surge'])
def test_limit_frequencies(): """Test if how the solver answers when asked for frequency of 0 or ∞.""" solver = Nemoh() solver.solve(RadiationProblem(body=sphere, omega=0.0, sea_bottom=-np.infty)) with pytest.raises(NotImplementedError): solver.solve(RadiationProblem(body=sphere, omega=0.0, sea_bottom=-1.0)) solver.solve( RadiationProblem(body=sphere, omega=np.infty, sea_bottom=-np.infty)) with pytest.raises(NotImplementedError): solver.solve( RadiationProblem(body=sphere, omega=np.infty, sea_bottom=-10))
def main(): args = parser.parse_args() for paramfile in args.paramfiles: problems = import_cal_file(paramfile) solver = Nemoh() results = [solver.solve(pb) for pb in problems] data = assemble_dataset(results) print(data) results_directory = os.path.join(os.path.dirname(paramfile), 'results') try: os.mkdir(results_directory) except FileExistsError: LOG.warning( "The 'results' directory already exists. You might be overwriting existing data." ) LOG.info("Write results in legacy tecplot format.") write_dataset_as_tecplot_files(results_directory, data)
def test_fill_dataset(): solver = Nemoh() test_matrix = xr.Dataset( coords={ 'omega': np.linspace(0.1, 4.0, 3), 'wave_direction': np.linspace(0.0, pi, 3), 'radiating_dof': list(sphere.dofs.keys()), 'rho': [1025.0], 'water_depth': [np.infty, 10.0] }) dataset = solver.fill_dataset(test_matrix, [sphere]) # Tests on the coordinates assert list(dataset.coords['influenced_dof']) == list( dataset.coords['radiating_dof']) == list(sphere.dofs.keys()) assert dataset.body_name == sphere.name assert dataset.rho == test_matrix.rho # Tests on the results assert 'added_mass' in dataset assert 'radiation_damping' in dataset assert 'Froude_Krylov_force' in dataset assert 'diffraction_force' in dataset # Test the attributes assert dataset.attrs['capytaine_version'] == __version__ assert 'start_of_computation' in dataset.attrs assert 'cache_rankine_matrices' in dataset.attrs assert 'incoming_waves_convention' in dataset.attrs # Try to strip out the outputs and recompute naked_data = dataset.drop([ "added_mass", "radiation_damping", "diffraction_force", "Froude_Krylov_force" ]) recomputed_dataset = solver.fill_dataset(naked_data, [sphere]) assert recomputed_dataset.rho == dataset.rho assert "added_mass" in recomputed_dataset assert np.allclose(recomputed_dataset["added_mass"].data, dataset["added_mass"].data)
def test_exportable_settings(): assert Nemoh().exportable_settings() == Nemoh.defaults_settings assert 'ACA_distance' not in Nemoh( hierarchical_matrices=False).exportable_settings() assert 'cache_rankine_matrices' not in Nemoh( matrix_cache_size=0).exportable_settings()
from capytaine.meshes.meshes import Mesh from capytaine.meshes.symmetric import ReflectionSymmetricMesh from capytaine.bodies import FloatingBody from capytaine.bodies.predefined.spheres import Sphere from capytaine.bodies.predefined.cylinders import HorizontalCylinder from capytaine.bem.problems_and_results import LinearPotentialFlowProblem, DiffractionProblem, RadiationProblem, \ LinearPotentialFlowResult, DiffractionResult, RadiationResult from capytaine.bem.nemoh import Nemoh from capytaine.io.xarray import problems_from_dataset from capytaine.io.legacy import import_cal_file solver = Nemoh(matrix_cache_size=0) def test_LinearPotentialFlowProblem(): # Without a body pb = LinearPotentialFlowProblem(omega=1.0) assert pb.omega == 1.0 assert pb.period == 2 * np.pi assert pb.wavenumber == 1.0 / 9.81 assert pb.wavelength == 9.81 * 2 * np.pi assert LinearPotentialFlowProblem(free_surface=np.infty, sea_bottom=-np.infty).depth == np.infty assert LinearPotentialFlowProblem(free_surface=0.0, sea_bottom=-np.infty).depth == np.infty
# coding: utf-8 """Quantitatively compare the results of Capytaine with the results from Nemoh 2.""" import numpy as np from capytaine.bodies.predefined.spheres import Sphere from capytaine.bodies.predefined.cylinders import HorizontalCylinder from capytaine.post_pro.free_surfaces import FreeSurface from capytaine.bem.problems_and_results import DiffractionProblem, RadiationProblem from capytaine.bem.nemoh import Nemoh from capytaine.io.xarray import assemble_dataset from capytaine.post_pro.kochin import compute_kochin solver = Nemoh(linear_solver='gmres', hierarchical_matrices=False, matrix_cache_size=0) def test_immersed_sphere(): """Compare with Nemoh 2.0 for a sphere in infinite fluid. The test is ran for two degrees of freedom; due to the symmetries of the problem, the results should be the same. They are actually slightly different due to the meshing of the sphere. """ sphere = Sphere(radius=1.0, ntheta=10, nphi=40, clip_free_surface=False) sphere.add_translation_dof(direction=(1, 0, 0), name="Surge") sphere.add_translation_dof(direction=(0, 0, 1), name="Heave") problem = RadiationProblem(body=sphere, radiating_dof="Heave",
from capytaine.meshes.symmetric import AxialSymmetricMesh, ReflectionSymmetricMesh, TranslationalSymmetricMesh from capytaine.bodies import FloatingBody from capytaine.bodies.predefined.spheres import Sphere from capytaine.bodies.predefined.cylinders import HorizontalCylinder, VerticalCylinder from capytaine.bem.problems_and_results import RadiationProblem from capytaine.bem.nemoh import Nemoh from capytaine.io.xarray import assemble_dataset from capytaine.meshes.geometry import xOz_Plane, yOz_Plane from capytaine.matrices.low_rank import LowRankMatrix solver_with_sym = Nemoh(hierarchical_matrices=True, ACA_distance=8, matrix_cache_size=0) solver_without_sym = Nemoh(hierarchical_matrices=False, ACA_distance=8, matrix_cache_size=0) # Use a single solver in the whole module to avoid reinitialisation of the solver (0.5 second). # Do not use a matrix cache in order not to risk influencing a test with another. @pytest.mark.parametrize("depth", [10.0, np.infty]) @pytest.mark.parametrize("omega", [0.1, 10.0]) def test_floating_sphere(depth, omega): """Comparison of the added mass and radiation damping for a heaving sphere described using several symmetries in finite and infinite depth. """