Files
sjy01-image-proc/vendor/github.com/nuknal/goNum/PDEDiffHyperbolic2.go
2024-10-24 15:46:01 +08:00

108 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// PDEDiffHyperbolic2
/*
------------------------------------------------------
作者 : Black Ghost
日期 : 2018-12-17
版本 : 0.0.0
------------------------------------------------------
求解双曲型偏微分方程的差分解法第二种差分格式t=0时微分方程须成立
理论:
对于抛物型偏微分方程:
d^2u d^2u
------ = A ------ + B
dt^2 dx^2
u(x, 0) = phi(x), (du/dt)_(t=0) = psi(x)
u(0, t) = u1(t), u(L, t) = u2(t)
0 < x < L, 0 < t < T
则差分格式为x分为m等份t分为n等份
u_(i,j+1) = lu_(i+1,j) + 2(1-l)u_(i,j) + lu_(i-1,j) -
u_(i,j-1) + B*ht^2
初值需要计算第零层和第一层、左右边界
第零层u_(i,0) = phi(i*hx), i=1,2,...,m-1
第一层u_(i,1) = u_(i,0) + ht*psi(i*hx) + B*ht^2/2 +
l*(u_(i+1,0)-2u_(i,0)+u_(i-1,0))/2
左边界u_(0,j) = u1(j*ht)
右边界u_(m,j) = u2(j*ht), j=0,1,2,...,n
参考 李信真, 车刚明, 欧阳洁, 等. 计算方法. 西北工业大学
出版社, 2000, pp 226-228.
------------------------------------------------------
输入 :
funphi, funpsi, funu1, funu2 边界函数
x0 求解范围2x2
A, B 常系数
m, n 网格数量
输出 :
sol 解矩阵
err 解出标志false-未解出或达到步数上限;
true-全部解出
------------------------------------------------------
*/
package goNum
// PDEDiffHyperbolic2 求解双曲型偏微分方程的差分解法第二种差分格式t=0时微分方程须成立
func PDEDiffHyperbolic2(funphi, funpsi, funu1, funu2 func(float64) float64,
x0 Matrix, A, B float64, m, n int) (Matrix, bool) {
/*
求解双曲型偏微分方程的差分解法第二种差分格式t=0时微分方程须成立
输入 :
funphi, funpsi, funu1, funu2 边界函数
x0 求解范围2x2
A, B 常系数
m, n 网格数量
输出 :
sol 解矩阵
err 解出标志false-未解出或达到步数上限;
true-全部解出
*/
//判断网格数量
if (m < 1) || (n < 1) {
panic("Error in goNum.PDEDiffHyperbolic1: Grid numbers error")
}
var err bool = false
sol := ZeroMatrix(m+1, n+1)
hx := (x0.GetFromMatrix(1, 0) - x0.GetFromMatrix(0, 0)) / float64(m) //x方向步长
ht := (x0.GetFromMatrix(1, 1) - x0.GetFromMatrix(0, 1)) / float64(n) //t方向步长
//1. 计算t第零层上的值u_(i,0) i=,1,...,m-1
for i := 1; i < m; i++ {
sol.SetMatrix(i, 0, funphi(x0.GetFromMatrix(0, 0)+float64(i)*hx))
}
//2. 计算x左右边界上的节点u_(0,j)和u_(m,j) j=0,1,2,...,n
for j := 0; j < n+1; j++ {
sol.SetMatrix(0, j, funu1(x0.GetFromMatrix(0, 1)+float64(j)*ht)) //左边界
sol.SetMatrix(m, j, funu2(x0.GetFromMatrix(0, 1)+float64(j)*ht)) //右边界
}
//lambda及稳定性判断
l := A * ht * ht / (hx * hx)
if l > 1 {
panic("Error in goNum.PDEDiffHyperbolic1: lambda greater than one")
}
//3. 计算t第一层上的值u_(i,1) i=,1,...,m-1
for i := 1; i < m; i++ {
temp0 := sol.GetFromMatrix(i, 0) + ht*funpsi(x0.GetFromMatrix(0, 0)+float64(i)*hx)
temp0 += sol.GetFromMatrix(i+1, 0) - 2.0*sol.GetFromMatrix(i, 0) + sol.GetFromMatrix(i-1, 0)
sol.SetMatrix(i, 1, l*temp0/2.0+B*ht*ht/2.0)
}
//4. 2n层
for j := 2; j < n+1; j++ {
for i := 1; i < m; i++ {
temp0 := l * sol.GetFromMatrix(i+1, j-1)
temp0 += 2.0 * (1.0 - l) * sol.GetFromMatrix(i, j-1)
temp0 += l * sol.GetFromMatrix(i-1, j-1)
temp0 -= sol.GetFromMatrix(i, j-2)
temp0 += B * ht * ht
sol.SetMatrix(i, j, temp0)
}
}
err = true
return sol, err
}