I am getting Error: Error using * Arguments must be 2-D, or at least one argument must be scalar.

22 views (last 30 days)
I have a 3D function where I am testing taking derivative along x,y, and z direction. My issue is that taking derivative wrt z is giving an error
clearvars; clc; close all;
Nx = 4;
Ny = 4;
Nz = 4;
%-----
Lx = 2*pi; %8; %128;
Ly = 2*pi;
% Set the number of grid points
%Set-up grids:
x = (0:Nx-1)/Nx*2*pi;
y = (0:Ny-1)/Ny*2*pi;
kx = (2*pi/Lx)*([0:Nx/2-1 , -Nx/2:-1]);
ky = (2*pi/Ly)*([0:Ny/2-1 , -Ny/2:-1]);
zgl = -cos(pi*(0:Ny)/Ny)'; %Gauss-Lobatto chebyshev points
[X,Y,Z] = meshgrid(x,y,zgl);
%Chebyshev matrix for Gauss-Lobatto
VGL = cos(acos(zgl(:))*(0:Nz));
dVGL = diag(1./sqrt(1-zgl.^2))*sin(acos(zgl)*(0:Nz))*diag(0:Nz);
dVGL(1,:) = (-1).^(1:Nz+1).*(0:Nz).^2;
dVGL(Nz+1,:) = (0:Nz).^2;
%Diferentiation matrix for Gauss-Lobatto points
Dgl = dVGL/VGL;
D = Dgl; %first-order derivative matrix
%------------------
ubar = Z.^2 .* sin( (2*pi / Lx) * X) .* sin( (2*pi / Ly) * Y) ; %Y^2 * sin( (2*pi / Lx) * x);
uh = fft(fft(ubar,[],2),[],1); %fft along x and y only
duhdxk = derivk(uh, kx); %works
duhdx = real(ifft(ifft(duhdxk,[],2),[],1));
exactDx = (2*pi)/(Lx)* Z.^2 .* cos( (2*pi / Lx) * X) .* sin( (2*pi / Ly) * Y);
DEx = exactDx -duhdx;
% y derivative
duhdyk = derivk(uh, ky'); %works
duhdy = real(ifft(ifft(duhdyk,[],2),[],1));
exactDy = (2*pi)/(Ly)* Z.^2 .* sin( (2*pi / Lx) * X) .* cos( (2*pi / Ly) * Y);
DEy = exactDy - duhdy;
%%
%z derivative
for e = 1:Nz
duhdzk(:,:,e) = D * uh(:,:,e); % ERROR: D is 5x5 size and uh is 4x4x5 size
end
exactDz = 2 .* Z .* sin( (2*pi / Lx) * X) .* sin( (2*pi / Ly) * Y);
I am aware the error comes from multiplying D an uh with the incorrect sizes so I tried creating a for loop to change the uh size to 4x5 but it's not working.
Full error:
Error using *
Arguments must be 2-D, or at least one argument must be scalar. Use TIMES (.*) for elementwise
multiplication, or use PAGEMTIMES to apply matrix multiplication to the pages of N-D arrays.
Error in FourierCheby3D (line 77)
duhdzk(:,:,e) = D * uh(:,:,e);
  7 Comments
Jamie Al
Jamie Al on 8 Apr 2022
First of all thanks for the help.
I don't know if you're able to run my code, but you can see I am trying to compare numerical derivatives to exact ones. So, my x and y derivatives are matching (taking derivatives in Fourier space). But, the third derivative along z is creating an issue. I am taking the derivative along z using chebyshev derivative matrix D which usually has a size of Nz+1 x Nz+1. While, your suggestions work, now I can't compare between my exact derivative and the numerical one. So, I get the error:
Array dimensions must match for binary array op.
Error in FourierCheby3D (line 86)
DEz = exactDz - duhdz;
I guess I am not appraoching this correctly.
This comes from the definition of the chebyshev matrix and I am following with a textbook, so I am not sure if I should change things here:
VGL = cos(acos(zgl(:))*(0:Nz));
dVGL = diag(1./sqrt(1-zgl.^2))*sin(acos(zgl)*(0:Nz))*diag(0:Nz);
dVGL(1,:) = (-1).^(1:Nz+1).*(0:Nz).^2;
dVGL(Nz+1,:) = (0:Nz).^2;

Sign in to comment.

Accepted Answer

Jamie Al
Jamie Al on 15 Apr 2022
So I was able to resolve this issue, by indexing in a very specific way:
[X,Z,Y] = meshgrid(x,zgl,y); %now this is a Z-by-X-by-Y 3D grid
%Taking FFT of X and Y is changed to 2nd and 3rd dimension instead
uh = fft(fft(ubar,[],2),[],3);
%Thus, x derivative is
duhdxk = derivk(uh, kx);
%y derivative
duhdyk = derivk(uh, reshape(ky, [1,1,Ny]));
%z derivative
for e = 1:Nz
duhdzk(:,:,e) = D * uh(:,:,e);
end
duhdz = real(ifft(ifft(duhdzk,[],2),[],3));
This works, however, I am not sure if I can index things correctly with a
[X,Y,Z] = meshgrid(x,y,zgl);

More Answers (0)

Categories

Find more on Fourier Analysis and Filtering in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!