Reputation: 867
I have spent all weekend trying to do something in Matlab that seems like it should be very simple. I am not an experienced Matlab user. I want to calculate flow through a tank. This requires me to define a rectangular geometry (the tank), then divide it into cells/elements (a grid made up of x/y coordinates). I can do this no problem:
Lx = 300; % Geometry length in x direction
Ly = 150; % Geometry length in y direction
Nx = 10; Ny = Nx; % Number of nodes in x and y direction
% Grid
x = linspace(0,Lx,Nx); y = linspace(0,Ly,Ny);
delta_x = Lx/(Nx-1); delta_y = Ly/(Ny-1);
Here's the problem. Now I want to add an inlet/pipe to the tank--a second rectangle joined to the first. No matter what I do, there are "holes" in the geometry where there are no points. Also, there are never grid points along y=0, which is a problem.
I have tried (1) this (below), which results in a weird-looking check-mark shaped grid:
c = [0 150 150 0 ]; % x dimension of large tank
d = [0 0 150 150]; % y dimension of large tank
v = [0 20 0 20 ]; % x dimension of inlet
w = [150 200 200 0]; % y dimension of inlet
x = union(c(1,:), v(1,:));
y = union(d(1,:), w(1,:));
grid_val = 10;
figure('Color','w');
[X,Y] = meshgrid(min(x):grid_val:max(x), min(y):grid_val:max(y));
I tried (2) simply making two arrays: one of all x coordinates and one of all y coordinates. Neither method works. Finally, I have tried (3) concatenating grids after making them and this only gives me errors that the grids are of different size, so can't be concatenated. Any advice would be very welcome.
Upvotes: 1
Views: 906
Reputation: 1140
I think you will need to take a slightly different approach here. Create your meshgrid()
such that the X
and Y
values completely contain all parts of the tank and intake. Your last line seems fine.
Next you'll have to create an additional masking matrix the size of X
(or Y
) to track whether each coordinate point is part of your tank or not.
tankMask = zeros(size(X));
Now just loop over the elements of X
and Y
and set the corresponding value of tankMask
to 1
if it's part of the tank and leave it set to 0
otherwise.
You should be able to use Matlab's inpolygon()
to accomplish this:
for i = 1:numel(X)
if inpolygon(X(i),Y(i),c,d) || inpolygon(X(i),Y(i),v,w)
tankMask(i) = 1;
end
end
Now, you still have all those grid points, but you also have a mask telling you whether or not each X,Y
value is part of your tank. Verify this with surf(X,Y,tankMask)
.
Also I'm not sure exactly what you want your intake to look like, but this looks closer to what you may be going for:
v = [0 0 20 20]; % x dimension of inlet
w = [150 200 200 150]; % y dimension of inlet
Here I've plotted surf(X,Y, tankMask)
with the mask created as described and with my suggested modified v
and w
vectors.
This method is not particularly efficient and will run into problems as your grid size gets smaller. It's simply a quick and dirty approach. If you need a very fine grid, you will want a more refined method.
Edit: I know it looks like the points along y = 160
are included in the tank (as well as the intake at x = 30
) but that's just an artifact of the grid size (10 unit spacing) and how the 3D plot is visualized.
Upvotes: 1