我需要使用NDSolve,而NDSolve又将来自另一个ODE的解决方案用作另一个NDSolve的输出函数。
如果我使用NDSolve中第一个微分方程的精确解,那就没关系。但是当我以函数的形式使用相同的解决方案(使用InterpolatingFunction)时,它不起作用。
我相信,它与NDSolve输出的结构有关。有谁能请赐教我这个。会有很大的帮助!
代码是:
feq = 2 V alpha fip F''[fi] - (V^2 - (V^2 + sigma - 2 fi) (F'[fi])^2 + (F'[fi])^4
Frange[lo_, hi_] :=
Module[{fii, sol},
sol = NDSolve[{(feq == 0 /.fi -> fii), F[0] == 0}, F, {fii, lo, hi}]]
eqpois = fi''[x] == ne[x] - F[fi[x]]/.sol
NDSolve[{eqpois, fi'[0] == 0, fi[0] == 0}, fi, {x,0,1}]
这里为了找到Fφ,我需要求解feq的第一个diff eq,它由函数Frange [lo,hi]内的NDSolve求解。然后在第二个方程eqpois中使用该解决方案,该方程必须再次使用NDSolve来解决。问题出现在第二个NDSolve中,它不会产生结果。如果我在eqopis中使用Fφ的解析解,那么就没有问题了。
示例问题
我做了一点实验。我们来看一个耦合的ODE的例子
初始条件为1st eqn : dg/dx = 2f(g)
的 g(0) = 1
函数f(y)
是来自另一个ODE的解决方案,比如说,
2nd eqn : df/dy = 2y
f(0) = 0
第二个ODE的解是f(y) = y^2
,当放入第一个ODE时变为
dg/dx = 2 g^2
,最终解决方案为g(x) = 1/(1-2x)
问题:
当我使用DSolve时,它会正确找到答案
In[39]:= s = DSolve[{f'[y] == 2 y, f[0] == 0}, f, y]
Out[39]= {{f -> Function[{y}, y^2]}}
In[40]:= ss = DSolve[{g'[x] == 2 (f[g[x]]/.First@s), g[0] == 1}, g, x]
Out[40]= {{g -> Function[{y}, 1/(1 - 2 x)]}}
当我使用NDSolve
时会出现问题 In[41]:= s = NDSolve[{f'[y] == 2 y, f[0] == 0}, f, {y, 1, 5}]
Out[41]= {{f -> InterpolatingFunction[{{1., 5.}}, <>]}}
In[42]:= ss1 = NDSolve[{g'[x] == 2 (Evaluate[f[g[x]]/.First@s1]), g[0] == 1}, g, {x, 1, 2}]
Out[42]= {}
错误是:
在评估In [41]期间:= InterpolatingFunction :: dmval:输入值{2.01726}位于插值函数的数据范围之外。将使用外推法。 &GT;&GT;
在评估In [41]期间:= InterpolatingFunction :: dmval:输入值{2.01726}位于插值函数的数据范围之外。将使用外推法。 &GT;&GT;
在评估In [41]期间:= InterpolatingFunction :: dmval:输入值{2.04914}位于插值函数的数据范围之外。将使用外推法。 &GT;&GT;
在评估In [41]期间:= General :: stop:在此计算过程中将抑制InterpolatingFunction :: dmval的进一步输出。 &GT;&GT;
评估In [41]期间:= NDSolve :: ndsz:在y == 0.16666654771477857,步长实际为零;怀疑奇点或僵硬的系统。 &GT;&GT;
评估In [41]期间:= NDSolve :: ndsz:在y == 0.16666654771477857,步长实际为零;怀疑奇点或僵硬的系统。 &GT;&GT;
在这方面的任何帮助将受到高度赞赏!
--- Madhurjya
答案 0 :(得分:2)
我有一个简单的例子,可以使用一个小模块。
f0 = First@First@DSolve[{f'[y] == 2 y, f[0] == 0}, f, y]
g0 = g /.
First@First@DSolve[{g'[x] == 2 (f[g[x]] /. f0), g[0] == 1}, g, x]
fn = f /. First@First@NDSolve[{f'[y] == 2 y, f[0] == 0}, f, {y, 0, 10}]
gn = g /.
First@First@
NDSolve[{g'[x] == 2 (fn[g[x]]), g[0] == 1}, g, {x, 0, 9/20}]
GraphicsRow[{
Plot[{g0@x, gn@x}, {x, 0, 9/20},
PlotStyle -> {{Thick, Black}, {Thin, Red, Dashed}}],
Plot[{f@x /. f0, fn@x}, {x, 0, 2},
PlotStyle -> {{Thick, Black}, {Thin, Red, Dashed}}]}]
请注意,我们需要确保第一个y
中的NDSolve
范围足以覆盖第二个g
的预期范围。这就是所有这些插值范围误差的来源。