def test_helmholtz_single_layer_potential_p1_complex_coeffs( default_parameters, helpers, device_interface, precision): """Test Helmholtz slp potential with p1 basis and complex coeffs.""" from bempp.api import function_space from bempp.api import GridFunction from bempp.api.operators.potential.helmholtz import single_layer grid = helpers.load_grid("sphere") space = function_space(grid, "P", 1) data = helpers.load_npz_data("helmholtz_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, WAVENUMBER, 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 check(): vox = Hexa_model('dataset/7.obj') vox.create_tetra_and_boundary() vox.set_transform([center_scale(0.2)]) print(vox.tets.shape) return r_in = 0.1 r_out = 0.2 sphere = boundary_mesh(grid=bempp.api.shapes.sphere(h=0.02,r = r_out)) current_model = boundary_mesh(vertices=vox.vertices, faces=vox.boundary_faces) c = 343 omega = 1000*6.28 k = omega / c print(k) scale = 10 poles = special.Multipole(scale) weights = np.zeros(poles.pole_number) weights[1] = 0.3 weights[5] = 0.3 neumann_coeff = [] dirichlet_coeff = [] for point,normal in zip(current_model.face_centers(), current_model.normals()): #print(point, normal) poles.reset(k,point) poles.dirichlet_reset() poles.neumann_reset(normal) neumann_coeff.append((poles.neumann*weights).sum()) dirichlet_coeff.append((poles.dirichlet*weights).sum()) neumann_fun = GridFunction(current_model.dp0_space, coefficients=np.asarray(neumann_coeff)) dirichlet_fun = GridFunction(current_model.dp0_space, coefficients=np.asarray(dirichlet_coeff)) os.makedirs(f'./modedata',exist_ok=True) current_model.set_wave_number(k) current_model.set_neumann_fun(neumann_fun) current_model.ext_neumann2dirichlet() export(f'./modedata/test_N.msh',grid_function=current_model.neumann_fun) identity = boundary.sparse.identity( current_model.p1_space, current_model.dp0_space, current_model.p1_space) export(f'./modedata/test_D.msh',grid_function=identity*current_model.dirichlet_fun) export(f'./modedata/test_D_truth.msh',grid_function=dirichlet_fun) coeff = current_model.points_dirichlet(sphere.face_centers()) print(coeff.shape) print(sphere.faces.shape) export(f'./modedata/sphere_predict.msh', grid_function=GridFunction(sphere.dp0_space, coefficients=coeff)) coeff = []
def check(): r_in = 0.1 r_out = 0.1 * 3**(0.5) sphere = boundary_mesh(grid=bempp.api.shapes.sphere(h=0.01, r=r_out)) current_model = boundary_mesh(grid=bempp.api.shapes.sphere(h=0.01, r=r_in)) c = 343 omega = 1000 * 6.28 k = omega / c scale = 10 poles = special.Multipole(scale) weights = np.zeros(poles.pole_number) weights[0] = 0.3 weights[10] = 0.3 weights[5] = 0.3 neumann_coeff = [] dirichlet_coeff = [] for point in current_model.face_centers(): poles.reset(k, point) poles.dirichlet_reset() poles.neumann_reset() neumann_coeff.append((poles.neumann * weights).sum()) dirichlet_coeff.append((poles.dirichlet * weights).sum()) neumann_fun = GridFunction(current_model.dp0_space, coefficients=np.asarray(neumann_coeff)) dirichlet_fun = GridFunction(current_model.dp0_space, coefficients=np.asarray(dirichlet_coeff)) current_model.set_wave_number(k) current_model.set_neumann_fun(neumann_fun) current_model.ext_neumann2dirichlet() export(f'./modedata/test_N.msh', grid_function=current_model.neumann_fun) export(f'./modedata/test_D.msh', grid_function=current_model.dirichlet_fun) export(f'./modedata/test_D_truth.msh', grid_function=dirichlet_fun) coeff = current_model.points_dirichlet(sphere.face_centers()) print(coeff.shape) print(sphere.faces.shape) export(f'./modedata/sphere_predict.msh', grid_function=GridFunction(sphere.dp0_space, coefficients=coeff)) coeff = [] for point in sphere.face_centers(): poles.reset(k, point) poles.dirichlet_reset() coeff.append((poles.dirichlet * weights).sum()) coeff = np.asarray(coeff) dirichlet_fun = GridFunction(sphere.dp0_space, coefficients=coeff) export(f'./modedata/shpere_truth.msh', grid_function=dirichlet_fun)
def get_grid_fun_from_list(self, sphere_mesh, weights_, k): coeff = np.zeros(len(sphere_mesh.face_centers()),dtype=np.complex) for weights in weights_: coeff += (self.get_sphere_coeff(sphere_mesh, weights, k))**2 coeff /= len(weights_) dirichlet_fun = GridFunction(sphere_mesh.dp0_space, coefficients=coeff**0.5) return dirichlet_fun
def test_maxwell_magnetic_field_potential_rwg(default_parameters, helpers, device_interface, precision): """Test Maxwell magnetic potential.""" from bempp.api import function_space from bempp.api import GridFunction from bempp.api.operators.potential.maxwell import magnetic_field grid = helpers.load_grid("sphere") space = function_space(grid, "RWG", 0) data = helpers.load_npz_data("maxwell_magnetic_field_potential") coefficients = data["vec"] points = data["points"] expected = data["result"] fun = GridFunction(space, coefficients=coefficients) actual = magnetic_field( space, points, WAVENUMBER, parameters=default_parameters, precision=precision, device_interface=device_interface, ).evaluate(fun) _np.testing.assert_allclose(actual, expected, rtol=helpers.default_tolerance(precision))
def test_helmholtz_double_layer_potential_p1(default_parameters, helpers, device_interface, precision): """Test Helmholtz dlp potential with p1 basis.""" from bempp.api import function_space from bempp.api import GridFunction from bempp.api.operators.potential.helmholtz import double_layer grid = helpers.load_grid("sphere") space = function_space(grid, "P", 1) data = helpers.load_npz_data("helmholtz_double_layer_potential_p1") coefficients = data["vec"] points = data["points"] expected = data["result"] fun = GridFunction(space, coefficients=coefficients) actual = double_layer( space, points, WAVENUMBER, parameters=default_parameters, precision=precision, device_interface=device_interface, ).evaluate(fun) _np.testing.assert_allclose(actual, expected, rtol=helpers.default_tolerance(precision))
def test_laplace_single_layer_potential_p0(default_parameters, helpers, device_interface, precision): """Test Laplace slp potential with p0 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, "DP", 0) data = helpers.load_npz_data("laplace_single_layer_potential_p0") 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 lu(A, b, lu_factor=None): """Simple direct solver interface. This function takes an operator and a grid function, converts the operator into a dense matrix and solves the system via LU decomposition. The result is again returned as a grid function. Parameters ---------- A : bempp.api.BoundaryOperator The left-hand side boundary operator b : bempp.api.GridFunction The right-hand side grid function lu_decomp : tuple Optionally pass the tuple (lu, piv) obtained by the scipy method scipy.linalg.lu_factor """ from bempp.api import GridFunction, as_matrix from scipy.linalg import solve, lu_solve if lu_factor is not None: vec = b.projections(A.dual_to_range) sol = lu_solve(lu_factor, vec) else: mat = as_matrix(A.weak_form()) vec = b.projections(A.dual_to_range) sol = solve(mat, vec) return GridFunction(A.domain, coefficients=sol)
def test(): scale = 0.2 vox = Plate_model(200) vox.create_tetra_and_boundary() vox.set_transform([center_scale(scale)]) fem = FEM_model(vox.vertices, vox.tets) fem.set_material(0) fem.create_matrix() fem.compute_modes() print('==========modal data=============') print(fem.vals.shape) print(fem.vecs.shape) print(fem.vertices.max(), fem.vertices.min()) sphere = boundary_mesh( grid=bempp.api.shapes.sphere(h=0.01, r=0.1 * 3**(0.5))) current_model = boundary_mesh(vertices=vox.vertices, faces=vox.boundary_faces) for i in range(len(fem.vals)): c = 343 omega = fem.vals[i] displacement = fem.vecs[:, i] k = omega / c displacement = displacement.reshape(-1, 3) displacement = displacement[vox.boundary_faces].mean(1) c = (displacement * current_model.grid.normals).sum(1) neumann_fun = GridFunction(current_model.dp0_space, coefficients=c) current_model.set_wave_number(k) current_model.set_neumann_fun(neumann_fun) current_model.ext_neumann2dirichlet() export(f'./modedata/{i}stMode.msh', grid_function=current_model.neumann_fun) export(f'./modedata/{i}stMode_d.msh', grid_function=current_model.dirichlet_fun) coeffs = current_model.points_dirichlet(sphere.face_centers()) print(coeffs.shape) print(sphere.faces.shape) export(f'./modedata/{i}st_sphere.msh', grid_function=GridFunction(sphere.dp0_space, coefficients=coeffs))
def work(file_list): sphere = boundary_mesh(grid=bempp.api.shapes.sphere(h=0.02,r = 0.2)) pole_matrix = PolesMatrix() pole_matrix.sample_points(0.1) pole_matrix.assemble_matrix() print('pole matrix initialized') for dirname in tqdm(file_list): if os.path.exists(dirname+'/displacements.npy'): continue vertices = np.load(dirname+'/vertices.npy') print(dirname) boundary_faces = np.load(dirname+'/boundary_faces.npy') print(boundary_faces.shape) tets = np.load(dirname + '/tets.npy') current_model = boundary_mesh(vertices=vertices, faces=boundary_faces) #=====================FEM modal analysis================= fem = FEM_model(vertices, tets) fem.set_material(Material.Iron) fem.create_matrix() fem.compute_modes(min_freq=20,max_freq=20000) print(len(fem.omega_d)) if len(fem.omega_d) < 5: continue if fem.omega_d[0]/(2*np.pi) < 500: continue #=====================save data========================== export(dirname+'/mesh.msh', grid=current_model.grid) np.save(dirname+'/face_centers', current_model.face_centers()) np.save(dirname+'/face_normals', current_model.normals()) np.save(dirname+'/omegas', fem.omega_d) modes_num = len(fem.vals) poles_coeffs = np.zeros((modes_num, pole_matrix.poles.pole_number), dtype = np.complex) displacements = np.zeros((modes_num, len(boundary_faces))) for i in range(modes_num): omega = fem.omega_d[i] k_ = omega / SPEED_OF_SOUND freq_idx = pole_matrix.wavenumber2index(k_) k = pole_matrix.wave_numbers[freq_idx] #=================BEM======================= displacement = fem.vecs[:,i].reshape(-1,3) displacement = displacement[boundary_faces].mean(1) displacement = (displacement*current_model.normals()).sum(1) displacements[i] = displacement neumann_coeff = AIR_DENSITY*omega**2*displacement neumann_fun = GridFunction(current_model.dp0_space, coefficients=np.asarray(neumann_coeff)) current_model.set_wave_number(k) current_model.set_neumann_fun(neumann_fun) current_model.ext_neumann2dirichlet() #==================least square method================= b = current_model.points_dirichlet(pole_matrix.points) A = pole_matrix.all_matrix[freq_idx] weights, res, _, _ = lstsq(A,b) poles_coeffs[i] = weights np.save(dirname+'/poles_coeffs', poles_coeffs) np.save(dirname+'/displacements', displacements)
def preprocess(dirname): displacements = np.load(dirname+'/displacements.npy') poles_coeffs = np.load(dirname+'/poles_coeffs.npy') omegas = np.load(dirname+'/omegas.npy') mesh = boundary_mesh(np.load(dirname+'/vertices.npy'),np.load(dirname+'/boundary_faces.npy')) modes_dict = {i:[] for i in range(freq.resolution)} for i,omega in enumerate(omegas): modes_dict[freq.omega2index(omega)].append(i) for i in range(23,24): idxs = modes_dict[i] if len(idxs) == 0: continue omega = freq.index2omega(i) k = omega / SPEED_OF_SOUND displace = displacements[idxs] displace = abs(displace) coeff = poles_coeffs[idxs] print(coeff) # A = (displace.T[...,np.newaxis]*coeff).sum(-2) # c = A.sum(0) # print(c.shape) # A = A - c # U,S,V = scipy.sparse.linalg.svds(A,k=2) # print(U.shape) # export(f'modedata/{i}_1.msh',grid_function=GridFunction(mesh.dp0_space, coefficients=U[:,0])) # export(f'modedata/{i}_2.msh',grid_function=GridFunction(mesh.dp0_space, coefficients=U[:,1])) for j,displace_ in enumerate(displace): export(f'modedata/{i}_dis{j}.msh',grid_function=GridFunction(mesh.dp0_space, coefficients=displace_)) export(f'modedata/{i}_dis_all.msh',grid_function=GridFunction(mesh.dp0_space, coefficients=displace.sum(0))) export(f'modedata/{i}_dis_all_square.msh',grid_function=GridFunction(mesh.dp0_space, coefficients=(displace**2).sum(0)**0.5)) sphere = boundary_mesh(grid=bempp.api.shapes.sphere(h=0.02,r = 0.2)) for j,coeff_ in enumerate(coeff): export(f'modedata/{i}_coeff{j}.msh',grid_function=pole_matrix.get_grid_function(sphere, coeff_, k)) export(f'modedata/{i}_coeff_all.msh',grid_function=pole_matrix.get_grid_fun_from_list(sphere, coeff, k))
def __mul__(self, other): """Return product with a scalar, grid function or other operator.""" import numpy as np from bempp.api import GridFunction if np.isscalar(other): return _ScaledBoundaryOperator(self, other) elif isinstance(other, BoundaryOperator): return _ProductBoundaryOperator(self, other) elif isinstance(other, GridFunction): if not self.domain.is_compatible(other.space): raise ValueError( "Operator domain space does not match GridFunction space.") return GridFunction(self.range, projections=self.weak_form() * other.coefficients, dual_space=self.dual_to_range) else: return NotImplemented
def lu(A, b, lu_factor=None): """Simple direct solver interface. This function takes an operator and a grid function, converts the operator into a dense matrix and solves the system via LU decomposition. The result is again returned as a grid function. Parameters ---------- A : bempp.api.BoundaryOperator The left-hand side boundary operator b : bempp.api.GridFunction The right-hand side grid function lu_decomp : tuple Optionally pass the tuple (lu, piv) obtained by the scipy method scipy.linalg.lu_factor """ from bempp.api import GridFunction, as_matrix from scipy.linalg import solve, lu_solve from bempp.api.assembly.blocked_operator import BlockedOperatorBase from bempp.api.assembly.blocked_operator import projections_from_grid_functions_list from bempp.api.assembly.blocked_operator import grid_function_list_from_coefficients if isinstance(A, BlockedOperatorBase): blocked = True vec = projections_from_grid_functions_list(b, A.dual_to_range_spaces) if lu_factor is not None: sol = lu_solve(lu_factor, vec) else: mat = A.weak_form().A sol = solve(mat, vec) return grid_function_list_from_coefficients(sol, A.domain_spaces) else: vec = b.projections(A.dual_to_range) if lu_factor is not None: sol = lu_solve(lu_factor, vec) else: mat = A.weak_form().A sol = solve(mat, vec) return GridFunction(A.domain, coefficients=sol)
def dirichlet_trace(self, space): """ Return the dirichlet trace GridFunction on the specified space """ return GridFunction(space, fun=self._dirichlet_trace_fun)
def neumann_trace(self, space): """ Return the neumann trace GridFunction on the specified space """ return self.k / self.mu * GridFunction(space, fun=self._neumann_trace_fun)
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))
def work(filename): dirname = os.path.basename(filename)[:-3] output_dir = 'modedata/' + dirname os.makedirs(output_dir, exist_ok=True) dirname = glob('dataset/*/test/' + dirname)[0] print(dirname) vertices = np.load(dirname + '/vertices.npy') omegas = np.load(dirname + '/omegas.npy') poles_coeffs = np.load(dirname + '/poles_coeffs.npy') boundary_faces = np.load(dirname + '/boundary_faces.npy') mesh = boundary_mesh(vertices, boundary_faces) n = 2048 data = torch.load(filename) faces_num = len(data.x) mask_list = torch.ones(faces_num) #==================================w==================== if mask_list.sum() > n: mask = torch.multinomial(mask_list, n, replacement=False) else: mask = torch.multinomial(mask_list, n, replacement=True) data1 = Data() data1.pos = data.pos[mask] data1.normal = data.normal[mask] data1.batch = torch.zeros(len(data1.pos), dtype=torch.int64) data1 = data1.to(device) out = model_w(data1).view(32, 200).cpu().numpy() out_w = out[:, :100] + 1j * out[:, 100:] w = data.w.view(32, 200).cpu().numpy() w = w[:, :100] + 1j * w[:, 100:] #================================dis======================= dis = data.dis.cpu().numpy() out_dis = np.zeros_like(dis) while mask_list.sum() > n: mask = torch.multinomial(mask_list, n, replacement=False) mask_list[mask] = 0 data1 = Data() data1.pos = data.pos[mask] data1.normal = data.normal[mask] data1.batch = torch.zeros(len(data1.pos), dtype=torch.int64) data1 = data1.to(device) out = model_dis(data1) out_dis[mask] = out.cpu().numpy() mask = torch.multinomial(mask_list, n, replacement=True) data1 = Data() data1.pos = data.pos[mask] data1.normal = data.normal[mask] data1.batch = torch.zeros(len(data1.pos), dtype=torch.int64) data1 = data1.to(device) out = model_dis(data1) out_dis[mask] = out.cpu().numpy() modes_dict = {i: [] for i in range(freq.resolution)} for i, omega in enumerate(omegas): modes_dict[freq.omega2index(omega)].append(i) for i in range(23, 24): if data.s[0, i] == 0: continue coeff = poles_coeffs[modes_dict[i]] export(f'{output_dir}/gt{i}.msh', grid_function=GridFunction(mesh.dp0_space, coefficients=dis[:, i])) export(f'{output_dir}/predict{i}.msh', grid_function=GridFunction(mesh.dp0_space, coefficients=out_dis[:, i])) export(f'{output_dir}/{i}_sphere.msh', grid_function=pole_matrix.get_grid_function( sphere, out_w[i], freq.index2omega(i) / SPEED_OF_SOUND)) export(f'{output_dir}/{i}_sphere_gt.msh', grid_function=pole_matrix.get_grid_function( sphere, w[i], freq.index2omega(i) / SPEED_OF_SOUND)) export(f'{output_dir}/{i}_sphere_gt2.msh', grid_function=pole_matrix.get_grid_fun_from_list( sphere, coeff, freq.index2omega(i) / SPEED_OF_SOUND))
self.all_matrix = [] for k in self.wave_numbers: dirichlet_matrix = [] for p in self.points: self.poles.reset(k,x=p) self.poles.dirichlet_reset() dirichlet_matrix.append(self.poles.dirichlet) self.all_matrix.append(dirichlet_matrix) self.all_matrix = np.asarray(self.all_matrix) # print('shape of all matrix') # print(self.all_matrix.shape) def get_grid_function(self, sphere_mesh, weights, k): <<<<<<< HEAD coeff = self.get_sphere_coeff(sphere_mesh, weights, k) dirichlet_fun = GridFunction(sphere_mesh.dp0_space, coefficients=coeff) return dirichlet_fun def get_grid_fun_from_list(self, sphere_mesh, weights_, k): coeff = np.zeros(len(sphere_mesh.face_centers()),dtype=np.complex) for weights in weights_: coeff += (self.get_sphere_coeff(sphere_mesh, weights, k))**2 coeff /= len(weights_) dirichlet_fun = GridFunction(sphere_mesh.dp0_space, coefficients=coeff**0.5) return dirichlet_fun def get_sphere_coeff(self, sphere_mesh, weights, k): ======= >>>>>>> 9e91e9052ddc2f40996d02a5b6d3292290e83072 coeff = [] for p in sphere_mesh.face_centers():