예제 #1
0
def test_laplace_single_layer_potential_p1(default_parameters, helpers,
                                           device_interface, precision):
    """Test Laplace slp potential with p1 basis."""
    from bempp.api import function_space
    from bempp.api import GridFunction
    from bempp.api.operators.potential.laplace import single_layer

    grid = helpers.load_grid("sphere")
    space = function_space(grid, "P", 1)

    data = helpers.load_npz_data("laplace_single_layer_potential_p1")

    coefficients = data["vec"]
    points = data["points"]
    expected = data["result"]

    fun = GridFunction(space, coefficients=coefficients)

    actual = single_layer(
        space,
        points,
        parameters=default_parameters,
        precision=precision,
        device_interface=device_interface,
    ).evaluate(fun)

    _np.testing.assert_allclose(actual,
                                expected,
                                rtol=helpers.default_tolerance(precision))
예제 #2
0
def helmholtz_potential_dense_large_p0_benchmark(benchmark,
                                                 default_parameters):
    """Benchmark for Helmholtz potential evaluation on large sphere"""

    from bempp.api.operators.potential.helmholtz import single_layer
    from bempp.api import function_space
    import numpy as np

    grid = bempp.api.shapes.regular_sphere(6)
    space = function_space(grid, "DP", 0)

    npoints = 10000

    theta = np.linspace(0, 2 * np.pi, npoints)
    points = np.vstack(
        [np.cos(theta),
         np.sin(theta), 3 * np.ones(npoints, dtype="float64")])

    coefficients = np.random.randn(
        space.global_dof_count) + 1j * np.random.randn(space.global_dof_count)

    grid_fun = bempp.api.GridFunction(space, coefficients=coefficients)

    fun = lambda: single_layer(
        space, points, 2.5, parameters=default_parameters).evaluate(grid_fun)

    benchmark(fun)
예제 #3
0
def test_laplace_single_layer_potential_p1_complex(default_parameters, helpers,
                                                   device_interface,
                                                   precision):
    """Test Laplace slp potential with p1 basis and complex coeffs."""
    from bempp.api import function_space
    from bempp.api import GridFunction
    from bempp.api.operators.potential.laplace import single_layer

    grid = helpers.load_grid("sphere")
    space = function_space(grid, "P", 1)

    data = helpers.load_npz_data("laplace_single_layer_potential_p1")

    points = data["points"]
    coefficients = _np.random.rand(
        space.global_dof_count) + 1j * _np.random.rand(space.global_dof_count)

    fun = GridFunction(space, coefficients=coefficients)
    fun_real = GridFunction(space, coefficients=_np.real(coefficients))
    fun_complex = GridFunction(space, coefficients=_np.imag(coefficients))

    op = single_layer(
        space,
        points,
        parameters=default_parameters,
        precision=precision,
        device_interface=device_interface,
    )

    expected = op.evaluate(fun_real) + 1j * op.evaluate(fun_complex)
    actual = op.evaluate(fun)

    _np.testing.assert_allclose(actual,
                                expected,
                                rtol=helpers.default_tolerance(precision))
예제 #4
0
    def calculate_solvation_energy(self):
        if not hasattr(self, 'phi'):
            ## If surface potential has not been calculated, calculate it now ##
            self.calculate_potential()

        start_time = time.time()
        dirichl_space = self.dirichl_space
        neumann_space = self.neumann_space

        solution_dirichl = self.phi
        solution_neumann = self.d_phi

        from bempp.api.operators.potential.laplace import single_layer, double_layer

        slp_q = single_layer(neumann_space, self.x_q.transpose())
        dlp_q = double_layer(dirichl_space, self.x_q.transpose())
        phi_q = slp_q * solution_neumann - dlp_q * solution_dirichl

        # total solvation energy applying constant to get units [kcal/mol]
        total_energy = 2 * np.pi * 332.064 * np.sum(self.q * phi_q).real

        self.solvation_energy = total_energy

        self.time_calc_energy = time.time() - start_time
        if self.print_times:
            print('It took ', self.time_calc_energy,
                  ' seconds to compute the solvatation energy')
예제 #5
0
    def calculate_solvation_energy(self, rerun_all=False):
        if rerun_all:
            self.calculate_potential(rerun_all)

        if "phi" not in self.results:
            # If surface potential has not been calculated, calculate it now
            self.calculate_potential()

        start_time = time.time()

        solution_dirichl = self.results["phi"]
        solution_neumann = self.results["d_phi"]

        from bempp.api.operators.potential.laplace import single_layer, double_layer

        slp_q = single_layer(self.neumann_space, self.x_q.transpose())
        dlp_q = double_layer(self.dirichl_space, self.x_q.transpose())
        phi_q = slp_q * solution_neumann - dlp_q * solution_dirichl

        # total solvation energy applying constant to get units [kcal/mol]
        total_energy = 2 * np.pi * 332.064 * np.sum(self.q * phi_q).real
        self.results["solvation_energy"] = total_energy

        self.timings["time_calc_energy"] = time.time() - start_time

        if self.print_times:
            print('It took ', self.timings["time_calc_energy"],
                  ' seconds to compute the solvation energy')
# Y Finalmente se resuelve para u_r y du_r
sol, info,it_count = bempp.api.linalg.gmres( blocked , rhs, return_iteration_count=True, tol=1e-4)
print("The linear system for u_r and du_r was solved in {0} iterations".format(it_count))
u_r , du_r = sol

# 5) Calculo de la energía de solvatación

# Se importan los operadores para el potencial en el dominio de la molecula
from bempp.api.operators.potential import laplace as lp

# En base a los puntos donde se encuentran las cargas, calculemos el potencial u_r y u_h
# Esto luego de que podemos escribir la energía de solvatación como
# G_solv = Sum_i q_i *u_reac = Sum_i q_i * (u_h+u_r)           evaluado en cada carga.

# Se definen los operadores
slp_in_O = lp.single_layer(neumann_space, x_q.transpose()) 
dlp_in_O = lp.double_layer(dirichl_space, x_q.transpose())

# Y con la solución de las fronteras se fabrica el potencial evaluada en la posición de cada carga
u_r_O = slp_in_O * du_r  -  dlp_in_O * u_r
u_h_O = slp_in_O * du_h  +  dlp_in_O * u_s

terms =  u_r_O + u_h_O

# Donde agregando algunas constantes podemos calcular la energía de solvatacion S
K     = 0.5 * 4. * np.pi * 332.064 
S     = K * np.sum(q * terms).real
print("Three Term Splitting Solvation Energy : {:7.8f} [kCal/mol] ".format(S) )


# 6) Post-Procesamiento
예제 #7
0
def test_laplace_p1_segments_complex_coeffs(default_parameters, helpers,
                                            device_interface, precision):
    """Test P1 potential evaluation on segments with complex coeffs."""

    from bempp.api.shapes import cube
    from bempp.api import function_space
    from bempp.api import GridFunction
    from bempp.api.operators.potential.laplace import single_layer

    grid = cube()
    seg1 = function_space(grid,
                          "P",
                          1,
                          segments=[1, 2, 3],
                          include_boundary_dofs=False)
    seg2 = function_space(
        grid,
        "P",
        1,
        segments=[4, 5, 6],
        include_boundary_dofs=True,
        truncate_at_segment_edge=False,
    )
    seg_all = function_space(grid, "DP", 1)

    random = _np.random.RandomState(0)

    coeffs1 = random.rand(
        seg1.global_dof_count) + 1j * random.rand(seg1.global_dof_count)
    coeffs2 = random.rand(
        seg2.global_dof_count) + 1j * random.rand(seg2.global_dof_count)
    coeffs_all = seg1.map_to_full_grid.dot(
        coeffs1) + seg2.map_to_full_grid.dot(coeffs2)

    points = 1.6 * _np.ones((3, 1)) + 0.5 * _np.random.rand(3, 20)

    fun1 = GridFunction(seg1, coefficients=coeffs1)
    fun2 = GridFunction(seg2, coefficients=coeffs2)
    fun_all = GridFunction(seg_all, coefficients=coeffs_all)

    seg1_res = single_layer(
        seg1,
        points,
        parameters=default_parameters,
        precision=precision,
        device_interface=device_interface,
    ).evaluate(fun1)

    seg2_res = single_layer(
        seg2,
        points,
        parameters=default_parameters,
        precision=precision,
        device_interface=device_interface,
    ).evaluate(fun2)

    seg_all_res = single_layer(
        seg_all,
        points,
        parameters=default_parameters,
        precision=precision,
        device_interface=device_interface,
    ).evaluate(fun_all)

    actual = seg1_res + seg2_res
    expected = seg_all_res

    _np.testing.assert_allclose(actual,
                                expected,
                                rtol=helpers.default_tolerance(precision))