新手求解决一个关于数值求解偏微分方程的问题
mathematica吧
全部回复
仅看楼主
level 2
我要求解一维波动方程,一维杆左端(x=0)固定,右端(x=L)自由,初始时刻杆处于静力平衡状态,在右端(x=L)加载一个自己定义的荷载P(t)。我的代码如下
EE = 30000000000;
\[Rho] = 2600;
\[Mu] = 0.2;
a = Sqrt[EE/\[Rho]*(1 - \[Mu])/((1 - 2*\[Mu])*(1 + \[Mu]))];
\[Xi] = 1500;
Pmax = 500000000;
Pmid = 500000000/2;
t1 = 0.01/1000;
t2 = 0.1/1000;
t3 = 5/1000;
Pt = \!\(\*
TagBox[GridBox[{
{"\[Piecewise]", GridBox[{
{
RowBox[{
RowBox[{"Pmax", "/", "t1"}], "*", "t"}],
RowBox[{"0", "<=", "t", "<=", "t1"}]},
{
RowBox[{"Pmax", "-",
RowBox[{
RowBox[{
RowBox[{"(",
RowBox[{"Pmax", "-", "Pmid"}], ")"}], "/",
RowBox[{"(",
RowBox[{"t2", "-", "t1"}], ")"}]}], "*",
RowBox[{"(",
RowBox[{"t", "-", "t1"}], ")"}]}]}],
RowBox[{"t1", "<=", "t", "<=", "t2"}]},
{
RowBox[{"Pmid", "-",
RowBox[{
RowBox[{"Pmid", "/",
RowBox[{"(",
RowBox[{"t3", "-", "t2"}], ")"}]}], "*",
RowBox[{"(",
RowBox[{"t", "-", "t2"}], ")"}]}]}],
RowBox[{"t2", "<=", "t", "<=", "t3"}]},
{"0",
RowBox[{"t", ">=", "t3"}]}
},
AllowedDimensions->{2, Automatic},
Editable->True,
GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}},
GridBoxItemSize->{"Columns" -> {{Automatic}}, "Rows" -> {{1.}}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.84]},
Offset[0.27999999999999997`]}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}},
Selectable->True]}
},
GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}},
GridBoxItemSize->{"Columns" -> {{Automatic}}, "Rows" -> {{1.}}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.35]},
Offset[0.27999999999999997`]}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}}],
"Piecewise",
DeleteWithContents->True,
Editable->False,
SelectWithContents->True,
Selectable->False]\);
L = 10;
s1 = NDSolve[{D[u[x, t], t, t] -
a^2 D[u[x, t], x, x] + \[Xi]*D[u[x, t], t] == 0, u[0, t] == 0,
Derivative[0, 1][u][x, 0] == 0, u[x, 0] == 0,
EE*Derivative[1, 0][u][L, t] == Pt}, u, {x, 0, L}, {t, 0, 20/1000}]
然后得到了两个提示
1.Warning: boundary and initial conditions are inconsistent.
2.Encountered non-numerical value for a derivative at t == 0.`.
请大家帮忙看一下
2020年04月15日 07点04分 1
level 6
1. 边界条件和初始条件不匹配,你要改一下定解条件。
2. 分段函数的表达方式不是你以为的那样。用Piecewise写分段函数。
Clear["Global`*"]
EE = 30000000000;
\[Rho] = 2600;
\[Mu] = 0.2;
a = Sqrt[EE/\[Rho]*(1 - \[Mu])/((1 - 2*\[Mu])*(1 + \[Mu]))];
\[Xi] = 1500;
Pmax = 500000000;
Pmid = 500000000/2;
t1 = 0.01/1000;
t2 = 0.1/1000;
t3 = 5/1000;
Pt[t_] :=
Piecewise[{{Pmax/t1*t,
0 <= t <= t1}, {Pmax - (Pmax - Pmid)/(t2 - t1)*(t - t1),
t1 <= t <= t2}, {Pmid - Pmid/(t3 - t2)*(t - t2),
t2 <= t <= t3}, {0, t >= t3}}];
L = 10;
s1 = NDSolve[{D[u[x, t], t, t] -
a^2 D[u[x, t], x, x] + \[Xi]*D[u[x, t], t] == 0, u[0, t] == 0,
Derivative[0, 1][u][x, 0] == 0, u[x, 0] == 0,
EE*Derivative[1, 0][u][L, t] == Pt}, u, {x, 0, L}, {t, 0, 20/1000}]
2020年04月15日 08点04分 2
我还有一些疑惑,因为回复有字数限制,所以我没有直接回复,麻烦看我下面的回复贴,感谢你
2020年04月15日 13点04分
1. 初始和边界不匹配不是大问题。2. LZ的分段函数定义没错,他大概用的是Esc+pw+ESC的定义法,你Ctrl+Shift+I就能转换成Piecewise的形式了。3. LZ其实是撞上Bug了,参看4楼。
2020年05月02日 04点05分
level 2
感谢你的解答,我还有点疑问。我复制你的代码到新的nb文件后,在右端x=L的边界条件右端是Pt,可以计算出数值解u[x,t],同时第2个提示消失了,只有第1个提示,但是用Plot3D画出来是一个值等于0的平面;我把Pt改为Pt[t],重新计算,就出现我原问题中同样的1和2提示。
所以我想问,1.按你那样延时定义的方法,边界条件中应该是Pt还是P[t]呢?
2.关于第2个提示,“Encountered non-numerical value for a derivative at t == 0.`.”,这个应该是个错误吧,这是因为什么原因出现的呢?以及该怎么避免。
感谢你的帮助
2020年04月15日 13点04分 3
抱歉那个Pt是我打漏了,应该是Pt[t],但是问题还是出在定解条件上。你给的定解条件不合理了,本来混合型的定解条件,就要注意条件自身是否自洽。这里主要是你自定义的荷载也不合理,你可以试下一般的初等函数,求解都没问题。
2020年04月15日 14点04分
@纯小树 按照你的建议,我修改了定义的荷载,那些错误提示没有了,不过得到的数值解还有些问题。我再好好琢磨,谢谢你的解答[大拇指]
2020年04月16日 02点04分
吧务
level 15
……你撞上bug了。ibcinc警告很多时候不是问题,但是,如果定义问题时用了分段函数,它经常会触发ndnum警告,这是一个已经被Wolfram客服证实的bug,你不妨把你这个也报上去,以便引起他们的重视。更多内容可以参看Stackexchange的[discontinuity]标签下的问题。
对于你这个问题,可以通过使用连续函数近似原本的分段函数来规避问题。注意NDSolve的选项也要做相应调整:
mol[n:_Integer|{_Integer..}, o_:"Pseudospectral"] := {"MethodOfLines",
"SpatialDiscretization" -> {"TensorProductGrid", "MaxPoints" -> n,
"MinPoints" -> n, "DifferenceOrder" -> o}}
mol[tf:False|True,sf_:Automatic]:={"MethodOfLines",
"DifferentiateBoundaryConditions"->{tf,"ScaleFactor"->sf}}
appro = With[{k = 10^6}, ArcTan[k #]/Pi + 1/2 &];
EE = 30000000000;
\[Rho] = 2600;
\[Mu] = 0.2;
a = Sqrt[EE/\[Rho]*(1 - \[Mu])/((1 - 2*\[Mu])*(1 + \[Mu]))];
\[Xi] = 1500;
Pmax = 500000000;
Pmid = 500000000/2;
t1 = 0.01/1000;
t2 = 0.1/1000;
t3 = 5/1000;
Pt = Simplify`PWToUnitStep@ Piecewise[{{(Pmax/t1)*t, 0 <= t <= t1},
{Pmax - ((Pmax - Pmid)/(t2 - t1))*(t - t1), t1 <= t <= t2},
{Pmid - (Pmid/(t3 - t2))*(t - t2), t2 <= t <= t3}, {0, t >= t3}}] /.
UnitStep -> appro;
L = 10;
s1 = NDSolveValue[{D[u[x, t], t, t] -
a^2 D[u[x, t], x, x] + \[Xi]*D[u[x, t], t] == 0, u[0, t] == 0,
Derivative[0, 1][u][x, 0] == 0, u[x, 0] == 0,
EE*Derivative[1, 0][u][L, t] == Pt}, u, {x, 0, L}, {t, 0, 20/1000},
MaxSteps -> Infinity, Method -> Union[mol[25, 4], mol[True, 10^6]]]
检查一下边界:
Plot[D[s1[x, t], x] /. x -> L // Evaluate, {t, 0, 0.001}, PlotRange -> All]
嗯,近似度还是可以的。看样子取10^6是够的。
Plot3D[s1[x, t], {t, 0, 20/1000}, {x, 0, L}, PlotPoints -> 50]
2020年05月02日 04点05分 4
感谢吧主的细致解答
2020年05月04日 12点05分
不好意思打扰你了,想再麻烦问一句,我改变长度L或者计算时间需要修改你添加的开头的三行代码或者NDSolveValue选项里的一些地方吗?我直接修改长度后计算的结果不太对,不知道是不是没有修改某些地方。
2020年05月11日 08点05分
@崎岖以寻壑 当然要改。两个mol的参数都要改。它们一个控制x方向网格密度,一个控制实际边界趋向分段边界的速度。具体效果你多试几个数就能看出来了。
2020年06月06日 04点06分
@xzcyr 我取几个值算了,发现第一个mol里的25和4应该是x、t方向的网格数,那么第2个mol的True、10^6是什么意思呢,其余的参数保持不变,我把10^6改成了10^10运算时间就增加了很多,几个小时都还没算完,这个参数的意义是不是取值越大,实际边界趋向原分段边界的效果就越好呢?麻烦吧主赐教
2020年06月10日 05点06分
level 9
指定纽曼条件和狄利克雷条件就可以了,但这种黑箱操作,很容易让人怀疑结果准不准,建议用多种方法验证一下。例如这里u的最大值为u=0.0294629,取在x=10,t=0.00292567处。
代码为,
Clear["Global`*"];
EE = 30000000000;
\[Rho] = 2600;
\[Mu] = 0.2;
a = Sqrt[EE/\[Rho]*(1 - \[Mu])/((1 - 2*\[Mu])*(1 + \[Mu]))];
\[Xi] = 1500;
Pmax = 500000000;
Pmid = 500000000/2;
t1 = 0.01/1000;
t2 = 0.1/1000;
t3 = 5/1000;
Pt[t_] = Piecewise[{{(Pmax/t1)*t, 0 <= t <= t1},
{Pmax - ((Pmax - Pmid)/(t2 - t1))*(t - t1), t1 <= t <= t2},
{Pmid - (Pmid/(t3 - t2))*(t - t2), t2 <= t <= t3}, {0, t >= t3}}];
L = 10;
sol = NDSolveValue[{D[u[x, t], t, t] -
a^2 D[u[x, t], x, x] + \[Xi]*D[u[x, t], t] ==
NeumannValue[Pt[t]/EE*a^2, x == L],
DirichletCondition[u[x, t] == 0, x == 0],
Derivative[0, 1][u][x, 0] == 0, u[x, 0] == 0}, u, {x, 0, L},
{t, 0, 20/1000}, Method -> "MethodOfLines"];
{Plot3D[sol[x, t], {t, 0, 20/1000}, {x, 0, L}, PlotPoints -> 50,
PlotTheme -> "Classic"],
Plot[sol[10, t], {t, 0, 20/1000}, Mesh -> Full, Frame -> True]}
Maximize[{sol[10, t], 0 <= t <= 20/1000}, t]
2020年06月10日 14点06分 5
感谢你的解答,你的方法得到的结果和吧主上面的方法是相同的,只是u在x=10的最大值有微小的差别。我现在的问题是方程改了,和分段函数匹配的边界条件的形式也改了,变成了u对x的偏导和u对x、t的混合偏导的组合(我感觉这样的边界条件有点怪),所以我不知道怎么根据你这里的代码进行修改
2020年06月11日 07点06分
@崎岖以寻壑 不用想太多,如果不是三种边界条件,那就是你的模型有问题。
2020年06月11日 15点06分
@逍遥诸葛亮 应该就是我模型的问题,边界条件确实没有对x、t的混合偏导的,我再改一下,感谢你的回答
2020年06月13日 14点06分
对啊,FiniteElement也是个规避边界问题的好办法。之前用着版本9,就给忘了……
2020年07月04日 04点07分
1