4
$\begingroup$

Basically I solved a problem, consequently I wanna define a function which uses part of that problem to use later on as a function. So I tried the SetDelay (:=)

fw[x_] := -2*Sqrt[2 x]*vCH2Cl2[x] - 4 x*Evaluate[D[f[x, 0], x] /. Sol];

Which yields no errors, but doesn't define a function. Then someone suggested that I just set the function with the = command. But when I define the same function as before.

fw[x_] = -2*Sqrt[2 x]*vCH2Cl2[x] - 4 x*Evaluate[D[f[x, 0], x] /. Sol];

I get the Error:

ReplaceAll::reps: "{Sol} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing. 

Any ideas?

EDIT: Since it was suggested that I add the complete try:

Sc = 18.7*10^(-6)/(1.2041*2.522^(-9)*301.15^1.462);
Sol = NDSolve[{
    D[f[x, η], η] == g[x, η],
    D[g[x, η], {η, 2}] + 
      f[x, η]*D[g[x, η], η] + 
      2*x*(D[g[x, η], η]*D[f[x, η], x] - 
         g[x, η]*D[g[x, η], x]) == 0,
    D[φ[x, η], {η, 2}] + 
      Sc*f[x, η]*D[φ[x, η], η] + 
      2*x*Sc*D[f[x, η], x]*D[φ[x, η], η] - 
      2*x*Sc*g[
        x, η]*(D[φ[x, η], x] + φ[
          x, η]) == 0,
    (*Boundary values*)
    (*η \[Rule] 0*)   
    f[x, 0] == 1.14267*Exp[-10000*x](*+((1-Exp[-10000*x])*fw[x])*),
    g[x, 0] == 1 - Exp[-10000 x],
    φ[x, 0] == 1 - Exp[-10000*x],
    (*x \[Rule] 0; Initial Condition, guesses from Blasius solution*)

        f[0, η] == 1.14267,
    g[0, η] == 0,
    φ[0, η] == 0,
    (*η \[Rule] ∞*)   
    g[x, 10] == 0,
    φ[x, 10] == 0},
   {f, g, φ}, (*Unknown Variables*)
   {x, 0, 
    1}, (*Range of x*)
   {η, 0, 10}, (*Range of η*)

   MaxStepSize -> 0.1, AccuracyGoal -> 3, 
   PrecisionGoal -> 3(*MaxStepSize\[Rule]0.01,AccuracyGoal\[Rule]4,
   PrecisionGoal\[Rule]4*), 
   Method -> {"PDEDiscretization" -> {"MethodOfLines", 
       "SpatialDiscretization" -> {"TensorProductGrid", 
         "MinPoints" -> 150}}}
   ];

and vCH2Cl2[x] is basically the same thing as in my question:

vCH2Cl2[x_] = constant*(Evaluate[
      D[φ[x, 0], ξ] /. Sol]*(-1));
$\endgroup$
6
  • 1
    $\begingroup$ What is f[x,0], include it in the question? $\endgroup$
    – zhk
    Commented Feb 8, 2017 at 8:21
  • $\begingroup$ f[x,0] is part of the previewious calculation. An interpolating function from NDsolve, sry forgot to mention $\endgroup$
    – M.Pow
    Commented Feb 8, 2017 at 8:27
  • $\begingroup$ @MMM Sry misread your comment xD... added it $\endgroup$
    – M.Pow
    Commented Feb 8, 2017 at 8:46
  • $\begingroup$ @MMM I'm sry I'm an idiot. I tried to simplify my problem but just made it worse. So now I posted the original try. As a little sidenote: The e-Functions are there so I don't the inconsistent boundary conditions error. The singular point at the beginning unfortunatly is problem related. Thanks for the help so far though. I can see you are really trying $\endgroup$
    – M.Pow
    Commented Feb 8, 2017 at 9:19
  • $\begingroup$ Is this a non-similar system and you want to plot ` D[φ[x, 0], ξ] vs x`? $\endgroup$
    – zhk
    Commented Feb 8, 2017 at 9:22

2 Answers 2

2
$\begingroup$

The short answer is that what you are looking for is With:

With[{dd = D[f[x, 0], x]},
  SetDelayed @@ Hold[ff[x_], -5*dd]
]

which is the standard way to insert evaluated expressions into held expressions as the RHS of a SetDelayed. Unfortunately SetDelayed is a scoping construct and will try to protect the x it uses as argument from the one used in the expression we insert. Thus we need an additional trick and only let SetDelayed see the xes after we inserted the expression. Evaluate will only work when it is a direct argument of a function/symbol with a Hold attribute.

If you find this complicated, yes it is. But the good news is that it is not necessary to go through all those evaluation order and scoping complications if we slightly raise the level of abstraction: the solution of a differential equation is a function, so when we extract those functions, we can work with them without ever being bothered with naming their arguments. Here is how you would do that (I'm leaving out the details in the code below which can be copied from the OPs question):

{fsol,gsol,φsol} = {f,g,φ} /. NDSolveValue[{
        D[f[x, η], η] == g[x, η],...},...},
        {f,g,φ},{x,0,1},{η, 0, 10},...]

In newer versions we have NDSolveValue, which which makes extraction of solutions functions even easier:

{fsol,gsol,φsol}=NDSolveValue[{D[f[x, η], η] == g[x, η],...},},
        {f,g,φ},{x,0,1},{η, 0, 10},...]

Either way, Nfsol, gsol and φsol will now hold the solution interpolating functions.

For an InterpolatingFunction you can get derivatives as another InterpolatingFunction for the complete domain like that:

dφdx = Derivative[1,0][φsol]

Now the variable dφdx holds the derivative of the solution with respect to its first argument. Note how well this matches the mathematical abstraction that the derivative of a function is another function, no arguments ever involved, no complications of passing, defining or even naming arguments.

If you go this path, you will find that it is one of the lucky cases where more elegant code does not only create clearer code but also more efficient one. You can of course use dφdx like a function with arguments, and e.g. plot it like this:

Plot[dφdx[x,0],{x,0,1}]

With that, we can define vCH2Cl2 like this (again making vCH2Cl2 another "mathematical" function):

With[{dφdx = dφdx,constant=N[Pi](*or whatever it is*)},
  vCH2Cl2 = Function[x,constant*(dφdx[x, 0]*(-1))]
]

This uses the same trick as above to insert the evaluated dφdx into the unevaluated body of the Function to which we set the variable vCH2Cl2. Function also is a scoping construct, but as we insert a function with no arguments, there is no scoping problem now. Thus the following would also work for the same reasons:

ClearAll[vCH2Cl2]
With[{dφdx = dφdx,constant=N[Pi](*or whatever it is*)},
  vCH2Cl2[x_] := constant*(dφdx[x, 0]*(-1));
]

But again I think the first version better matches the abstraction that we are manipulating "mathematical functions" as objects than the second and will make further manipulation or passing around of these functions easier.

$\endgroup$
6
$\begingroup$

The interpolating functions can be called separatly as SetDelay like this

f11[x_, η_] := (f /. Sol[[1, 1]])[x, η];    
g11[x_, η_] := (g /. Sol[[1, 2]])[x, η];    
p11[x_, η_] := (φ /. Sol[[1, 3]])[x, η];

Now plotting the SetDelay

Plot3D[{f11[x, η], g11[x, η], p11[x, η]}, {x, 0,1}, {η, 0, 10}, PlotRange -> Full]

enter image description here

The function of single variable can be defined like this

fw[x_] := D[p11[x, η], η] /. η -> 0;

fw[0.1]

-0.0996175

and finally, plotting it

Plot[fw[x], {x, 0, 1}]

enter image description here

Update by m_goldberg

Here is a refinement to MMM's answer that is more robust and more efficient.

This gets the interpolating functions from the solution and gives them names so they may be referenced like any other functions. No substitution is necessary, especially no substitution at every call as happens with f11, g11 and p11.

{fF, gF, φF} = Sol[[1, All, 2]];
Plot3D[{fF[u, v], gF[u, v], φF[u, v]}, {u, 0, 1}, {v, 0, 10}, PlotRange -> Full]

Here, substitution is used, but only once. Block protects the variables x and u from any previously made global assignments.

x = 42; u = 43;
Block[{x, u}, fw[x_] = D[φF[x, u], u] /. u -> 0;]
Plot[fw[x], {x, 0, 1}]

The plots give the same images as shown by MMM.

$\endgroup$
5
  • $\begingroup$ If I could I would hug you right now. I have been struggeling with this for the better part of the last 3 weeks! Thanks! $\endgroup$
    – M.Pow
    Commented Feb 8, 2017 at 9:47
  • $\begingroup$ @M.Pow Happy to help. Ask freely here but please first be sure about your question and describe it clearly. $\endgroup$
    – zhk
    Commented Feb 8, 2017 at 9:48
  • $\begingroup$ @m_goldberg What exactly do you mean by that? (sry kind of new and interessted) $\endgroup$
    – M.Pow
    Commented Feb 9, 2017 at 9:01
  • $\begingroup$ @m_goldberg I like you to edit my attempt and add your part for the benefit of new users. If you don't mind? $\endgroup$
    – zhk
    Commented Feb 9, 2017 at 10:40
  • 1
    $\begingroup$ Ok, I'll add an update. $\endgroup$
    – m_goldberg
    Commented Feb 9, 2017 at 10:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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