Search code examples
matlabplotsymbolic-math

Plot symbolic equation using standard plot function in Matlab


In order to obtain a graphical representation of the behaviour of a fluid it is common practice to plot its streamlines.

For a given two-dimensional fluid with speed components u = Kx and v = -Ky (where K is a constant, for example: K = 5), the streamline equation can be obtained integrating the flow velocity field components as follows:

Streamline equation: ∫dx/u = ∫dy/v

The solved equation looks like this: A = B + C (where A is the solution of the first integral, B is the solution of the second integral and C is an integration constant).

Once we have achieved this, we can start plotting a streamline by simply assigning a value to C, for example: C = 1, and plotting the resulting equation. That would generate a single streamline, so in order to get more of them you need to iterate this last step assigning a different value of C each time.

I have successfully plotted the streamlines of this particular flow by letting matlab integrate the equation symbolically and using ezplot to produce a graphic as follows:

syms x y

K = 5; %Constant.

u = K*x; %Velocity component in x direction.
v = -K*y; %Velocity component in y direction.

A = int(1/u,x); %First integral.
B = int(1/v,y); %Second integral.

for C = -10:0.1:10; %Loop. C is assigned a different value in each iteration.
    eqn = A == B + C; %Solved streamline equation.
    ezplot(eqn,[-1,1]); %Plot streamline.
    hold on;
end

axis equal;
axis([-1 1 -1 1]);

This is the result:

The problem is that for some particular regions of the flow ezplot is not accurate enough and doesn't handle singularities very well (asymptotes, etc.). That's why a standard "numeric" plot seems desirable, in order to obtain a better visual output.

The challenge here is to convert the symbolic streamline solution into an explicit expression that would be compatible with the standard plot function.

I have tried to do it like this, using subs and solve with no success at all (Matlab throws an error).

syms x y

K = 5; %Constant.

u = K*x; %Velocity component in x direction.
v = -K*y; %Velocity component in y direction.

A = int(1/u,x); %First integral.
B = int(1/v,y); %Second integral.

X = -1:0.1:1; %Array of x values for plotting.

for C = -10:0.1:10; %Loop. C is assigned a different value in each iteration.
    eqn = A == B + C; %Solved streamline equation.
    Y = subs(solve(eqn,y),x,X); %Explicit streamline expression for Y.
    plot(X,Y); %Standard plot call.
    hold on;
end

This is the error that is displayed on the command window:

Error using mupadmex
Error in MuPAD command: Division by zero.
[_power]

Evaluating: symobj::trysubs

Error in sym/subs>mupadsubs (line 139)
G =
mupadmex('symobj::fullsubs',F.s,X2,Y2);

Error in sym/subs (line 124)
G = mupadsubs(F,X,Y);

Error in Flow_Streamlines (line 18)
Y = subs(solve(eqn,y),x,X); %Explicit
streamline expression for Y.

So, how should this be done?


Solution

  • Since you are using subs many times, matlabFunction is more efficient. You can use C as a parameter, and solve for y in terms of both x and C. Then the for loop is very much faster:

    syms x y
    
    K = 5; %Constant.
    
    u = K*x; %Velocity component in x direction.
    v = -K*y; %Velocity component in y direction.
    
    A = int(1/u,x); %First integral.
    B = int(1/v,y); %Second integral.
    
    X = -1:0.1:1; %Array of x values for plotting.
    
    syms C % C is treated as a parameter
    eqn = A == B + C; %Solved streamline equation.
    
    % Now solve the eqn for y, and make it into a function of `x` and `C`
    Y=matlabFunction(solve(eqn,y),'vars',{'x','C'})
    
    for C = -10:0.1:10; %Loop. C is assigned a different value in each iteration.
        plot(X,Y(X,C)); %Standard plot call, but using the function for `Y`
        hold on;
    end