-
Notifications
You must be signed in to change notification settings - Fork 1
/
mesh.go
142 lines (123 loc) · 3.15 KB
/
mesh.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
package data
import (
"fmt"
"log"
)
// Mesh stores info of a finite-difference mesh.
type Mesh struct {
gridSize [3]int
cellSize [3]float64
pbc [3]int
Unit string // unit of cellSize, default: "m"
noi int
gneb [2]int
}
// Images stores info of a number of images.
// type Images struct {
// noi int
// }
// Retruns a new mesh with N0 x N1 x N2 cells of size cellx x celly x cellz.
// Optional periodic boundary conditions (pbc): number of repetitions
// in X, Y, Z direction. 0,0,0 means no periodicity.
func NewMesh(N0, N1, N2 int, cellx, celly, cellz float64, pbc ...int) *Mesh {
var pbc3 [3]int
if len(pbc) == 3 {
copy(pbc3[:], pbc)
} else {
if len(pbc) != 0 {
log.Panic("mesh: need 0 or 3 PBC arguments, got:", pbc)
}
}
size := [3]int{N0, N1, N2}
gneb := [2]int{0, 0}
return &Mesh{size, [3]float64{cellx, celly, cellz}, pbc3, "m", 1, gneb}
}
func NewMeshGneb(N0, N1, N2, noi, gneb2D, gneb3D int, cellx, celly, cellz float64, pbc ...int) *Mesh {
var pbc3 [3]int
if len(pbc) == 3 {
copy(pbc3[:], pbc)
} else {
if len(pbc) != 0 {
log.Panic("mesh: need 0 or 3 PBC arguments, got:", pbc)
}
}
size := [3]int{N0, N1, N2}
gneb := [2]int{gneb2D, gneb3D}
return &Mesh{size, [3]float64{cellx, celly, cellz}, pbc3, "m", noi, gneb}
}
// Returns N0, N1, N2, as passed to constructor.
func (m *Mesh) Size() [3]int {
if m == nil {
return [3]int{0, 0, 0}
} else {
return m.gridSize
}
}
// // Returns Number of Images as passed to constructor.
func (m *Mesh) NumberOfImages() int {
return m.noi
}
// Returns cellx, celly, cellz, as passed to constructor.
func (m *Mesh) CellSize() [3]float64 {
return m.cellSize
}
// Returns pbc (periodic boundary conditions), as passed to constructor.
func (m *Mesh) PBC() [3]int {
return m.pbc
}
func (m *Mesh) GNEB() [2]int {
return m.gneb
}
func (m *Mesh) SetGNEB(gneb2D, gneb3D int) {
m.gneb = [2]int{gneb2D, gneb3D}
}
func (m *Mesh) SetPBC(nx, ny, nz int) {
m.pbc = [3]int{nx, ny, nz}
}
// Total number of cells, not taking into account PBCs.
// N0 * N1 * N2
func (m *Mesh) NCell() int {
return m.gridSize[0] * m.gridSize[1] * m.gridSize[2]
}
// WorldSize equals (grid)Size x CellSize.
func (m *Mesh) WorldSize() [3]float64 {
return [3]float64{float64(m.gridSize[0]) * m.cellSize[0], float64(m.gridSize[1]) * m.cellSize[1], float64(m.gridSize[2]) * m.cellSize[2]}
}
// 3 bools, packed in one byte, indicating whether there are periodic boundary conditions in
// X (LSB), Y(LSB<<1), Z(LSB<<2)
func (m *Mesh) PBC_code() byte {
var code byte
if m.pbc[X] != 0 {
code = 1
}
if m.pbc[Y] != 0 {
code |= 2
}
if m.pbc[Z] != 0 {
code |= 4
}
return code
}
func (m *Mesh) GNEB_code() byte {
var code byte
if m.gneb[X] != 0 {
code = 1
}
if m.gneb[Y] != 0 {
code |= 2
}
return code
}
func (m *Mesh) String() string {
s := m.gridSize
c := m.cellSize
pbc := ""
if m.pbc != [3]int{0, 0, 0} {
pbc = fmt.Sprintf(", PBC: [%v x %v x %v],", m.pbc[0], m.pbc[1], m.pbc[2])
}
return fmt.Sprintf("[%v x %v x %v] x [%vm x %vm x %vm]%v", s[0], s[1], s[2], float32(c[0]), float32(c[1]), float32(c[2]), pbc)
}
// product of elements.
func prod(size [3]int) int {
return size[0] * size[1] * size[2]
}