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

180 lines
6.6 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.

// PDEDiffEllipticalLL5
/*
------------------------------------------------------
作者 : Black Ghost
日期 : 2019-01-07
版本 : 0.0.0
------------------------------------------------------
求解椭圆型偏微分方程Laplace的差分解法五点格式
理论:
对于椭圆型偏微分方程Laplace方程
d^2u d^2u
------ + ------ = 0
dx^2 dy^2
u(x, 0) = fy0(x), u(x, b) = fyb(x)
u(0, y) = fx0(y), u(a, y) = fxa(y)
0 < x < a, 0 < y < b
x分为n等份y分为m等份
hy^2[u_(i+1,j) + u_(i-1,j) - 2u_(i,j)] +
hx^2[u_(i,j+1) + u_(i,j-1) - 2u_(i,j)] = 0
解以上方程组可得解
参考 John H. Mathews and Kurtis D. Fink. Numerical
methods using MATLAB, 4th ed. Pearson
Education, 2004. ss 10.3.1.
------------------------------------------------------
输入 :
funy0, funyb, funx0, funxa 边界函数
x0 求解范围2x2
n, m 网格数量, 对应x和y
输出 :
sol 解矩阵
err 解出标志false-未解出或达到步数上限;
true-全部解出
------------------------------------------------------
*/
package goNum
// PDEDiffEllipticalLL5 求解椭圆型偏微分方程Laplace的差分解法五点格式
func PDEDiffEllipticalLL5(funy0, funyb, funx0, funxa func(float64) float64,
x0 Matrix, n, m int) (Matrix, bool) {
/*
求解椭圆型偏微分方程Laplace的差分解法五点格式
输入 :
funy0, funyb, funx0, funxa 边界函数
x0 求解范围2x2
n, m 网格数量, 对应x和y
输出 :
sol 解矩阵
err 解出标志false-未解出或达到步数上限;
true-全部解出
*/
//判断网格数量
if (m < 1) || (n < 1) {
panic("Error in goNum.PDEDiffEllipticalLL5: Grid numbers error")
}
//判断初值维数
if (x0.Rows < 2) || (x0.Columns < 2) {
panic("Error in goNum.PDEDiffEllipticalLL5: Initial values error")
}
var err bool = false
sol := ZeroMatrix(m+1, n+1) //行y变化列x变化
hx := (x0.GetFromMatrix(1, 0) - x0.GetFromMatrix(0, 0)) / float64(n) //x方向步长
hy := (x0.GetFromMatrix(1, 1) - x0.GetFromMatrix(0, 1)) / float64(m) //y方向步长
//边界框的解
//第一行的值和最后一行的值,不包括第一个和最后一个
for i := 1; i < n; i++ {
sol.SetMatrix(0, i, funy0(x0.GetFromMatrix(0, 0)+hx*float64(i)))
sol.SetMatrix(m, i, funyb(x0.GetFromMatrix(0, 0)+hx*float64(i)))
}
//第一列的值和最后一列的值,包括第一个和最后一个
for j := 0; j < m+1; j++ {
sol.SetMatrix(j, 0, funx0(x0.GetFromMatrix(0, 1)+hy*float64(j)))
sol.SetMatrix(j, n, funxa(x0.GetFromMatrix(0, 1)+hy*float64(j)))
}
//求解中间点,主对角占优矩阵解法,利用高斯消去方法
AA := ZeroMatrix((n-1)*(m-1), (n-1)*(m-1)) //系数矩阵A
BA := ZeroMatrix((n-1)*(m-1), 1) //值矩阵B
//赋值系数矩阵和值矩阵
//第一行, j = 1
//第一个
AA.SetMatrix(0, 0, -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix(0, 1, hy*hy)
AA.SetMatrix(0, n-1, hx*hx)
tempBA := 0.0 - hy*hy*funx0(x0.GetFromMatrix(0, 1)+hy*1.0)
tempBA = tempBA - hx*hx*funy0(x0.GetFromMatrix(0, 0)+hx*1)
BA.SetMatrix(0, 0, tempBA)
for i := 2; i < n-1; i++ {
AA.SetMatrix(i-1, i-2, hy*hy)
AA.SetMatrix(i-1, i-1, -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix(i-1, i, hy*hy)
AA.SetMatrix(i-1, (n-1)*1+i-1, hx*hx)
tempBA = 0.0 - hx*hx*funy0(x0.GetFromMatrix(0, 0)+hx*float64(i))
BA.SetMatrix((n-1)*0+i-1, 0, tempBA)
}
//最后一个
AA.SetMatrix(n-1-1, n-1-2, hy*hy)
AA.SetMatrix(n-1-1, n-1-1, -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix(n-1-1, (n-1)*1+n-1-1, hx*hx)
tempBA = 0.0 - hy*hy*funxa(x0.GetFromMatrix(0, 1)+hy*1.0)
tempBA = tempBA - hx*hx*funy0(x0.GetFromMatrix(0, 0)+hx*float64(n-1))
BA.SetMatrix(n-1-1, 0, tempBA)
//中间行
for j := 2; j < m-1; j++ {
//第一个
AA.SetMatrix((n-1)*(j-1), (n-1)*(j-1-1), hx*hx)
AA.SetMatrix((n-1)*(j-1), (n-1)*(j-1), -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix((n-1)*(j-1), (n-1)*(j-1)+1, hy*hy)
AA.SetMatrix((n-1)*(j-1), (n-1)*(j-1)+n-1, hx*hx)
tempBA = 0.0 - hy*hy*funx0(x0.GetFromMatrix(0, 1)+hy*float64(j))
BA.SetMatrix((n-1)*(j-1), 0, tempBA)
for i := 2; i < n-1; i++ {
AA.SetMatrix((n-1)*(j-1)+i-1, (n-1)*(j-1-1)+i-1, hx*hx)
AA.SetMatrix((n-1)*(j-1)+i-1, (n-1)*(j-1)+i-2, hy*hy)
AA.SetMatrix((n-1)*(j-1)+i-1, (n-1)*(j-1)+i-1, -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix((n-1)*(j-1)+i-1, (n-1)*(j-1)+i, hy*hy)
AA.SetMatrix((n-1)*(j-1)+i-1, (n-1)*(j-1+1)+i-1, hx*hx)
BA.SetMatrix((n-1)*(j-1)+i-1, 0, 0.0)
}
//最后一个
AA.SetMatrix((n-1)*(j-1)+n-1-1, (n-1)*(j-1-1)+n-1-1, hx*hx)
AA.SetMatrix((n-1)*(j-1)+n-1-1, (n-1)*(j-1)+n-1-2, hy*hy)
AA.SetMatrix((n-1)*(j-1)+n-1-1, (n-1)*(j-1)+n-1-1, -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix((n-1)*(j-1)+n-1-1, (n-1)*(j-1+1)+n-1-1, hx*hx)
tempBA = 0.0 - hy*hy*funxa(x0.GetFromMatrix(0, 1)+hy*float64(j))
BA.SetMatrix((n-1)*(j-1)+n-1-1, 0, tempBA)
}
//最后一行, j = m-1
//第一个
AA.SetMatrix((n-1)*(m-1-1), (n-1)*(m-1-1-1), hx*hx)
AA.SetMatrix((n-1)*(m-1-1), (n-1)*(m-1-1), -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix((n-1)*(m-1-1), (n-1)*(m-1-1)+1, hy*hy)
tempBA = 0.0 - hy*hy*funx0(x0.GetFromMatrix(0, 1)+hy*float64(m-1))
tempBA = tempBA - hx*hx*funyb(x0.GetFromMatrix(0, 0)+hx*1)
BA.SetMatrix((n-1)*(m-1-1), 0, tempBA)
for i := 2; i < n-1; i++ {
AA.SetMatrix((n-1)*(m-1-1)+i-1, (n-1)*(m-1-1-1)+i-1, hx*hx)
AA.SetMatrix((n-1)*(m-1-1)+i-1, (n-1)*(m-1-1)+i-2, hy*hy)
AA.SetMatrix((n-1)*(m-1-1)+i-1, (n-1)*(m-1-1)+i-1, -2.0*hx*hx-2.0*hy*hy)
AA.SetMatrix((n-1)*(m-1-1)+i-1, (n-1)*(m-1-1)+i, hy*hy)
tempBA = 0.0 - hx*hx*funyb(x0.GetFromMatrix(0, 0)+hx*float64(i))
BA.SetMatrix((n-1)*(m-1-1)+i-1, 0, tempBA)
}
//最后一个
AA.SetMatrix((n-1)*(m-1-1)+n-1-1, (n-1)*(m-1-1-1)+n-1-1, hx*hx)
AA.SetMatrix((n-1)*(m-1-1)+n-1-1, (n-1)*(m-1-1)+n-1-2, hy*hy)
AA.SetMatrix((n-1)*(m-1-1)+n-1-1, (n-1)*(m-1-1)+n-1-1, -2.0*hx*hx-2.0*hy*hy)
tempBA = 0.0 - hy*hy*funxa(x0.GetFromMatrix(0, 1)+hy*float64(m-1))
tempBA = tempBA - hx*hx*funyb(x0.GetFromMatrix(0, 0)+hx*float64(n-1))
BA.SetMatrix((n-1)*(m-1-1)+n-1-1, 0, tempBA)
//求解矩阵方程
tempp, temperr := LEs_ECPE(Matrix2ToSlices(AA), Matrix1ToSlices(BA))
if temperr != true {
panic("Error in goNum.PDEDiffEllipticalLL5: Solve error")
}
//解赋予sol
ii := 1
jj := 1
for i := 0; i < len(tempp); i++ {
sol.SetMatrix(ii, jj, tempp[i])
if jj == n-1 {
ii++
jj = 0
}
jj++
}
err = true
return sol, err
}