function [a,b,c] = submerged_semiinfinite_dock(alpha,h,d,theta,N) % [a,b,c] = submerged_semiinfinite_dock(alpha,h,d,theta,N) % % this program solves the submerged semiinfinite dock problem by an % eigenfunction matching. % alpha is the radian frequency squared % h is the water depth, d is the depth of the submerged plate, % theta is the angle of incidence % and N+1 is the number of eigenfunctions in each region % % a is the vector of coefficients for the eigenfunctions % cos(kh_n(z+h))/cos(kh_n h) where kh_n are the roots of the dispersion % equation for depth h % % b is the vector of coefficients for the eigenfunctions % cos(kd_n(z+h))/cos(kd_n h) where kd_n are the roots of the dispersion % equation for depth d (b has size N_above) % % c is the vector of coefficients for the eigenfunctions % cos(kappa_n(z+h) where kappa_n = n*pi/(h-d) (c has size N_below) % % the boundary value problem is described in % http://www.wikiwaves.org/index.php/Eigenfunction_Matching_for_a_Submerged_Semi-Infinite_Dock % we need to allocate the modes on the right so that they are roughly in % the same ratio as d and (h-d) while allowing at least one. % remember that there is actually N + 1 modes. N_above = round(d/h*(N+1)) -1; % number of modes above is N_above + 1; N_below = N-1-N_above; % numebr of modes below is N_below +1; if N_above < 0 N_above = 0; N_below = N-1; elseif N_below < 0 N_above = N-1; N_below = 0; end % first we calculate the roots of the dispersion equation for the water kh = dispersion_free_surface(alpha,N,h); kd = dispersion_free_surface(alpha,N_above,d); % we need to determine the wavenumber in the y direction k_y = sin(theta)*kd(1); % we calculate the roots of the dispersion equation for the dock covered % region kappa = [0:N_below]*pi/(h-d); % we now find the modified coefficients kh_hat = sqrt(kh.^2 - k_y^2); kd_hat = sqrt(kh.^2 - k_y^2); kappa_hat = sqrt(kappa.^2 - k_y^2); % we calculate the matrix of inner products. A = zeros(N+1,N+1); B = zeros(N+1,N+1); for j = 1:N+1; A(j,j) = innerproduct_h_to_d(kh(j),kh(j),h,0)/cos(kh(j)*h)^2; % first we do the modes above for l = 1:N_above+1; B(j,l) = innerproduct_d_to_0(kh(j),kd(l),h,d)/(cos(kh(j)*h)*cos(kd(l)*d)); end % then the modes below for l = 1:N_below+1; B(j,l+N_above+1) = innerproduct_h_to_d(kh(j),kappa(l),h,d)/cos(kh(j)*h); end end % we do not calculate in the most efficient manner but we want the code to % be easy to follow. We now assemble the equations to solve M = zeros(size(B)); for j = 1:N+1; for l = 1:N_above+1; M(j,l) = (kh_hat(j) + kd_hat(l))*B(j,l); end for l = 1:N_below+1; M(j,l+N_above+1) = (kh_hat(j) + kappa_hat(l))*B(j,l+N_above+1); end end RHS = zeros(N+1,1); RHS(1) = A(1,1); b = M\(2*kh_hat(1)*RHS); a = A\(B*b - RHS); c = b(N_above+2:end);b = b(1:N_above+1); %-------------------------------------------------------------------------- % a set of commands used to test this program. We plot the potential and % its derivative on each side and show that they match. You can also check % that the program is correct by making sure abs(a(1)) = 1 (from % conservation of energy). % uncomment these lines to run the test (except this one) % z_full = -h:h/200:0; % z_above = -d:h/200:0; % z_below = -h:h/200:-d; % % phi_minus = cos(kh(1)*(z_full+h))/cos(kh(1)*h); % phi_plus_above = zeros(size(z_above)); % phi_plus_below = zeros(size(z_below)); % % phi_minus = phi_plus; % % for count = 1:N+1 % phi_minus = phi_minus + a(count)*cos(kh(count)*(z_full+h))/cos(kh(count)*h); % end % % for count = 1:N_above+1 % phi_plus_above = phi_plus_above + b(count)*cos(kd(count)*(z_above+d))/cos(kd(count)*d); % end % % for count = 1:N_below+1 % phi_plus_below = phi_plus_below + c(count)*cos(kappa(count)*(z_below+h)); % end % % plot(z_full,abs(phi_minus),z_above,abs(phi_plus_above),z_below,abs(phi_plus_below)) % % pause % % phi_minus_n = -kh_hat(1)*cos(kh(1)*(z_full+h))/cos(kh(1)*h); % phi_plus_above_n = zeros(size(z_above)); % phi_plus_below_n = zeros(size(z_below)); % % phi_minus = phi_plus; % % for count = 1:N+1 % phi_minus_n = phi_minus_n + kh_hat(count)*a(count)*cos(kh(count)*(z_full+h))/cos(kh(count)*h); % end % % for count = 1:N_above+1 % phi_plus_above_n = phi_plus_above_n - kd_hat(count)*b(count)*cos(kd(count)*(z_above+d))/cos(kd(count)*d); % end % % for count = 1:N_below+1 % phi_plus_below_n = phi_plus_below_n - kappa_hat(count)*c(count)*cos(kappa(count)*(z_below+h)); % end % % plot(z_full,abs(phi_minus_n),z_above,abs(phi_plus_above_n),z_below,abs(phi_plus_below_n)) %-------------------------------------------------------------------------- % this is a program to calculate the inner product of the eigenfunctions % with each other. function out = innerproduct_h_to_d(k,kappa,h,d) % program to calculate % \int_{-h}^{-d}\cos \kappa\left( z+h\right) % \cos k\left(z+h\right) dz % first we test for the case when \kappa and k are equal (or nearly equal) if abs((k-kappa)/(h-d)) > 1e-6 out = 1/2 * (sin(d*kappa - d*k - kappa*h + k*h)) / (k - kappa) ... + 1/2 * (sin(-d*kappa - d*k + kappa*h + k*h)) / (kappa + k); else if k == 0 out = h-d; else out = (1/2)*((cos(-k*d+k*h)*sin(-k*d+k*h)-k*d+k*h)/k); end end function out = innerproduct_d_to_0(kh,kd,h,d) % program to calculate % \int_{-d}^{0}\cos kh\left( z+h\right) \cos kd\left(z+d\right) dz % first we test for the case when kh and kd are equal (or nearly equal) if abs((kd-kh)/(h-d)) > 1e-6 out = (1/2)*(((sin(kh*h-d*kd))*kh+(sin(kh*h-d*kd))*kd ... + (sin(kh*h+d*kd))*kh -(sin(kh*h+d*kd))*kd-2*(sin(-d*kh+kh*h))*kh)/(kh^2-kd^2)); else if kd == 0 out = d; else out = (1/4)*((sin(kd*h+d*kd)+2*(cos(-d*kd+kd*h))*d*kd-sin(-d*kd+kd*h))/kd); end end