# Why ReplaceAll behave differently in very similar VectorPlot3D situations?

Posted 10 months ago
1022 Views
|
3 Replies
|
1 Total Likes
|
 I have a vector field named nqvrbmmf[mu0, a, b, c, x, y, z]. It is basically the magnetic field of a cube with sides a, b, c and the origin of the Cartesian coordinate system is at the center of the cube. When I display the field with VectorPlot3D, I am not assigning the parameters beforehand, but Postfix them with ReplaceAll like: VectorPlot3D[ nqvrbmmf[mu0, a, b, c, x, y, z] , {x, -1.5*a, 5.5*a + 4*gap}, {y, -2*b, 2*b}, {z, -3.5*c, 1.5*c + R}, VectorPoints -> {40, 20, 30}, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> {{-0.015, 0.059}, {-0.02, 0.02}, {-0.035, 0.115}}] // ReplaceAll[#, {mu0 -> 10^6, a -> 0.01, b -> 0.01, c -> 0.01, gap -> 0.001, R -> 0.1}] & // Quiet // AbsoluteTiming and I get a nice little plot: I want to move the origin of the Cartesian to the z=-0.1 point and display the field as: VectorPlot3D[ nqvrbmmf[mu0, a, b, c, x, y, z - R] , {x, -1.5*a, 5.5*a + 4.0*gap}, {y, -2.0*b, 2.0*b}, {z, -3.5*c, 1.5*c + R}, VectorPoints -> {40, 20, 30}, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> {{-0.015, 0.059}, {-0.02, 0.02}, {-0.035, 0.115}}] // ReplaceAll[#, {mu0 -> 10^6, a -> 0.01, b -> 0.01, c -> 0.01, gap -> 0.001, R -> 0.1}] & // Quiet // AbsoluteTiming and I get another nice little plot like: All looks good. Now I would like to refer to the coordinates of the field by {x1,y1,z1}, instead of the {x,y,z-R} , so I do a TransformedField transformation: tnqvrbmmf[mu0_, a_, b_, c_, x1_, y1_, z1_] = TransformedField["Cartesian" -> "Cartesian", nqvrbmmf[mu0, a, b, c, x, y, z - R], {x, y, z} -> {x1, y1, z1}]; and checking it with a Point and the parameters, like: In[13]:= tnqvrbmmf[mu0, a, b, c, x1, y1, z1] //. {mu0 -> 10^6, a -> 0.01, b -> 0.01, c -> 0.01, x1 -> -0.015, y1 -> -0.02, z1 -> -0.035, gap -> 0.001, R -> 0.1} Out[13]= {9.90952, 13.2127, 58.4381} Looks ok, so I try to display it as I done previously: VectorPlot3D[ tnqvrbmmf[mu0, a, b, c, x1, y1, z1] , {x1, -1.5*a, 5.5*a + 4.0*gap}, {y1, -2.0*b, 2.0*b}, {z1, -3.5*c, 1.5*c + R}, VectorPoints -> {40, 20, 30}, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> {{-0.015, 0.059}, {-0.02, 0.02}, {-0.035, 0.115}}] // ReplaceAll[#, {mu0 -> 10^6, a -> 0.01, b -> 0.01, c -> 0.01, gap -> 0.001, R -> 0.1}] & // Quiet // AbsoluteTiming However now Mathematica thinks for more than 2 magnitudes of time and throws out all the values and gives me an empty box, like: The interesting thing is that if make the parameters' assignment before the VectorPlot3D, then I get the right plot, like:  mu0 = 10^6; a = 0.01; b = 0.01; c = 0.01; gap = 0.0099; R = 0.1; VectorPlot3D[ tnqvrbmmf[mu0, a, b, c, x1, y1, z1] , {x1, -1.5*a, 5.5*a + 4.0*gap}, {y1, -2.0*b, 2.0*b}, {z1, -3.5*c, 1.5*c + R}, VectorPoints -> {40, 20, 30}, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> {{-0.015, 0.059}, {-0.02, 0.02}, {-0.035, 0.115}}] // Quiet // AbsoluteTiming very quickly. So, what am I doing wrong with ReplaceAll after TransformedField is done? Thanks ahead, János
3 Replies
Sort By:
Posted 10 months ago
 suggest you try looking at the values you're trying to plot.
 I do not see a problem there. If I discretize it like: Clear[mu0, a, b, c, gap, R] a = b = c = 0.01; gap = 0.00106; R = 0.1; mu0 = 10^6; lsttnqvrbmmf = ParallelTable[{{x1, y1, z1}, tnqvrbmmf[mu0, a, b, c, x1, y1, z1]}, {x1, -1.5*a, 5.5*a + 4.0*gap, gap}, {y1, -2.0*b, 2.0*b, gap}, {z1, -3.5*c, 1.5*c + R, gap}] ; and display the data with ListVectorPlot3D, I am getting the same kind of plot. ListVectorPlot3D[lsttnqvrbmmf, VectorPoints -> {40, 20, 30}, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> {{-0.015, 0.059}, {-0.02, 0.02}, {-0.035, 0.115}}] so, I still suspecting that the TransformedField-ed field is somewhat different for VectorPlot3D than was the original and that can cause problems for ReplaceAll, does not matter how I do want to employ it, PostFix or not.
 Janos,I believe your problem is one of evaluation order. By turning off the messages (Quiet). You are obscuring the errors that you get. VectorPlot3D holds its inputs. When you transform the field, you get an unevaluated transformation. When VectorPlot3D substitutes in values, it breaks the transformed field.for example, I created a field from an example in the documentation: nqvrbmmf[mu0_,a_,b_,c_,x_,y_,z_]:=Evaluate[1000*D[a*Sin[(b+c)x y z],{{x,y,z}}]] tfld = TransformedField["Cartesian"->"Cartesian",nqvrbmmf[mu0,a,b,c,x,y,z-R],{x,y,z}->{x1,y1,z1}] the output is {1000 a (b + c) y1 (-R + z1) Cos[(b + c) x1 y1 (-R + z1)], 1000 a (b + c) x1 (-R + z1) Cos[(b + c) x1 y1 (-R + z1)], 1000 a (b + c) x1 y1 Cos[(b + c) x1 y1 (-R + z1)]} if you use tfld in your plot, it will work fine because the expression is fully evaluated: VectorPlot3D[ With[{mu0 = 0, a = 0.01, b = 0.01, c = 0.01, R = .5}, tfld], {x1, -1, 1}, {y1, -1, 1}, {z1, -1, 1}, VectorPoints -> 5, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> All] Note that I used With[] because doing a replace later is problematic because VectorPlot3D wants to compute numerical values and you really want to have the expression defined and ready to go before the plot function -- you only got away with it in your examples because of the delayed evaluation.Now if you try the same thing using the UNEvaluated form, you will break the plot: VectorPlot3D[ With[{mu0 = 0, a = 0.01, b = 0.01, c = 0.01, R = .5}, TransformedField["Cartesian" -> "Cartesian", nqvrbmmf[mu0, a, b, c, x, y, z - R], {x, y, z} -> {x1, y1, z1}]], {x1, -1, 1}, {y1, -1, 1}, {z1, -1, 1}, VectorPoints -> 5, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> All] This code fails to plot because VectorPlot3D substitutes the values for x1,y1,and z1 in BEFORE evaluating the TransformedField so the transformation makes no sense. You can see this by examining the stack trace when it throws an error: TransformedField[ "Cartesian" -> "Cartesian", {0.2 y (-0.5 + z) Cos[0.02 x y (-0.5 + z)], 0.2 x (-0.5 + z) Cos[0.02 x y (-0.5 + z)], 0.2 x y Cos[0.02 x y (-0.5 + z)]}, {x, y, z} -> {-0.9995, -0.9995, -0.9995}] Note that the x1,y1, and z1 became numbers BEFORE the transformation. This is what is happening to you in your example.To fix it, force the Evaluation to happen first-- this code works. VectorPlot3D[ Evaluate[With[{mu0 = 0, a = 0.01, b = 0.01, c = 0.01, R = .5}, TransformedField["Cartesian" -> "Cartesian", nqvrbmmf[mu0, a, b, c, x, y, z - R], {x, y, z} -> {x1, y1, z1}]]], {x1, -1, 1}, {y1, -1, 1}, {z1, -1, 1}, VectorPoints -> 5, BoxRatios -> Automatic, Axes -> True, PlotLegends -> Automatic, PlotRange -> All] So long story, short -- you should wrap an Evaluate around the plot argument and I think you are best to use a With[] instead of a ReplaceAll because with Replace you are trying to delay evaluation until after the replace but the TransformedField does not like the delayed evaluation because numbers get substituted in too early. I hope this helps.Regards,Neil