如何强制微分方程的变量为实数。警告引起的一个问题:“NDSolve :: evfrf:”

时间:2011-09-17 12:22:46

标签: wolfram-mathematica

当我使用以下代码数字解决一个颂歌时,会提示名为“evfrf”的警告。

我想知道如何将微分方程的变量强制为实数

NDSolve[{y''[t] + .1 y'[t] + Sin[y[t]] == 0, y'[0] == 1, 
y[0] == 0}, y, {t, 0, 20}, 
Method -> {"EventLocator", "Event" -> y[t], 
"EventCondition" -> y'[t] > 0, 
"EventAction" :> Print[t, ", ", y[t], ", ", y'[t]]}]

警告信息:

NDSolve::evfrf: 
The event function did not evaluate to a real number somewhere 
between t =  1.5798366385128957` and t = 1.6426647495929725`,
preventing FindRoot from finding the root accurately. >>  

谢谢:)

3 个答案:

答案 0 :(得分:3)

错误消息似乎仅由"EventCondition" -> y'[t] >= 0部分引起。我不知道那里有什么问题,但考虑到你想要将事件(y [t] == 0)限制为上传(y'[t]> 0),你可以用{替换该部分{1}}也是如此。

或者,您可以使用"Direction" -> 1简单地关闭消息,因为它似乎对最终结果没有影响。 Off[NDSolve::evfrf]方法生成的事件与生成消息的原始事件相同。

答案 1 :(得分:2)

我不认为这是一个真正在这些点上复杂数字的答案问题。 以下内容不会出错。

sol = NDSolve[{y''[t] + .1 y'[t] + Sin[y[t]] == 0, y'[0] == 1, 
 y[0] == 0}, y, {t, 0, 20}]

Plot[y[t] /. sol, {t, 0, 20}]

enter image description here

问题是尝试在y'[t]中找到零,并在隐含的根查找过程中找到限制。我尝试增加WorkingPrecisionMaxSteps,但它没有删除错误。

sol = NDSolve[{y''[t] + .10`64 y'[t] + Sin[y[t]] == 0, y'[0] == 1, 
y[0] == 0}, y, {t, 0, 20}, 
  Method -> {"EventLocator", "Event" -> y[t], 
 "EventCondition" -> y'[t] >= 0, 
 "EventAction" :> Print[t, ", ", y[t], ", ", y'[t]]},  
   MaxSteps -> 10^9, MaxStepSize -> 0.0001, WorkingPrecision -> 32]

除非你真的关心小数点后八位或小数位,否则我建议你不要担心这个错误。

在数值分析中比我更专业的人可能不同意,但我在一个领域工作,我们通常对百分比变化的第一个小数位之后的任何数据的准确性没有任何信心(小数点后三位)电平)。

答案 2 :(得分:1)

使用EventLocator很重要吗?是否有可能解决y'然后在其上应用FindRoot?类似的东西:

ndsolveOptions = {MaxSteps -> Infinity, Method -> {"StiffnessSwitching", 
  Method ->{"ExplicitRungeKutta", Automatic}}, AccuracyGoal -> 10,PrecisionGoal -> 10};

sol = First@NDSolve[{y''[t] + .1 y'[t] + Sin[y[t]] == 0, y'[0] == 1, y[0] == 0}, 
     {y[t], y'[t]}, {t, 0, 20}, Sequence@ndsolveOptions];

der = y'[t] /. sol;
Plot[der, {t, 1.2, 1.7}]

FindRoot[der, {t, 1.6}]

      {t -> 1.614}

enter image description here