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

30 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)

Community Treasure Hunt

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

Start Hunting!