4
$\begingroup$

I solved Laplace's equation over a square region. There are Dirichlet BC's (the top wall is fixed at 100, the other walls are fixed at 0).

Plotted result of Laplace's equation is below:

result

I took the gradient and plotted the result like this:

gradientfield = -Grad[sol[x, y], {x, y}];

StreamDensityPlot[gradientfield, {x, y} \[Element] mesh, StreamStyle -> Black, Mesh -> None, ColorFunction -> "Rainbow", PlotRange -> All, 
 PlotLegends -> Automatic]

Here StreamStyle -> Black gets ignored:

style_broken

But if I switch {x, y} \[Element] mesh to {x, 0, 10}, {y, 0, 10} then everything is fine:

style_ok

Does anyone know what makes me lose control over StreamStyle? It is important for me to use {x, y} \[Element] mesh because I have several solutions in which there are openings in the middle of a region. Using {x, 0, 10}, {y, 0, 10} puts streamlines over the empty region. I tested it on Mathematica 10.3.

P.S. I found a way around this. For this I break StreamDensityPlot into StreamPlot (where I use StreamStyle -> Black) and DensityPlot. Then I overlap them with Show[]. Still, I would want to know what the problem with StreamDensityPlot is.

$\endgroup$
3
$\begingroup$

This problem can fixed by just using Evaluate@gradientfield.

But the main issue for me is that when, I use {x, y} ∈ mesh

StreamDensityPlot[Evaluate@gradientfield, {x, y} ∈ mesh, StreamStyle -> Black,
 Mesh -> None, ColorFunction -> "Rainbow", PlotRange -> All, PlotLegends -> Automatic];

I get an error,

StreamDensityPlot::idomdim: {x,y}[Element]mesh does not have a valid dimension as a plotting domain.

But when I do this {x, y} ∈ square, everything works fine,

StreamDensityPlot[Evaluate@gradientfield, {x, y} ∈ square, 
 StreamStyle -> Black, Mesh -> None, ColorFunction -> "Rainbow", 
 PlotRange -> All, PlotLegends -> Automatic]

enter image description here

This question is linked here.

$\endgroup$
  • $\begingroup$ Could you please explain what exactly Evaluate@gradientfield changes? I just tried your code and I don't get that error with my Mathematica 10.3. I believe it is because of the bug with mesh that was introduced after the version 10.3. $\endgroup$ – space bobcat Apr 27 '17 at 6:36
  • $\begingroup$ @ViacheslavPlotnikov Does Evaluate@gradientfield fixed your problem? $\endgroup$ – zhk Apr 27 '17 at 6:37
  • $\begingroup$ It does solve the problem. Thank you very much! I still don't see what exactly disables StreamStyle in the first place and how Evaluate@gradientfield fixes it. $\endgroup$ – space bobcat Apr 27 '17 at 6:40
  • $\begingroup$ @ViacheslavPlotnikov you can find the explanation here mathematica.stackexchange.com/questions/8637/… $\endgroup$ – zhk Apr 27 '17 at 6:42
  • $\begingroup$ You are very helpful. Thanks! $\endgroup$ – space bobcat Apr 27 '17 at 6:44
5
$\begingroup$

The issue is similar to the classic Plot draws list of curves in same color when not using Evaluate.

Plotting is one of the more dynamic areas of development in Mathematica, so this explanation is based on V11.1.

The initial source of the trouble is that plotting functions such as StreamDensityPlot hold their arguments, that is, the expression is what they get and not its value. In StreamDensityPlot, argument is used as is to determine its type and the subsequent styling of the plot. It probably should evaluate it at a numerical point in the domain, but that is not how it is currently programmed to behave. In OP's case, the argument is a symbol and not a vector and Length[gradient] is 0. This length is passed to a styling function, which thinks, "That's ridiculous, I'm defaulting to the default styling," if I may anthropomorphize.

Here a comparison of using the symbol gradientfield as an argument with passing its value with Evaluate@gradientfield.

Trace[
 StreamDensityPlot[gradientfield, {x, y} ∈ mesh, 
  StreamStyle -> Black, Mesh -> None, ColorFunction -> "Rainbow", 
  PlotRange -> All, PlotLegends -> Automatic],
 _Charting`customVectorStyle
 ]

Mathematica graphics

Trace[
 StreamDensityPlot[Evaluate@gradientfield, {x, y} ∈ mesh, 
  StreamStyle -> Black, Mesh -> None, ColorFunction -> "Rainbow", 
  PlotRange -> All, PlotLegends -> Automatic],
 _Charting`customVectorStyle
 ]

Mathematica graphics

In the OP's case, the styling function evaluates to an empty list, which is then replaced by the default styling of stream lines:

Mathematica graphics

One can fix the problem with any method that passes the value of gradientfield, such as Evaluate@gradientfield. One can also use With:

With[{g = gradientfield}, 
 StreamDensityPlot[g, {x, y} ∈ mesh, StreamStyle -> Black, Mesh -> None, 
  ColorFunction -> "Rainbow", PlotRange -> All, PlotLegends -> Automatic]]

However, passing the option Evaluated -> True has no effect. The option is not a documented option of SteamDensityPlot, but it is present among Options[StreamDensityPlot] and generates no errors.

The documentation of SteamDensityPlot discusses uses of Evaluate, but not this specific issue. From my own point of view as a user, even given the long-standing fame of the question linked at the top of my answer, I consider this an unnecessary constraint on usage (i.e., a bug).


Test Code

The OP did not supply test code so I made this up:

Needs["NDSolve`FEM`"];
gradientfield = {x, y};
mesh = ToElementMesh[Rectangle[]];
StreamDensityPlot[gradientfield, {x, y} ∈ mesh, 
 StreamStyle -> Black, Mesh -> None, ColorFunction -> "Rainbow", 
 PlotRange -> All, PlotLegends -> Automatic, Evaluated -> True]
$\endgroup$
  • $\begingroup$ Thanks, Michael E2. That is a very deep explanation. I will make sure to include the code into all of my future questions. $\endgroup$ – space bobcat Apr 27 '17 at 21:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.