How to compute gradients of a data on a 3D grid?

51 次查看(过去 30 天)
Hi,
I am interested in calculating gradient of a vector, say, f at all points on a 3D grid where I have the values for each components of the vector f. The grid points are not evenly spaced in any of the dimensions. They are, in fact, points corresponding to a meshed geometry. Are there MATLAB programs already written for such an application? If not, what inbuilt functions in MATLAB are useful for this purpose? (I think that the gradent function is not useful here as it requires uniform spacing of the grid points. Is it?)

采纳的回答

Aykut Satici
Aykut Satici 2014-8-19
It is my understanding that you would like to find the gradient of a function f from R^3 to R. If you mean a vector-valued function, i.e., f: R^3 --> R^3, then you would have to find the gradient of each component of this function. In any case, the "gradient" function is indeed useful. If you look at the documentation,
one way to call this function is to specify the spacing for each dimension of f. Therefore, you can write something like this:
h1 = 0.2;
h2 = 0.1;
h3 = 0.05;
x = -3:h1:3;
y = -2:h2:2;
z = 0:h3:1;
[x,y,z] = ndgrid(x,y,z);
f = exp(-z.^2).*cos(x) + sin(y);
gradf = gradient(f,h1,h2,h3)
  3 个评论
Aykut Satici
Aykut Satici 2014-8-20
编辑:Aykut Satici 2014-8-20
Hello Pradeep,
Let us concentrate on one of the component functions of this vector function. Computing the gradient for the whole vector function will then amount to repeating the same procedure.
Do you need the gradient information at the exact points that you have the values of the function on? If not, you can interpolate your function on a uniformly spaced grid and use the "gradient" function on this interpolated function. This solution would look like the following:
x = (-3 + 6*rand(50,1));
y = (-2 + 4*rand(50,1));
z = rand(50,1);
f = exp(-z.^2).*cos(x) + sin(y);
fInterpolated = scatteredInterpolant(x,y,z,f);
h1 = 0.2;
h2 = 0.1;
h3 = 0.05;
xq = -3:h1:3;
yq = -2:h2:2;
zq = 0:h3:1;
[xq,yq,zq] = ndgrid(xq,yq,zq);
fgrid = fInterpolated(xq,yq,zq);
[gradfx,gradfy, gradfz] = gradient(fgrid,h1,h2,h3)
If you would like the gradient at the exact point that you have the value of the function on, then you would have to write a simple difference code. The "fInterpolated" variable is still useful here because with that object you can compute the value of the function at any point in R^3. In particular, it will agree with the value of the function at the sample points. Thus, for example, you can loop over your points and compute the gradient at each of these points. Here I have used the central difference method:
dx = 0.1;
dy = 0.1;
dz = 0.1;
gradfx = zeros(length(f),1);
gradfy = zeros(length(f),1);
gradfz = zeros(length(f),1);
for i = 1:length(f)-1
gradfx(i) = 1/2 * ( fInterpolated(x(i)+dx,y(i),z(i)) - ...
fInterpolated(x(i)-dx,y(i),z(i)) );
gradfy(i) = 1/2 * ( fInterpolated(x(i),y(i)+dy,z(i)) - ...
fInterpolated(x(i),y(i)-dy,z(i)) );
gradfz(i) = 1/2 * ( fInterpolated(x(i),y(i),z(i)+dz) - ...
fInterpolated(x(i),y(i),z(i)-dz) );
end
In this latter approach, for example, gradfx(i) would be the partial derivative of f in the x-direction and [gradfx(i), gradfy(i), gradfz(i)] would be the gradient of f at the point (x(i),y(i),z(i)).
Pradeep Bhat
Pradeep Bhat 2014-8-25
Aykut,
thanks for further clarification.
I agree. Using interpolation and then finite differences to obtain the gradients works in many of my cases (exceptions are cases where the gradients are off mainly at some nodes along boundary faces). Your former approach would work well for cases where the mesh is a rectangular box/cuboid. In cases where a more complex body is meshed, the latter approach works.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Surface and Mesh Plots 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by