Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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])
Esempio n. 9
0
    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
Esempio n. 10
0
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
Esempio n. 12
0
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)
Esempio n. 13
0
                        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)
Esempio n. 14
0
    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.
Esempio n. 15
0
    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
Esempio n. 16
0
    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']
Esempio n. 17
0
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(
Esempio n. 19
0
    #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
Esempio n. 20
0
                                  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)
Esempio n. 21
0
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",
Esempio n. 22
0
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()
Esempio n. 23
0
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