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))
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)
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))
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')
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
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))