def prepare_problems(self): if MPI: n_cores = MPI.COMM_WORLD.Get_size() max_cores = min(n_cores, self.max_cores) rank = MPI.COMM_WORLD.Get_rank() else: n_cores = 1 max_cores = 1 rank = 0 if rank == 0: problems = [] if self.radiation: if self.zero_frequency: problems += [cpt.RadiationProblem( body=self._cpt_hydrobody, free_surface=0.0, sea_bottom=-np.infty, omega=0.0, rho=self.water_rho, g=self.grav, radiating_dof=dof ) for dof in self._cpt_hydrobody.dofs ] problems += [cpt.RadiationProblem( body=self._cpt_hydrobody, free_surface=0.0, sea_bottom=-self.water_depth, omega=omega, rho=self.water_rho, g=self.grav, radiating_dof=dof ) for dof in self._cpt_hydrobody.dofs for omega in self.omega_range ] if self.inf_frequency: problems += [cpt.RadiationProblem( body=self._cpt_hydrobody, free_surface=0.0, sea_bottom=-np.infty, omega=np.infty, rho=self.water_rho, g=self.grav, radiating_dof=dof ) for dof in self._cpt_hydrobody.dofs ] if self.diffraction: problems += [cpt.DiffractionProblem( body=self._cpt_hydrobody, free_surface=0.0, sea_bottom=-self.water_depth, omega=omega, rho=self.water_rho, g=self.grav, wave_direction=wave_dir ) for omega in self.omega_range for wave_dir in self.wave_dir_range ] problems = sorted(problems) problists = list(self.__split_list_chunks(problems, max_cores)) if len(problists) < n_cores: for _ in range(0, n_cores - len(problists)): problists.append([]) # unused threads else: problems = [] problists = [] if MPI: MPI.COMM_WORLD.barrier() problems = MPI.COMM_WORLD.scatter(problists, root=0) self._problems = problems
def evaluate_column_modal_response_amplitudes(self): """ """ bem_solver = cpt.BEMSolver() problems = [ cpt.RadiationProblem(sea_bottom=self.water_depth, body=self.column_mesh, radiating_dof=dof, omega=omega) for dof in self.column_mesh.dofs for omega in self.wave_frequencies ] problems += [ cpt.DiffractionProblem(sea_bottom=self.water_depth, body=self.column_mesh, wave_direction=self.wave_direction, omega=omega) for omega in self.wave_frequencies ] results = [bem_solver.solve(problem) for problem in problems] result_data = cpt.assemble_dataset(results) modal_response_amplitude_data = cpt.post_pro.rao( result_data, wave_direction=self.wave_direction) self.result_data = result_data self.modal_response_amplitude_data = modal_response_amplitude_data
def test_potential(): sphere = cpt.Sphere(radius=1.0, ntheta=3, nphi=12, clip_free_surface=True) sphere.add_translation_dof(name="Heave") solver = cpt.BEMSolver() result = solver.solve(cpt.RadiationProblem(body=sphere, omega=1.0), keep_details=True) free_surface = cpt.FreeSurface(x_range=(-100, 100), nx=5, y_range=(-100, 100), ny=5) eta = solver.get_potential_on_mesh(result, free_surface.mesh, chunk_size=3)
def evaluate_buoy_forces(buoy_object): # Set up radiation and diffraction problems problems = [cpt.RadiationProblem(body=buoy_object, radiating_dof=degree_of_freedom, omega=omega) for omega in omega_range] problems += [cpt.DiffractionProblem(omega=omega, body=buoy_object, wave_direction=wave_direction) for omega in omega_range] # Solve each matrix problem solver = cpt.BEMSolver(engine=cpt.HierarchicalToeplitzMatrixEngine()) results = [solver.solve(pb) for pb in sorted(problems)] return cpt.assemble_dataset(results)
def make_database(body, omegas, wave_directions): # SOLVE BEM PROBLEMS problems = [] for wave_direction in wave_directions: for omega in omegas: problems += [cpt.RadiationProblem(omega=omega, body=body, radiating_dof=dof) for dof in body.dofs] problems += [cpt.DiffractionProblem(omega=omega, body=body, wave_direction=wave_direction)] results = [bem_solver.solve(problem) for problem in problems] *radiation_results, diffraction_result = results dataset = cpt.assemble_dataset(results) dataset['diffraction_result'] = diffraction_result return dataset
def simulation(lc, ship, weights, tanks, mesh, omegas): body = generate_boat(lc, ship, weights, tanks, mesh) problems = [] for omega in omegas: for dof in body.dofs: problems.append(cpt.RadiationProblem(omega=omega, body=body, radiating_dof=dof)) for d in DIRS: problems.append(cpt.DiffractionProblem(omega=omega, body=body, wave_direction=d)) return problems
def setup_animation(body, fs, omega, wave_amplitude, wave_direction) -> Animation: # SOLVE BEM PROBLEMS problems = [ cpt.RadiationProblem(omega=omega, body=body, radiating_dof=dof) for dof in body.dofs ] problems += [ cpt.DiffractionProblem(omega=omega, body=body, wave_direction=wave_direction) ] results = [bem_solver.solve(problem) for problem in problems] *radiation_results, diffraction_result = results dataset = cpt.assemble_dataset(results) # COMPUTE RAO dataset['RAO'] = cpt.post_pro.rao(dataset, wave_direction=wave_direction) # Compute the motion of each face of the mesh for the animation rao_faces_motion = sum( dataset['RAO'].sel(omega=omega, radiating_dof=dof).data * body.full_body.dofs[dof] for dof in body.dofs) # COMPUTE FREE SURFACE ELEVATION # Compute the diffracted wave pattern diffraction_elevation = bem_solver.get_free_surface_elevation( diffraction_result, fs) incoming_waves_elevation = fs.incoming_waves(diffraction_result) # Compute the wave pattern radiated by the RAO radiation_elevations_per_dof = { res.radiating_dof: bem_solver.get_free_surface_elevation(res, fs) for res in radiation_results } rao_radiation_elevation = sum( dataset['RAO'].sel(omega=omega, radiating_dof=dof).data * radiation_elevations_per_dof[dof] for dof in body.dofs) # SET UP ANIMATION animation = Animation(loop_duration=2 * pi / omega) animation.add_body(body.full_body, faces_motion=wave_amplitude * rao_faces_motion) animation.add_free_surface( fs, wave_amplitude * (incoming_waves_elevation + diffraction_elevation + rao_radiation_elevation)) return animation
def test_xarray_dataset_with_more_data(): # Store some mesh data when several bodies in dataset bodies = [ cpt.Sphere(radius=1, ntheta=3, nphi=3, name="sphere_1"), cpt.Sphere(radius=2, ntheta=5, nphi=3, name="sphere_2"), cpt.Sphere(radius=3, ntheta=7, nphi=3, name="sphere_3"), ] for body in bodies: body.keep_immersed_part() body.add_translation_dof(name="Heave") problems = [cpt.RadiationProblem(body=b, radiating_dof="Heave", omega=1.0) for b in bodies] results = cpt.BEMSolver().solve_all(problems) ds = cpt.assemble_dataset(results, mesh=True) assert 'nb_faces' in ds.coords assert set(ds.coords['nb_faces'].values) == set([b.mesh.nb_faces for b in bodies])
def solve_tube_hydrodynamics(self): """ """ #print('\tSolving tube hydrodynamics.') solver = cpt.BEMSolver() problems = [ cpt.RadiationProblem(omega=omega, body=self.tube, radiating_dof=dof, rho=self.rho, sea_bottom=self.water_depth) for dof in self.tube.dofs for omega in self.wave_frequencies ] problems += [ cpt.DiffractionProblem(omega=omega, body=self.tube, wave_direction=self.wave_direction, rho=self.rho, sea_bottom=self.water_depth) for omega in self.wave_frequencies ] results = solver.solve_all(problems, keep_details=False) result_data = cpt.assemble_dataset(results) if self.save_results: from capytaine.io.xarray import separate_complex_values save_file_name = 'flexible_tube_results__rs_le_zs__{:.2f}_{:.1f}_{:.2f}__with_{}_cells.nc' \ .format(self.static_radius, self.length, self.submergence, self.tube.mesh.nb_faces) separate_complex_values(result_data).to_netcdf( save_file_name, encoding={ 'radiating_dof': { 'dtype': 'U' }, 'influenced_dof': { 'dtype': 'U' } }) self.result_data = result_data
def test_rotation_axis(): body = cpt.RectangularParallelepiped(resolution=(4, 4, 4), center=(0, 0, -1), name="body") body.add_translation_dof(name="Sway") body.add_rotation_dof(axis=cpt.Axis(point=(0, 0, 0), vector=(0, 0, 1)), name="Yaw") l = 2.0 body.add_rotation_dof(axis=cpt.Axis(point=(l, 0, 0), vector=(0, 0, 1)), name="other_rotation") assert np.allclose(body.dofs['other_rotation'], (body.dofs['Yaw'] - l * body.dofs['Sway'])) problems = [ cpt.RadiationProblem(body=body, radiating_dof=dof, omega=1.0) for dof in body.dofs ] solver = cpt.Nemoh() results = solver.solve_all(problems, keep_details=True) dataset = cpt.assemble_dataset(results) sources = {result.radiating_dof: result.sources for result in results} assert np.allclose(sources['other_rotation'], sources['Yaw'] - l * sources['Sway'], atol=1e-4) potential = {result.radiating_dof: result.potential for result in results} assert np.allclose(potential['other_rotation'], potential['Yaw'] - l * potential['Sway'], atol=1e-4) A_m = dataset['added_mass'].sel(radiating_dof="other_rotation", influenced_dof="other_rotation").data A = dataset['added_mass'].sel(radiating_dof=["Yaw", "Sway"], influenced_dof=["Yaw", "Sway"]).data P = np.array([1, -l]) assert np.isclose(A_m, P.T @ A @ P)
def solve_beam_hydrodynamics(self, save_results): """ """ bem_solver = cpt.BEMSolver() problems = [ cpt.RadiationProblem(sea_bottom=self.water_depth, body=self.beam_mesh, radiating_dof=dof, omega=omega) for dof in self.beam_mesh.dofs for omega in self.wave_frequencies ] problems += [ cpt.DiffractionProblem(sea_bottom=self.water_depth, body=self.beam_mesh, wave_direction=self.wave_direction, omega=omega) for omega in self.wave_frequencies ] results = [bem_solver.solve(problem) for problem in problems] result_data = cpt.assemble_dataset(results) if save_results: from capytaine.io.xarray import separate_complex_values separate_complex_values(result_data).to_netcdf( 'beam_hydrodynamics_results.nc', encoding={ 'radiating_dof': { 'dtype': 'U' }, 'influenced_dof': { 'dtype': 'U' } }) return result_data
def test_sum_of_dofs(): body1 = cpt.Sphere(radius=1.0, ntheta=3, nphi=12, center=(0, 0, -3), name="body1") body1.add_translation_dof(name="Heave") body2 = cpt.Sphere(radius=1.0, ntheta=3, nphi=8, center=(5, 3, -1.5), name="body2") body2.add_translation_dof(name="Heave") both = body1 + body2 both.add_translation_dof(name="Heave") problems = [ cpt.RadiationProblem(body=both, radiating_dof=dof, omega=1.0) for dof in both.dofs ] solver = cpt.Nemoh() results = solver.solve_all(problems) dataset = cpt.assemble_dataset(results) both_added_mass = dataset['added_mass'].sel(radiating_dof="Heave", influenced_dof="Heave").data body1_added_mass = dataset['added_mass'].sel( radiating_dof="body1__Heave", influenced_dof="body1__Heave").data body2_added_mass = dataset['added_mass'].sel( radiating_dof="body2__Heave", influenced_dof="body2__Heave").data assert np.allclose(both_added_mass, body1_added_mass + body2_added_mass, rtol=1e-2)
K[j, i] = -area / (4 * pi) * 3 if mesh1 is mesh2: for i in range(mesh1.nb_faces): K[i, i] += 1 / 2 return S, K else: raise NotImplementedError # Define a solver using the Green function above. solver = cpt.BEMSolver(green_function=MyAbstractGreenFunction()) # Example of a problem sphere = cpt.Sphere( radius=1.0, # Dimension center=(0, 0, -2), # Position nphi=4, ntheta=4, # Fineness of the mesh ) sphere.add_translation_dof(name="Heave") problem = cpt.RadiationProblem(body=sphere, free_surface=np.infty, sea_bottom=-np.infty, radiating_dof='Heave') result = solver.solve(problem) print(result.added_masses)
center=(0, 0, -2), # Position nr=5, nx=40, ntheta=20, # Fineness of the mesh ) # Define a degree of freedom. The keyword "Heave" # is recognized by the code and the vertical translation # motion is automatically defined. cylinder.add_translation_dof(name="Heave") # Define the range of water depth depth_range = list(range(5, 25, 2)) + [np.infty] # Set up the problems: we will solve a radiation problem for each # water depth: problems = [ cpt.RadiationProblem(body=cylinder, sea_bottom=-depth, omega=2.0) for depth in depth_range ] # Water density, gravity and radiating dof have not been specified. # Default values are used. (For the radiating dof, the default value # is usually the first one that have been defined. Here only one have # been defined.) # Solve all radiation problems with Nemoh solver = cpt.Nemoh() results = [solver.solve(pb) for pb in sorted(problems)] # Gather the computed added mass into a labelled array. data = cpt.assemble_dataset(results) # Plot the added mass of each dofs as a function of the water depth.
nr=5, nx=40, ntheta=20, # Fineness of the mesh ) # Automatically add the six degrees of freedom of a rigid body cylinder.add_all_rigid_body_dofs() # Define the range of frequencies as a Numpy array omega_range = np.linspace(0.1, 6.0, 20) # Set up the problems: we will solve a radiation problem for each # degree of freedom of the body and for each frequency in the # frequency range. problems = [ cpt.RadiationProblem(body=cylinder, radiating_dof=dof, omega=omega) for dof in cylinder.dofs for omega in omega_range ] # Water density, gravity and water depth have not been specified. # Default values are used. # Solve all radiation problems solver = cpt.BEMSolver() results = [solver.solve(pb) for pb in sorted(problems)] # The 'sorted' function ensures that the problems are sequentially # treated in an optimal order. # Gather the computed added mass into a labelled array. data = cpt.assemble_dataset(results) # Plot the added mass of each dofs as a function of the frequency
ntheta=50, clever= False, # Do not use axial symmetry of the mesh (not really useful here) ) body.keep_immersed_part() body.add_translation_dof(name='Heave') solver = cpt.BEMSolver() # Define and solve the diffraction and radiation problems diff_problem = cpt.DiffractionProblem(body=body, sea_bottom=-depth, omega=omega, wave_direction=0.) rad_problem = cpt.RadiationProblem(body=body, sea_bottom=-depth, omega=omega, radiating_dof='Heave') diff_solution = solver.solve(diff_problem) rad_solution = solver.solve(rad_problem) # Read mesh properties faces_centers = body.mesh.faces_centers faces_normals = body.mesh.faces_normals faces_areas = body.mesh.faces_areas from capytaine.bem.airy_waves import airy_waves_potential, airy_waves_velocity, froude_krylov_force # Computation from the diffraction solution (Capytaine) FK = froude_krylov_force(diff_problem)['Heave'] diff_force = diff_solution.forces['Heave']
I = np.array([[34.298, 1.133E-10, 0], [1.133E-10, 34.303, 0], [0, 0, 33.331]]) M = block_diag(m, m, m, I) body.mass = body.add_dofs_labels_to_matrix(M) # print(body.mass) # Hydrostatics kHS = block_diag(0, 0, hsd['stiffness_matrix'], 0) body.hydrostatic_stiffness = body.add_dofs_labels_to_matrix(kHS) # change omega values omega = np.linspace(0.1, 2, 10) wave_direction = 0.0 #body.keep_only_dofs(['Heave']) problems = [ cpt.RadiationProblem(omega=w, body=body, radiating_dof=dof) for dof in body.dofs for w in omega ] problems += [ cpt.DiffractionProblem(omega=w, body=body, wave_direction=wave_direction) for w in omega ] results = [bem_solver.solve(problem) for problem in problems] *radiation_results, diffraction_result = results dataset = cpt.assemble_dataset(results) # COMPUTE RAO dataset['RAO'] = cpt.post_pro.rao(dataset, wave_direction=wave_direction) # print(dataset['RAO']) # print(dataset['RAO'].data) #plt.plot(omega,dataset['RAO'].data)
full_sphere.add_translation_dof(name="Heave") # Keep only the immersed part of the mesh sphere = full_sphere.keep_immersed_part(inplace=False) sphere.add_translation_dof(name="Heave") # Set up and solve problem solver = cpt.BEMSolver() diffraction_problem = cpt.DiffractionProblem(body=sphere, wave_direction=0.0, omega=2.0) diffraction_result = solver.solve(diffraction_problem) radiation_problem = cpt.RadiationProblem(body=sphere, radiating_dof="Heave", omega=2.0) radiation_result = solver.solve(radiation_problem) # Define a mesh of the free surface and compute the free surface elevation free_surface = cpt.FreeSurface(x_range=(-50, 50), y_range=(-50, 50), nx=150, ny=150) diffraction_elevation_at_faces = solver.get_free_surface_elevation( diffraction_result, free_surface) radiation_elevation_at_faces = solver.get_free_surface_elevation( radiation_result, free_surface) # Add incoming waves diffraction_elevation_at_faces = diffraction_elevation_at_faces + free_surface.incoming_waves(
#you can use meshmagick to find inertia matrix but they use constant density #alternatively use a CAD software to acquire inertia matrix hsd = hs.Hydrostatics(mm.Mesh(body.mesh.vertices, body.mesh.faces)).hs_data m = hsd['disp_mass'] I = np.array([[hsd['Ixx'], -1*hsd['Ixy'], -1*hsd['Ixz']], [-1*hsd['Ixy'], hsd['Iyy'], -1*hsd['Iyz']], [-1*hsd['Ixz'], -1*hsd['Iyz'], hsd['Izz']]]) M = block_diag(m, m, m, I) body.mass = body.add_dofs_labels_to_matrix(M) print(body.mass) #mass matrix # Hydrostatics kHS = block_diag(0,0,hsd['stiffness_matrix'],0) body.hydrostatic_stiffness = body.add_dofs_labels_to_matrix(kHS) print(body.hydrostatic_stiffness) #hydrostatic coefficient # ---------------------- find damping coeff + added mass @ frequency ----------------------------- omega=5.0 problem = cpt.RadiationProblem(body=body, radiating_dof="Heave", omega=omega) solver = cpt.BEMSolver() result = solver.solve(problem) print(result.radiation_dampings) #damping coefficient print(result.added_masses) #added mass coefficient
radius=1.0, center=(1.5, 3.0, -3.0), nx=20, nr=3, ntheta=20, name="cylinder") cylinder.add_translation_dof(name="Surge") cylinder.add_translation_dof(name="Heave") # Combine the three individual bodies into a single body. all_bodies = cylinder + sphere + other_sphere print("Merged body name:", all_bodies.name) print("Merged body dofs:", list(all_bodies.dofs.keys())) # The merged body can be used to define the problems in the usual way problems = [ cpt.RadiationProblem(body=all_bodies, radiating_dof=dof, omega=1.0) for dof in all_bodies.dofs ] problems += [ cpt.DiffractionProblem(body=all_bodies, wave_direction=0.0, omega=1.0) ] # Solves the problem solver = cpt.Nemoh() results = solver.solve_all(problems) data = cpt.assemble_dataset(results) print(data)
def shape(z): return 0.1 * (-(z + 1)**2 + 16) # Generate the mesh and display it with VTK. buoy = cpt.FloatingBody( cpt.AxialSymmetricMesh.from_profile(shape, z_range=np.linspace(-5, 0, 30), nphi=40)) buoy.add_translation_dof(name="Heave") buoy.show() # Set up problems omega_range = np.linspace(0.1, 5.0, 60) problems = [ cpt.RadiationProblem(body=buoy, radiating_dof='Heave', omega=omega) for omega in omega_range ] # Solve the problems solver = cpt.Nemoh() results = [solver.solve(pb) for pb in sorted(problems)] dataset = capytaine.io.xarray.assemble_dataset(results) # Plot results import matplotlib.pyplot as plt plt.figure() plt.plot( omega_range, dataset['added_mass'].sel(radiating_dof='Heave', influenced_dof='Heave'), label="Added mass",
body.keep_immersed_part() # D. Add degrees of freedom body.add_all_rigid_body_dofs() # E. Define simulation parameters freq = np.linspace(0.02, 8.4, 3) directions = np.linspace(0, 90, 2) # 2. Define a list of problems to be solved. Can be radiation problems or # diffraction problems. ( # Uses python 'list comprehension' to easily loop through all dofs / freq problems = [ cpt.RadiationProblem(body=body, radiating_dof=dof, omega=w, sea_bottom=-np.infty, g=9.81, rho=1000.0) for dof in body.dofs for w in freq ] problems += [ cpt.DiffractionProblem(body=body, omega=w, wave_direction=heading, sea_bottom=-np.infty, g=9.81, rho=1000.0) for w in freq for heading in directions ] # 3. Define the BEM solver to be used. solver = cpt.BEMSolver()
body.keep_immersed_part() # D. Add degrees of freedom body.add_all_rigid_body_dofs() # E. Define simulation parameters freq = np.linspace(0.02, 8.4, 3) directions = np.linspace(0,90,2) # 2. Define a list of problems to be solved. Can be radiation problems or # diffraction problems. ( # Uses python 'list comprehension' to easily loop through all dofs / freq problems = [cpt.RadiationProblem(body=body, radiating_dof=dof, omega=w, sea_bottom=-np.infty, g=9.81, rho=1000.0) for dof in body.dofs for w in freq] problems += [cpt.DiffractionProblem(body=body, omega=w, wave_direction=heading, sea_bottom=-np.infty, g=9.81, rho=1000.0) for w in freq for heading in directions] # 3. Define the BEM solver to be used. solver = cpt.BEMSolver() # 4. Loop through the problems and solve each