-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathPDEDiffEllipticalLL5.go
179 lines (166 loc) · 6.65 KB
/
PDEDiffEllipticalLL5.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// 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
}