-
Notifications
You must be signed in to change notification settings - Fork 0
/
Multigrid.scala
71 lines (56 loc) · 1.72 KB
/
Multigrid.scala
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
package poisson
def multigrid(
width: Int,
height: Int,
xPrev: Array[Double],
laplacian: Array[Double],
xNext: Array[Double],
nPre: Int,
nPost: Int,
h: Double): Unit = {
val xPrevCopy = xPrev.clone()
if (width <= 3 || height <= 3) {
var i = xNext.size -1
while (i >= 0) {
xNext(i) = 0.0
i -= 1
}
} else {
var nIter = nPre / 2
while (nIter >= 0) {
jacobiSorVec_!(width, height, xPrev, laplacian, xNext, h)
jacobiSorVec_!(width, height, xNext, laplacian, xPrev, h)
nIter -= 1
}
val r = new Array[Double](width * height)
residualVec_!(width, height, xPrev, laplacian, r, h)
val coarseWidth = width / 2
val coarseHeight = height / 2
val coarseSize = coarseWidth * coarseHeight
val coarseNext = new Array[Double](coarseSize)
val coarseL = new Array[Double](coarseSize)
// maybe optimize more?
restrictVec(width, height, r, coarseL)
val zeros = new Array[Double](coarseSize)
multigrid(coarseWidth, coarseHeight, zeros, coarseL, coarseNext, nPre, nPost, h * 2)
val err = new Array[Double](width * height)
prolongate(coarseWidth, coarseHeight, coarseNext, width, height, err)
var offset = 0
(0 until height).foreach { y =>
(0 until width).foreach { x =>
if (x == 0 || x == width -1 || y == 0 || y == height - 1) {
xNext(offset) = xPrevCopy(offset)
} else {
xNext(offset) = xPrev(offset) + err(offset)
}
offset += 1
}
}
nIter = nPost / 2
while (nIter >= 0) {
jacobiSorVec_!(width, height, xNext, laplacian, xPrev, h)
jacobiSorVec_!(width, height, xPrev, laplacian, xNext, h)
nIter -= 1
}
}
}