Message Boards Message Boards

Why ReplaceAll behave differently in very similar VectorPlot3D situations?

GROUPS:

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: enter image description here

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: enter image description here

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: enter image description here

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. enter image description here

So, what am I doing wrong with ReplaceAll after TransformedField is done? Thanks ahead, János

POSTED BY: Janos Lobb
Answer
4 months ago

suggest you try looking at the values you're trying to plot.

POSTED BY: Frank Kampas
Answer
4 months ago

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}}]

enter image description here

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.

POSTED BY: Janos Lobb
Answer
4 months ago

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

POSTED BY: Neil Singer
Answer
4 months ago

Group Abstract Group Abstract