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
#![feature(inclusive_range_syntax)]
#![feature(step_by)]
#![feature(slice_patterns)]
extern crate rulinalg;
extern crate num;
use num::{Float, NumCast};
use rulinalg::matrix::{BaseMatrix, Matrix};
use topo::{pairwise_dist, uniform_grid};
pub struct ElectroGrid<T,U>
where T: Float, U: Float {
pub space: Matrix<[U; 2]>,
pub potential: Matrix<T>,
pub permittivity: Matrix<T>,
pub charge: Option<Matrix<T>>
}
impl<T, U> ElectroGrid<T,U>
where T: Float, U: Float {
pub fn uniform_freespace(x_size: U, y_size: U, spacing: U, potential: T) ->
ElectroGrid<T, U>
where T: Float, U: Float {
let space_grid = uniform_grid(spacing, x_size, y_size);
let row_count = space_grid.rows();
let col_count = space_grid.cols();
ElectroGrid {
space: space_grid,
potential: Matrix::from_fn(row_count,
col_count,
|_,_| { potential.clone() }),
permittivity: Matrix::ones(row_count, col_count),
charge: None
}
}
pub fn uniform_freespace_zero(x_size: U, y_size: U, spacing: U) ->
ElectroGrid<T, U>
where T: Float, U: Float {
ElectroGrid::uniform_freespace(x_size, y_size, spacing,
NumCast::from(0).unwrap())
}
pub fn uniform_freespace_unit(x_size: U, y_size: U, spacing: U) ->
ElectroGrid<T, U>
where T: Float, U: Float {
ElectroGrid::uniform_freespace(x_size, y_size, spacing,
NumCast::from(1).unwrap())
}
pub fn space_area(&self, element_ind: [usize; 2]) -> U {
let two = NumCast::from(2.0).unwrap();
let mut left_dist = NumCast::from(0.0).unwrap();
let mut right_dist = NumCast::from(0.0).unwrap();
let mut up_dist = NumCast::from(0.0).unwrap();
let mut down_dist = NumCast::from(0.0).unwrap();
if element_ind[0] > 0 {
let left_neighbor = self.space[[element_ind[0] - 1, element_ind[1]]];
left_dist = pairwise_dist(&self.space[element_ind], left_neighbor) / two;
}
if element_ind[0] < self.space.rows() - 1 {
let right_neighbor = self.space[[element_ind[0] + 1, element_ind[1]]];
right_dist = pairwise_dist(&self.space[element_ind], right_neighbor) / two;
}
if element_ind[1] > 0 {
let up_neighbor = self.space[[element_ind[0], element_ind[1] - 1]];
up_dist = pairwise_dist(&self.space[element_ind], up_neighbor) / two;
}
if element_ind[1] < self.space.cols() - 1 {
let down_neighbor = self.space[[element_ind[0], element_ind[1] + 1]];
down_dist = pairwise_dist(&self.space[element_ind], down_neighbor) / two;
}
NumCast::from((left_dist + right_dist) * (up_dist + down_dist)).unwrap()
}
}
pub mod topo;
pub mod material;
pub mod fd;
pub mod mm;
pub mod fem;