2

私はMathematicaの初心者ですので、ご容赦ください!

NDSolve を使用して mma の非線形偏微分方程式を解こうとしています。シミュレーションの時間がなくなるずっと前に特異点が発生するため、解法プロセスは短くなります。このような特異点を持つ硬いシステムは、ステップ サイズを小さくすることで (少なくとも力ずくで) 対処できることを認識しています。

ただし、「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` で、ステップ サイズは事実上ゼロです。特異点または硬いシステムが疑われます。>>

NDSolve::eerr: 警告: 独立変数 x の方向の 571455.5042645375 のスケーリングされたローカル空間誤差推定値はat t = 2.366570254802048、規定の許容誤差よりもはるかに大きいです。19 ポイントのグリッド間隔は、必要な精度または精度を達成するには大きすぎる場合があります。特異点が形成されているか、MaxStepSize または MinPoints メソッド オプションを使用してより小さなグリッド間隔を指定する必要がある場合があります。>>

4

2 に答える 2

3

「使用可能なメモリがありません」という問題が発生した場合、解決策はメモリ不足の原因によって異なります。たとえば、シミュレーションを実行する必要があったため、大容量の3D磁場を計算する必要がありました。ご想像のとおり、計算に時間がかかるだけでなく、計算するのも現実的ではありませんでした。毎回、それを横切る粒子のシミュレーションを実行する必要がありました。メモリの問題を回避し、プログラムの計算を軽くするために、磁場データをテキストファイルに書き込むことにしました。グリッド内のスペースの各ポイントのBフィールドベクトルを使用した単純なcsvスタイルのファイルでうまくいきました...

したがって、私のアドバイスは、大量のデータを計算しているためにメモリが不足している場合は、それをファイルにストリーミングしてから、プログラムの次のステップでファイルを読み取る必要があるということです...このテクニックが役立つことを願っています;)

于 2012-09-07T02:48:16.613 に答える
2

コード内の 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}に変更します。ここで、fromtoは、両者の間の距離が小さいままになるように、毎回小さな値で進められます。(これを行うには、小さなロジック コードを追加する必要があります)、解決したい時間範囲全体をカバーするまで。

したがって、ソルバーを小さなステップで解決するように変更してみてください。そうすれば、はるかに良い結果が得られると思います。

また、Method -> {"StiffnessSwitching"}NDSolver のオプションで使用してみてください。Mathematica によると、それはスティッフなシステムです。

于 2011-09-22T22:26:01.823 に答える