我是mathematica的新手所以请耐心等待我!
我正在尝试使用NDSolve在mma中解决非线性PDE。解决过程被缩短,因为在模拟耗尽之前很多时候出现了奇点。我意识到具有这种奇点的刚性系统可以通过减小步长来处理(至少通过蛮力)。
然而,“MaxSteps”或“MaxStepSize”似乎对我的代码没有实际影响。
是什么给出的?我可能遗失的任何其他方法?
**
**
Needs["VectorAnalysis`"]
Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"];
Clear[Eq4, EvapThickFilm, h, S, G, E1, K1, D1, VR, M, R]
Eq4[h_, {S_, G_, E1_, K1_, D1_, VR_, M_, R_}] := \!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]h\) +
Div[-h^3 G Grad[h] +
h^3 S Grad[Laplacian[h]] + (VR E1^2 h^3)/(D1 (h + K1)^3)
Grad[h] + M (h/(1 + h))^2 Grad[h]] + E1/(
h + K1) + (R/6) D[D[(h^2/(1 + h)), x] h^3, x] == 0;
SetCoordinates[Cartesian[x, y, z]];
EvapThickFilm[S_, G_, E1_, K1_, D1_, VR_, M_, R_] :=
Eq4[h[x, y, t], {S, G, E1, K1, D1, VR, M, R}];
TraditionalForm[EvapThickFilm[S, G, E1, K1, D1, VR, M, R]];
L = 318; TMax = 7.0;
Off[NDSolve::mxsst];
Clear[Kvar];
Kvar[t_] := Piecewise[{{0.01, t <= 4}, {0.05, t > 4}}]
(*Ktemp = Array[0.001+0.001#^2&,13]*)
hSol = h /. NDSolve[{
(*S,G,E,K,D,VR,M*)
EvapThickFilm[1, 3, 0.1, Kvar[t], 0.01, 0.1, 0, 160],
h[0, y, t] == h[L, y, t],
h[x, 0, t] == h[x, L, t],
(*h[x,y,0] == 1.1+Cos[x] Sin[2y] *)
h[x, y, 0] ==
1 + (-0.25 Cos[2 \[Pi] x/L] - 0.25 Sin[2 \[Pi] x/L]) Cos[
2 \[Pi] y/L]
},
h,
{x, 0, L},
{y, 0, L},
{t, 0, TMax}
][[1]]
NDSolve :: ndsz:在t == 2.366570254802048`时,步长实际为零;怀疑奇点或僵硬的系统。 &GT;&GT;
NDSolve :: eerr:警告:在自变量x方向上的缩放局部空间误差估计值571455.5042645375 at t = 2.366570254802048
远大于规定的误差容限。具有19个点的网格间距可能太大而无法实现所需的精度或精度。可能已形成奇点,或者您可能希望使用MaxStepSize或MinPoints方法选项指定较小的网格间距。 &GT;&GT;
答案 0 :(得分:2)
我遇到“没有更多可用内存”的问题,解决方案取决于导致内存不足的原因。例如,我曾经不得不运行一个模拟,这需要我在大容量上计算3D磁场,正如您可能想象的那样,不仅花了我很长时间来计算它,而且计算它也是不可能的。每次我必须运行模拟穿过它的粒子。为了避免内存问题并使程序计算更轻,我决定将磁场数据写入文本文件。对于网格中的每个空间点,一个带有B字段向量的简单csv样式文件就可以实现......
所以,我的建议是,如果你因为计算大量数据而内存不足,你应该将它流式传输到一个文件,然后在程序的下一步读取文件...我希望这种技术有帮助;)
答案 1 :(得分:1)
尝试将代码中的TMax缩小,例如2或1.
这将删除错误。我发现,如果我使用较小的时间跨度解决,我可以获得更准确的结果(更高AccuracyGoal ->
),我也可以使用MaxSteps -> Infinity
。
技巧是当前NDSolve调用的开始时间不必与初始条件时间相同。开始时间可以远离初始条件。
来自帮助
The point Subscript[x, 0] that appears in the initial or boundary conditions
need not lie in the range Subscript[x, min] to Subscript[x, max] over which
the solution is sought.
这样,人们可以多次调用NDSolve,每次调用时间跨度较小,而每次调用都使用相同的初始条件。但作为交换,每一步,都可以做得更准确。我发现调用NDSolve的速度非常快,并且在性能方面没有任何影响。
即。将NDSolve时间规格更改为{from,to}
vs {0,TMax}
,其中from
和to
每次都以较小的值前进,以使它们之间的距离保持较小。 (您需要添加小的逻辑代码才能执行此操作),直到您覆盖了您有兴趣解决的整个时间范围。
所以,尝试更改你的求解器来解决更小的步骤,我认为你会得到更好的结果。
另外,请尝试在NDSolver的选项中使用Method -> {"StiffnessSwitching"}
,因为Mathematica说它是僵硬的系统。