function [P]=p2d(P_old, Beta, k_mu, Q, nx, ny, dx, dy, dt, Bound_type_hor, Bound_val_hor, Bound_type_ver, Bound_val_ver) % 1999-2002 Boris Kaus % 2015 Gunnar Jansen & Stephen A. Miller % 2022 Last modified: Thanushika Gunatilake %Transpose input arrays P_old = P_old'; k_mu = k_mu'; Beta = Beta'; Q = Q'; %Initialise working arrays: A = sparse(nx*ny,nx*ny); aa = zeros(nx*ny,1);bb=aa;cc=aa;dd=aa;ee=aa; P_vec = zeros(nx*ny,1); k_mu_vec = zeros(nx*ny,1); rhs = zeros(nx*ny,1); %1 = spalte P = zeros(ny,nx); % Check the timestep and give a warning if the timestep is too large kappa = k_mu./Beta; dt_opt = (2*sqrt(dx^2+dy^2))^2/(4*pi^2*max(max(kappa))); k_mu_vec = k_mu(:); Q_vec = Q(:); beta_vec = Beta(:); rhs = -P_old(:) - Q_vec.*dt./beta_vec; ii = [ny+1:ny*nx-ny]; cc(1:end)=0;cc(ii) = dt./beta_vec(ii).*1/2.*(k_mu_vec(ii+1 )+k_mu_vec(ii))./dy^2; aa(1:end)=0;aa(ii) = dt./beta_vec(ii).*1/2.*(k_mu_vec(ii-1 )+k_mu_vec(ii))./dy^2; dd(1:end)=0;dd(ii) = dt./beta_vec(ii).*1/2.*(k_mu_vec(ii-ny)+k_mu_vec(ii))./dx^2; ee(1:end)=0;ee(ii) = dt./beta_vec(ii).*1/2.*(k_mu_vec(ii+ny)+k_mu_vec(ii))./dx^2; bb(1:end)=1;bb(ii) = -1 -aa(ii)-cc(ii)-dd(ii)-ee(ii); if strcmp(lower(Bound_type_hor{1}), 'dirichlet' ) % constant head left boundary ii = 1:ny; bb(ii)=1; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=0; rhs(ii) = Bound_val_hor(:,1); elseif strcmp(lower(Bound_type_hor{1}), 'neumann' ) % constant flux left boundary ii = 1:ny; bb(ii)=-1/dx; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=1/dx; rhs(ii) = Bound_val_hor(:,1); elseif strcmp(lower(Bound_type_hor{1}), 'periodic' ) % periodic left boundary: watch out it has to be set after the matrix is formed!!! ii = 1:ny; bb(ii)=-1/dx; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=1/dx; else error('The left boundary condition you specified is not implemented yet') end if strcmp(lower(Bound_type_hor{2}), 'dirichlet' ) % constant head right boundary ii = nx*ny-ny:nx*ny; bb(ii)=1; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=0; rhs(ii) = Bound_val_hor(:,2); elseif strcmp(lower(Bound_type_hor{2}), 'neumann' ) % constant flux right boundary ii = nx*ny-ny:nx*ny; bb(ii)= 1/dx; aa(ii)=0; cc(ii)=0; dd(ii)=-1/dx; ee(ii)=0; rhs(ii) = Bound_val_hor(:,2); elseif strcmp(lower(Bound_type_hor{2}), 'periodic' ) % periodic right boundary: watch out it has to be set after the matrix is formed!!! ii = nx*ny-ny:nx*ny; bb(ii)=-1/dx; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=1/dx; else error('The right boundary condition you specified is not implemented yet') end if strcmp(lower(Bound_type_ver{1}), 'dirichlet' ) % constant head lower boundary ii = 1:ny:nx*ny; bb(ii)=1; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=0; rhs(ii) = Bound_val_ver(:,1); elseif strcmp(lower(Bound_type_ver{1}), 'neumann' ) % constant flux lower boundary ii = 1:ny:nx*ny; bb(ii)=-1/dy; aa(ii)=0; cc(ii)= 1/dy; dd(ii)=0; ee(ii)=0; rhs(ii) = Bound_val_ver(:,1); else error('The lower boundary condition you specified is not implemented yet') end if strcmp(lower(Bound_type_ver{2}), 'dirichlet' ) % constant head upper boundary ii = ny:ny:nx*ny; bb(ii)=1; aa(ii)=0; cc(ii)=0; dd(ii)=0; ee(ii)=0; rhs(ii) = Bound_val_ver(:,2); elseif strcmp(lower(Bound_type_ver{2}), 'neumann' ) % constant flux upper boundary ii = ny:ny:nx*ny; bb(ii)= 1/dy; aa(ii)=-1/dy; cc(ii)=0; dd(ii)=0; ee(ii)=0; rhs(ii) = Bound_val_ver(:,2); else error('The upper boundary condition you specified is not implemented yet') end A = spdiags([ee cc bb aa dd], [-ny -1:1 ny], nx*ny, nx*ny); A = A'; % If there ar periodic horizontal BC's, we have to set them here if strcmp(lower(Bound_type_hor{1}), 'periodic' ) ii = 1:ny; for i=1:length(ii) A(ii(i),:) = 0; end for i=1:length(ii) ii_normal = ii(i); ii_periodic = ny*(nx-1)+ii(i); A(ii_normal,ii_normal + 1 ) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_normal + 1 ) + k_mu_vec(ii_normal))./dy^2; A(ii_normal,ii_periodic - 1 ) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_periodic - 1 ) + k_mu_vec(ii_normal))./dy^2; A(ii_normal,ii_periodic - ny) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_periodic - ny) + k_mu_vec(ii_normal))./dx^2; A(ii_normal,ii_normal + ny) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_normal + ny) + k_mu_vec(ii_normal))./dx^2; A(ii_normal,ii_normal) = -1 - A(ii_normal,ii_normal+1) - A(ii_normal,ii_periodic-1) - A(ii_normal,ii_periodic-ny) - A(ii_normal,ii_normal+ny); A(ii_normal,:) = -A(ii_normal,:); end end if strcmp(lower(Bound_type_hor{2}), 'periodic' ) ii = nx*ny-ny+1:nx*ny-1; for i=1:length(ii) A(ii(i),:) = 0; end for i=1:length(ii) ii_normal = ii(i); ii_periodic = ii(i) - ny*(nx-1); A(ii_normal,ii_periodic + 1 ) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_periodic +1 ) + k_mu_vec(ii_normal))./dy^2; A(ii_normal,ii_normal - 1 ) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_normal -1 ) + k_mu_vec(ii_normal))./dy^2; A(ii_normal,ii_normal - ny) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_normal -ny) + k_mu_vec(ii_normal))./dx^2; A(ii_normal,ii_periodic + ny) = dt./beta_vec(ii_normal).*1/2.*(k_mu_vec(ii_periodic +ny) + k_mu_vec(ii_normal))./dx^2; A(ii_normal,ii_normal ) = -1 - A(ii_normal,ii_periodic+1) - A(ii_normal,ii_normal-1) - A(ii_normal,ii_normal-ny) - A(ii_normal,ii_periodic+ny); end end P_vec = A\rhs; P(find(P_vec)) = P_vec(find(P_vec)); % reshape() P=P';