NiHu  2.0
helmholtz_bem_3d_test.m
1 %// sphere radiator with radius R = 1, divided into 8 elements along the radius.
2 radiator = create_sphere_boundary(1, 8);
3 
4 %// the radiator is divided into two parts to get tria and quad elements
5 rad_left = drop_unused_nodes(mesh_section(radiator, [-inf, -inf, -inf; 1e-3, inf, inf]));
6 rad_right = drop_unused_nodes(mesh_section(radiator, [-1e-3, -inf, -inf; inf, inf, inf]));
7 radiator = merge_coincident_nodes(join_meshes(rad_left, quad2tria(rad_right)));
8 
9 %// field point mesh, a line revolved around the z axis
10 field = revolve_mesh(create_line([1.125, 0, 0; 3.625, 0, 0], 40), pi/100, 50, [0 0 1]);
11 
12 %// extract the mesh description matrices
13 [r_nodes, r_elem] = extract_core_mesh(radiator);
14 [f_nodes, f_elem] = extract_core_mesh(field);
15 
16 %// call C++ code at wave number k = 4
17 k = 4;
18 [Ls, Ms, Lf, Mf] = helmholtz_bem_3d(r_nodes, r_elem, f_nodes, f_elem, k);
19 
20 %// define the incident velocity field and analytical solutions
21 x0 = [-.2 0 .3];
22 [r_cent, r_norm] = centnorm(radiator);
23 [ps_ana, qs_ana] = incident('point', x0, r_cent, r_norm, k);
24 
25 %// analytical solution on the field
26 f_cent = centnorm(field);
27 pf_ana = incident('point', x0, f_cent, [], k);
28 
29 %// acoustic pressure on the surface and in the field points
30 ps_num = Ms \ (Ls * qs_ana);
31 pf_num = Mf*ps_num - Lf*qs_ana;
32 
33 % // calculate errors
34 ps_err = abs(ps_num-ps_ana)./abs(ps_ana);
35 pf_err = abs(pf_num-pf_ana)./abs(pf_ana);
36 
37 % // plot results
38 figure;
39 subplot(1,2,1);
40 plot_mesh(radiator, real(ps_num));
41 plot_mesh(field, real(pf_num)); view(2); shading flat;
42 c1 = colorbar('SouthOutside');
43 xlabel(c1, 'Real part of numerical solution');
44 subplot(1,2,2);
45 plot_mesh(radiator, log10(ps_err));
46 plot_mesh(field, log10(pf_err)); view(2); shading flat;
47 c2 = colorbar('SouthOutside');
48 xlabel(c2, 'Log 10 error of solution');
49 
50 %// display error information
51 fprintf('Surface log10 error: %f \n', log10(mean(ps_err)));
52 fprintf('Field log10 error: %f \n', log10(mean(pf_err)));