Message Boards Message Boards

How to use FindRoot output as input to NDSolve for 1st order DFEQ?

GROUPS:

Consider the system NDSolve[{y'[x]==g[y[x],x],y[0]==q},y[x],{x,0,xf}]; g[x,y[x]]=Module[{gs,res,g0=0},gs=FindRoot[h[x,y[x]]==0,{g.g0}];res=g/.gs[[1]];Return[res]

This always gives error messages of the form FindRoot::nlnum: "The function value {8.51808*10^10-1.\ (0.0333333\x+0.333333\y[x])^(2/3)\ (0.05\x+y[x])^(1/3)} is not a list of numbers with dimensions {1} at {p2$97812} = {0.05`}." where all the above numbers are coming from a fairly complicated expression for h

It seems clear to me that NDSolve regards g[x,y[x]] as an analytical function rather than the numerical result of a calculation. It is probably doing this in order to calculate the derivative of g with respect to x.

If this is what is going on, is there some way to force NDSolve to use the chord method to calculate the derivative of g with respect to x? Only FindRoot seems to be able to get a numerical value of g from the expression for h.

POSTED BY: Robert Curl
Answer
2 years ago

THe code above will of course not run as given (no definition for h). Also there is a typ0 {g.g0} where certainly you want a comma separator {g,g0}. The upshot is I cannot replicate the actual issue. I will take a guess that first you need to make g into a function that only exists for explicitly numeric input. That can be done as below.

g[x_?NumberQ, y_?NumberQ] = ...

There seem to be other issues (e.g. g does not seem to be a variablebut rather a function). Really you should post with full input to replicate the problem; this is simply too confused as it stands.

POSTED BY: Daniel Lichtblau
Answer
2 years ago

Thank you for your reply Mr. Lichtblau. I apologize for all the mistakes. I will follow up on your suggestions and post the complete code in the future. In the meantime, I have managed to get the program to work by setting up a grid of values of y[x] and x using FindRoot to populate the grid with values g and then create a 2D InterpolatingFunction . I replace the g function that calls FindRoot directly by the InterpolatingFunction. It feels like a kluge to me, but it works.

POSTED BY: Robert Curl
Answer
2 years ago

It sounds like a reasonable approach. There might be better ways but when you have something that works well enough, you have to ask whether it is worth the time to improve on it. Often this decision depends on whether you are doing a one-off problem vs. creating a method you may need to scale to larger size down the road.

POSTED BY: Daniel Lichtblau
Answer
2 years ago

Please see this article:

http://support.wolfram.com/kb/12502

for an explanation of why ?NumericQ had to be added

POSTED BY: Sean Clarke
Answer
2 years ago

Dear Mr. Clarke,

It works like a charm!

Thank you,

Bob Curl

POSTED BY: Robert Curl
Answer
2 years ago

Group Abstract Group Abstract