当我尝试处理实验数据时,我在Mathematica中遇到了内存问题。我正在使用Mathematica找到三个偏微分方程组的最优参数。
当e
参数大于0.4时,Mathematica消耗了大量内存。对于e < 0.4
,该计划正常运作。
我尝试过使用$HistoryLength = 0
,并减少AccuracyGoal
和WorkingPrecision
但没有成功。
我正在努力了解我犯了哪些错误,以及如何限制内存使用量。
Clear[T, L, e, v, q, C0, R, data, model];
T = 13200;
L = 0.085;
e = 0.41;
v = 0.000557197;
q = 0.1618;
C0 = 0.0256;
R = 0.00075;
data = {{L, 600, 0.141124587}, {L, 1200, 0.254134509}, {L, 1800,
0.342888644}, {L, 2400, 0.424476295}, {L, 3600, 0.562844542}, {L,
4800, 0.657111356}, {L, 6000, 0.75137817},
{L, 7200, 0.815876516}, {L, 8430, 0.879823594}, {L, 9000,
0.900771775}, {L, 13200, 1}};
model[(De_)?NumberQ, (Kf_)?NumberQ, (Y_)?NumberQ] :=
model[De, Kf, Y] = yeld /. Last[Last[
NDSolve[{
v D[Ci[z, t], z] + D[Ci[z, t], t] == -((
3 (1 - e) Kf (Ci[z, t] - C0))/(
R e (1 - (R Kf (1 - R/r[z, t]))/De))),
D[r[z, t], t] == (R^2 Kf (Ci[z, t] - C0))/(
q r[z, t]^2 (1 - (R Kf (1 - R/r[z, t]))/De)),
D[yeld[z, t], t] == Y*(v e Ci[z, t])/(L q (1 - e)),
r[z, 0] == R,
Ci[z, 0] == 0,
Ci[0, t] == 0,
yeld[z, 0] == 0},
{r[z, t], Ci[z, t], yeld}, {z, 0, L}, {t, 0, T}]]]
fit = FindFit[
data, {model[De, Kf, Y][z, t], {0.97 < Y < 1.03,
10^-6 < Kf < 10^-4, 10^-13 < De < 10^-9}},
{{De, 10^-12}, {Kf, 10^-6}, {Y, 1}}, {z, t}, Method -> NMinimize]
data = {{600, 0.141124587}, {1200, 0.254134509}, {1800,
0.342888644}, {2400, 0.424476295}, {3600, 0.562844542}, {4800,
0.657111356}, {6000, 0.75137817}, {7200, 0.815876516},
{8430, 0.879823594}, {9000, 0.900771775}, {13200, 1}};
YYY = model[De /. fit[[1]], Kf /. fit[[2]], Y /. fit[[3]]];
Show[Plot[Evaluate[YYY[L, t]], {t, 0, T}, PlotRange -> All],
ListPlot[data, PlotStyle -> Directive[PointSize[Medium], Red]]]
链接到.nb文件:http://www.4shared.com/folder/249TSjlz/_online.html
答案 0 :(得分:3)
我有一种潜在的怀疑,为什么它失败的原因是因为你正在缓存结果。
您是否需要存储NDSolve
正在生成的每个解决方案?我对Findfit
这是否有用持怀疑态度,因为我非常怀疑它会重新审视过去的结果。
此外,它不像你在谈论你正在谈论的有限域的整数。您正在使用实数甚至超出您指定的范围,可能会有 A LOT 不同的解决方案。我认为你不想存储它们中的每一个。
重写您的代码,而不是:
model[(De_)?NumberQ, (Kf_)?NumberQ, (Y_)?NumberQ] :=
model[De, Kf, Y] = yeld /. Last[Last[
NDSolve[..]
你改为:
model[(De_)?NumberQ, (Kf_)?NumberQ, (Y_)?NumberQ] :=
NDSolve[..]
通过缓存你以前的结果,你会在FindFit
之后吃掉没有明天的记忆。通常情况下,当你有一个递归关系时它很有用,但在这里我会认真反对它。
一些注释:
在我的机器上运行2415
秒后,Mathematica的内存使用率从112,475,400
个字节变为1,642,280,320
个字节,并带有缓存。
我现在正在运行没有缓存的代码。