I get into trouble when I use ContourPlot
to draw streamlines in a free surface flow domain.
This is my data.The data are a little bit big, please be patient. Here is my code:
Get["C:\\Users\\Administrator\\Desktop\\...\\data.mx"]
Firstly, I plot the free surface, which is a function of x.
profile = Plot[mdfun[x, 6], {x, 0, 2*Sqrt[2] \[Pi]},
PlotRange -> {{0, 2*Sqrt[2] \[Pi]}, {0, 2}},
ImageSize -> 400,Frame -> True, Axes -> False,
PlotStyle -> {Directive[Black, Thick]},
FrameTicks -> {{{0, 0.2, 0.4, 0.6, 0.8, {1, "1.0"}, 1.2, 1.4, 1.6, 1.8}, None},
{{0, {1, ""}, 2, {3, ""}, 4, {5, ""}, 6, {7, ""}, 8}, None}}]
hx = Derivative[1, 0][mdfun]; (*get the first derivative with respect to x*)
hxxx = Derivative[3, 0][mdfun]; (*get the third derivative with respect to x*)
scaledA[d_, B_, k_, e_, hx_, h_, hxxx_] := (-3*d*(1 + B*k) *hx )/((k + h + B*k*h)^3*e) - 3*1/e*hxxx - 3*1/e*hx;
A = scaledA[1, 1, 0.1, 0.05, hx[x, 6], mdfun[x, 6], hxxx[x, 6]]; (*calculate a term of stream function*)
scaled\[Phi][A_, z_, h_, B_, k_, hx_, e_, m_] := A*(z^3/6 - (h*z^2)/2) + m ((1 + B k)*k*hx*z^2)/((k + h + B k h)^2*e); (* stream function *)
sl = ContourPlot[scaled\[Phi][A, y, mdfun[x, 6], 1, 0.1, hx[x, 6], 0.05, 1] == Range[0.1, 1.3, 0.2],{x, 0, 2*Sqrt[2] \[Pi]}, {y, 0, mdfun[x, 6]}, ImageSize -> 400,ContourStyle -> {
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin]
}, Frame -> False (*,PerformanceGoal\[Rule]"Speed"*)] (*plot seven streamlines *)
NOTE: ContourPlot
takes about 60s on a common PC, you can uncomment PerformanceGoal\[Rule]"Speed"
to speed up. Please be patient...The reason why I plot 7 streamlines is to show the different directions of the arrows drawn
Then, I got the streamlines
If I use RegionFunction
to explicitly specify the domain drawn.
sl2 = ContourPlot[scaled\[Phi][A, y, mdfun[x, 6], 1, 0.1, hx[x, 6], 0.05, 1] == Range[0.1, 1.3, 0.2],
{x, 0, 2*Sqrt[2] \[Pi]}, {y, 0, mdfun[x, 6]}, ImageSize -> 400,
RegionFunction -> Function[{x, y, z}, 0 <= y <= mdfun[x, 6]],
ContourStyle -> {
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin],
Directive[Black, Thin]
}, Frame -> False(*,PerformanceGoal\[Rule]"Speed"*)]
I still get the same plot as above.
Then I add arrow for the streamlines
asl = sl /. Line[x_] :> {Arrowheads[{{0.02, 0.2}, {0.02, 0.4}, {0.02, 0.6}, {0.02, 0.85}}], Arrow[x]}
And I got the following plot
Last, I combine the profile and streamlines.
Show[profile, asl]
Here I have four questions:
(1) How can I specify the upper limit in a free surface problem? Here I employed {y, 0, mdfun[x, 6]}
;
(2) Is there any method to find all the representative or distinctive streamlines instead of assign different values to ContourPlot
every time;
(3) Frankly speaking, I am not sure whether my streamline is correct or has the completed range. Because I drew them by restricting the y-range by {y, 0, mdfun[x, 6]}
in the first code, in addition, by RegionFunction -> Function[{x, y, z}, 0 <= y <= mdfun[x, 6]]
in the second code sl2
. I really do not understand the difference between them in my case.
(4)This question has been solved by @ bbgodfrey. As you can see, the orientation of the arrows of the streamlines is different from each other. I have tried to change the sign of 0.02
in Arrowheads
, but I still can not get the same orientation anyway, say towards the right. Can any one tell me how can I manipulate the arrow individually for each streamline?
Thank you for your patience!
CountourPlot[]
and re-ask without all the burden $\endgroup$sl = ContourPlot[Cos[x] + 1/2 y^2, {x, -2 π, 2 π}, {y, -π, π}, Contours -> 5, AspectRatio -> Automatic, ContourStyle -> Directive[Black, Opacity[1]], ContourShading -> None]
$\endgroup$Contours->5
:). BTW, what is your mean by "based on which side of the line has the larger function value"? As we known, for streamline or the contour lines inContourPlot
, the value of each curve is a constant. $\endgroup$