def test_floating_sphere(reso, depth): full_sphere = generate_sphere(radius=1.0, ntheta=2*reso, nphi=4*reso, clip_free_surface=True) full_sphere.dofs["Heave"] = full_sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=full_sphere, omega=1.0, sea_bottom=-depth) mass1, damping1 = Nemoh().solve(problem) half_sphere = generate_half_sphere(radius=1.0, ntheta=reso, nphi=4*reso, clip_free_surface=True) # half_sphere = full_sphere.extract_faces(np.where(full_sphere.faces_centers[:, 1] > 0)[0]) two_halves_sphere = ReflectionSymmetry(half_sphere, xOz_Plane) two_halves_sphere.dofs["Heave"] = two_halves_sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=two_halves_sphere, omega=1.0, sea_bottom=-depth) mass2, damping2 = Nemoh().solve(problem) quarter_sphere = half_sphere.extract_faces(np.where(half_sphere.faces_centers[:, 0] > 0)[0]) four_quarter_sphere = ReflectionSymmetry(ReflectionSymmetry(quarter_sphere, yOz_Plane), xOz_Plane) four_quarter_sphere.dofs["Heave"] = four_quarter_sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=four_quarter_sphere, omega=1.0, sea_bottom=-depth) mass3, damping3 = Nemoh().solve(problem) clever_sphere = generate_clever_sphere(radius=1.0, ntheta=reso, nphi=4*reso, clip_free_surface=True) clever_sphere.dofs['Heave'] = clever_sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=clever_sphere, omega=1.0, sea_bottom=-depth) mass4, damping4 = Nemoh().solve(problem) # (quarter_sphere + half_sphere + full_sphere + clever_sphere).show() assert np.isclose(mass1, mass2, atol=1e-4*full_sphere.volume*problem.rho) assert np.isclose(damping1, damping2, atol=1e-4*full_sphere.volume*problem.rho) assert np.isclose(mass1, mass3, atol=1e-4*full_sphere.volume*problem.rho) assert np.isclose(damping1, damping3, atol=1e-4*full_sphere.volume*problem.rho) assert np.isclose(mass1, mass4, atol=1e-4*full_sphere.volume*problem.rho) assert np.isclose(damping1, damping4, atol=1e-4*full_sphere.volume*problem.rho)
def test_floating_sphere_finite_depth(): sphere = generate_sphere(radius=1.0, ntheta=6, nphi=12, clip_free_surface=True) sphere.dofs["Heave"] = sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=sphere, omega=1.0, sea_bottom=-10.0) mass, damping = Nemoh().solve(problem) assert np.isclose(mass, 1740.6, atol=1e-3 * sphere.volume * problem.rho) assert np.isclose(damping, 380.46, rtol=1e-3 * sphere.volume * problem.rho) problem = DiffractionProblem(body=sphere, omega=1.0, sea_bottom=-10.0) force = Nemoh().solve(problem) assert np.isclose(force, 1749.4 * np.exp(-2.922j) * -1j, rtol=1e-3)
def test_odd_axial_symmetry(): """Buoy with odd number of slices.""" def shape(z): return 0.1*(-(z+1)**2 + 16) buoy = generate_axi_symmetric_body(shape, z_range=np.linspace(-5.0, 0.0, 9), nphi=5) buoy.dofs['Heave'] = buoy.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=buoy, omega=2.0) mass1, damping1 = Nemoh().solve(problem) problem = RadiationProblem(body=buoy.as_FloatingBody(), omega=2.0) mass2, damping2 = Nemoh().solve(problem) assert np.isclose(mass1, mass2, atol=1e-4*buoy.volume*problem.rho) assert np.isclose(damping1, damping2, atol=1e-4*buoy.volume*problem.rho)
def test_horizontal_cylinder(depth): cylinder = generate_open_horizontal_cylinder(length=10.0, radius=1.0, ntheta=10, nx=10) cylinder.translate_z(-3.0) cylinder.dofs["Heave"] = cylinder.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=cylinder, omega=1.0, sea_bottom=-depth) mass1, damping1 = Nemoh().solve(problem) sym_cylinder = generate_clever_horizontal_cylinder(length=10.0, radius=1.0, ntheta=10, nx=10) sym_cylinder.translate_z(-3.0) sym_cylinder.dofs["Heave"] = sym_cylinder.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=sym_cylinder, omega=1.0, sea_bottom=-depth) mass2, damping2 = Nemoh().solve(problem) cylinder_volume = 10*1.0*2*np.pi assert np.isclose(mass1, mass2, atol=1e-4*cylinder_volume*problem.rho) assert np.isclose(damping1, damping2, atol=1e-4*cylinder_volume*problem.rho)
def test_floating_sphere_finite_freq(): sphere = generate_sphere(radius=1.0, ntheta=6, nphi=12, clip_free_surface=True) sphere.dofs["Heave"] = sphere.faces_normals @ (0, 0, 1) solver = Nemoh() problem = RadiationProblem(body=sphere, omega=1.0, sea_bottom=-np.infty) mass, damping = solver.solve(problem, keep_details=True) assert np.isclose(mass, 1819.6, atol=1e-3 * sphere.volume * problem.rho) assert np.isclose(damping, 379.39, atol=1e-3 * sphere.volume * problem.rho) free_surface = generate_free_surface(width=125, length=125, nw=5, nl=5) eta = solver.get_free_surface(problem, free_surface, dof="Heave") ref = np.array( [[ -0.4340802E-02 - 0.4742809E-03j, -0.7986111E-03 + 0.4840984E-02j, 0.2214827E-02 + 0.4700642E-02j, -0.7986111E-03 + 0.4840984E-02j, -0.4340803E-02 - 0.4742807E-03j ], [ -0.7986111E-03 + 0.4840984E-02j, 0.5733187E-02 - 0.2179381E-02j, 0.9460892E-03 - 0.7079404E-02j, 0.5733186E-02 - 0.2179381E-02j, -0.7986110E-03 + 0.4840984E-02j ], [ 0.2214827E-02 + 0.4700643E-02j, 0.9460892E-03 - 0.7079403E-02j, -0.1381670E-01 + 0.6039315E-01j, 0.9460892E-03 - 0.7079405E-02j, 0.2214827E-02 + 0.4700643E-02j ], [ -0.7986111E-03 + 0.4840984E-02j, 0.5733186E-02 - 0.2179381E-02j, 0.9460891E-03 - 0.7079404E-02j, 0.5733187E-02 - 0.2179380E-02j, -0.7986113E-03 + 0.4840984E-02j ], [ -0.4340803E-02 - 0.4742807E-03j, -0.7986111E-03 + 0.4840984E-02j, 0.2214827E-02 + 0.4700643E-02j, -0.7986113E-03 + 0.4840983E-02j, -0.4340803E-02 - 0.4742809E-03j ]]) assert np.allclose(eta.reshape((5, 5)), ref, rtol=1e-4) problem = DiffractionProblem(body=sphere, omega=1.0, sea_bottom=-np.infty) force = Nemoh().solve(problem) assert np.isclose(force, 1834.9 * np.exp(-2.933j) * -1j, rtol=1e-3)
def test_immersed_sphere(): sphere = generate_sphere(radius=1.0, ntheta=20, nphi=40) sphere.dofs["Heave"] = sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=sphere, free_surface=np.infty, sea_bottom=-np.infty) mass, damping = Nemoh().solve(problem) assert np.isclose(mass, 2187, atol=1e-3 * sphere.volume * problem.rho) assert np.isclose(damping, 0.0, atol=1e-3 * sphere.volume * problem.rho)
def profile_capytaine(body, omega_range, result_dir, **problem_kwargs): if not os.path.isdir(result_dir): os.makedirs(result_dir) os.environ["MKL_NUM_THREADS"] = "1" if logging.root: del logging.root.handlers[:] logging.basicConfig( filename=f"{result_dir}/capytaine.log", level=logging.DEBUG, format="%(levelname)s:\t%(message)s" ) pr = cProfile.Profile() pr.enable() #==Start profiler== problems = [RadiationProblem(body=body, omega=omega, **problem_kwargs) for omega in omega_range] solver = Nemoh() results = [solver.solve(pb) for pb in problems] pr.disable() #================= results = np.asarray(results) np.savetxt(f'{result_dir}/results.csv', results) s = io.StringIO() sortby = 'time' ps = pstats.Stats(pr, stream=s).sort_stats(sortby) ps.print_stats() profiler_results = s.getvalue() with open(f'{result_dir}/profile.log', 'w') as log: log.write(profiler_results) os.environ["MKL_NUM_THREADS"] = "4" return float(profiler_results.split('\n')[0].split('in')[1].strip('seconds\n'))
def test_alien_sphere(): sphere = generate_sphere(radius=1.0, ntheta=6, nphi=12, clip_free_surface=True) sphere.dofs["Heave"] = sphere.faces_normals @ (0, 0, 1) problem = RadiationProblem(body=sphere, rho=450.0, g=1.625, omega=1.0, sea_bottom=-np.infty) mass, damping = Nemoh().solve(problem) assert np.isclose(mass, 515, atol=1e-3 * sphere.volume * problem.rho) assert np.isclose(damping, 309, atol=1e-3 * sphere.volume * problem.rho) problem = DiffractionProblem(body=sphere, rho=450.0, g=1.625, omega=1.0, sea_bottom=-np.infty) force = Nemoh().solve(problem) assert np.isclose(force, 548.5 * np.exp(-2.521j) * -1j, rtol=1e-2)
def test_multibody(): sphere = generate_sphere(radius=1.0, ntheta=10, nphi=20) sphere.translate_z(-2.0) sphere.dofs["Surge"] = sphere.faces_normals @ (1, 0, 0) sphere.dofs["Heave"] = sphere.faces_normals @ (0, 0, 1) cylinder = generate_horizontal_cylinder(length=5.0, radius=1.0, nx=10, nr=1, ntheta=10) cylinder.translate([-1.0, 3.0, -3.0]) cylinder.dofs["Surge"] = cylinder.faces_normals @ (1, 0, 0) cylinder.dofs["Heave"] = cylinder.faces_normals @ (0, 0, 1) both = cylinder + sphere # both.show() problem = RadiationProblem(body=both, omega=1.0, free_surface=0.0, sea_bottom=-np.infty) mass, damping = Nemoh().solve(problem) Nemoh_2 = np.array([ [ 3961.86548, 50.0367661, -3.32347107, 6.36901855E-02, 172.704819, 19.2018471, -5.67303181, -2.98873377 ], [ -3.08301544, 5.72392941E-02, 14522.1689, 271.796814, 128.413834, 6.03351116, 427.167358, 64.1587067 ], [ 161.125534, 17.8332844, 126.392113, 5.88006783, 2242.47412, 7.17850924, 1.29002571, 0.393169671 ], [ -5.02560759, -2.75930357, 419.927460, 63.3179016, 1.23501396, 0.416424811, 2341.57593, 15.8266096 ], ]) assert np.allclose(mass, Nemoh_2[:, ::2], atol=1e-3 * both.volume * problem.rho) assert np.allclose(damping, Nemoh_2[:, 1::2], atol=1e-3 * both.volume * problem.rho)
def test_panels(depth): panel = generate_one_sided_rectangle(height=1.0, width=1.0, nh=6, nw=2) panel.translate_z(-1.0) half_panel = panel.extract_faces(np.where(panel.faces_centers[:, 0] > 0)[0]) symmetric_panel = ReflectionSymmetry(half_panel, yOz_Plane) # symmetric_panel.show() # Next lines only to set up LISC in Nemoh's Core... problem = RadiationProblem(body=panel, omega=0.1, free_surface=0.0, sea_bottom=-depth) Nemoh().solve(problem) S1, V1 = panel.build_matrices(panel) S2, V2 = symmetric_panel.build_matrices(symmetric_panel) # import matplotlib.pyplot as plt # plt.matshow(np.real(S1), vmin=-0.1, vmax=0) # plt.colorbar() # plt.matshow(np.real(S2), vmin=-0.1, vmax=0) # plt.colorbar() # plt.show() assert np.allclose(S1, S2.full_matrix(), atol=1e-5) assert np.allclose(V1, V2.full_matrix(), atol=1e-5)
def solve_flap(clever=True, resolution=2): """Solve the flap problem for a given resolution. Parameters: resolution: int the number of cells in the mesh will be proportional to this coefficient """ # Load reference range of frequencies T_range, _, _ = np.loadtxt( os.path.join(os.path.dirname(__file__), "data/flap_mu_nu.tsv")).T depth = 10.9 # Create mesh if clever: # Use prismatic shape to speed up computations. flap = generate_clever_open_rectangular_parallelepiped( height=depth, width=3.0, thickness=0.001, nh=int(10 * resolution), nw=int(3 * resolution)) else: # Do not use prismatic shape to speed up computations. flap = generate_open_rectangular_parallelepiped(height=depth, width=3.0, thickness=0.001, nh=int(10 * resolution), nw=int(3 * resolution)) flap.translate_z(-depth) # Set oscillation degree of freedom flap.dofs["Oscillation"] = np.asarray([ flap.faces_normals[j, 1] * (flap.faces_centers[j, 2] + 9.4) * np.heaviside(flap.faces_centers[j, 2] + 9.4, 0.0) for j in range(flap.nb_faces) ]) # Set up problems and initialise solver problems = [ RadiationProblem(body=flap, omega=omega, sea_bottom=-depth) for omega in 2 * np.pi / T_range ] solver = Nemoh() # Solve problems results = np.asarray(solver.solve_all(problems, processes=1)) # Create directory to store results if not os.path.isdir(result_directory): os.mkdir(result_directory) # Save result in csv file result_file_path = os.path.join( os.path.dirname(__file__), "flap_results", f"Results_{'clever_' if clever else ''}{30*resolution**2}_cells.csv") if os.path.exists(result_file_path): LOG.warning(f"Overwriting {result_file_path}") np.savetxt(result_file_path, np.asarray(results))
#!/usr/bin/env python # coding: utf-8 """ """ import numpy as np import matplotlib.pyplot as plt from capytaine.reference_bodies import * from capytaine.symmetries import * from capytaine.Nemoh import Nemoh cylinder = generate_clever_horizontal_cylinder(length=10.0, radius=1.0, nx=5, ntheta=10) cylinder.translate_z(-2.0) # cylinder.show() solver = Nemoh() S, V = cylinder.build_matrices(cylinder, free_surface=np.infty) # S, V = cylinder.build_matrices(cylinder) plt.imshow(np.abs(V.full_matrix())) plt.colorbar() plt.title("$|V|$") plt.tight_layout() plt.show()
from capytaine.problems import DiffractionProblem from capytaine.Nemoh import Nemoh from matplotlib.patches import Circle # Set up logging logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s:\t%(message)s", datefmt="%H:%M:%S") # Initialize mesh and solver sphere = generate_clever_sphere(radius=5, ntheta=40, nphi=40, z0=-1.0, clip_free_surface=True) solver = Nemoh() # Solve diffraction problem problem = DiffractionProblem(body=sphere, angle=0.0, omega=2.0) results = solver.solve(problem, keep_details=True) # Compute free surface elevation fs_mesh = generate_free_surface(width=100.0, length=100.0, nw=100, nl=100) fs = solver.get_free_surface(problem, fs_mesh) # Add incoming waves fs = fs + 1j * problem.omega / problem.g * problem.Airy_wave_potential( fs_mesh.faces_centers) # Plot free surface elevation X = fs_mesh.faces_centers[:, 0].reshape(100, 100)
def shape(z): return 0.1 * (-(z + 1)**2 + 16) # buoy = generate_axi_symmetric_body( # profile=[[0, 0, -5], [1, 0, -4], [1.5, 0, -3], [2.0, 0, -2], [1.3, 0, -1], [0, 0, -0.5]] # ) buoy = generate_axi_symmetric_body(shape, z_range=np.linspace(-5.0, 0.0, 20), nphi=20) # buoy.show() buoy.dofs["Heave"] = buoy.faces_normals @ (0, 0, 1) solver = Nemoh() omega_range = np.linspace(0.1, 5.0, 40) problems = [ RadiationProblem(body=buoy, rho=rho, omega=omega) for omega in omega_range ] results = [solver.solve(pb) for pb in problems] results = np.array(results) plt.figure() plt.plot(omega_range, results[:, 0, 0, 0] / (rho * buoy.volume), label="Added mass") plt.plot(omega_range,