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
use serde::{Deserialize, Serialize};
/// Specifies the Mandel representation
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub enum Mandel {
/// General representation of a 3×3 Tensor2 as a 9D vector
///
/// ```text
/// ┌ ┐
/// 00 │ T00 │ 0
/// 11 │ T11 │ 1
/// ┌ ┐ 22 │ T22 │ 2
/// │ T00 T01 T02 │ 01 │ (T01+T10) / √2 │ 3
/// │ T10 T11 T12 │ => 12 │ (T12+T21) / √2 │ 4
/// │ T20 T21 T22 │ 02 │ (T02+T20) / √2 │ 5
/// └ ┘ 10 │ (T01-T10) / √2 │ 6
/// 21 │ (T12-T21) / √2 │ 7
/// 20 │ (T02-T20) / √2 │ 8
/// └ ┘
/// ```
General,
/// Mandel representation of a symmetric 3×3 Tensor2 as a 6D vector
///
/// ```text
/// ┌ ┐
/// ┌ ┐ 00 │ T00 │ 0
/// │ T00 T01 T02 │ 11 │ T11 │ 1
/// │ T01 T11 T12 │ => 22 │ T22 │ 2
/// │ T02 T12 T22 │ 01 │ T01 * √2 │ 3
/// └ ┘ 12 │ T12 * √2 │ 4
/// 02 │ T02 * √2 │ 5
/// └ ┘
/// ```
///
/// **NOTE:** For Tensor4, "symmetric" means **minor-symmetric**
Symmetric,
/// Mandel representation of a symmetric 3×3 Tensor2 as a 4D vector (useful in 2D simulations)
///
/// ```text
/// ┌ ┐ ┌ ┐
/// │ T00 T01 │ 00 │ T00 │ 0
/// │ T01 T11 │ => 11 │ T11 │ 1
/// │ T22 │ 22 │ T22 │ 2
/// └ ┘ 01 │ T01 * √2 │ 3
/// └ ┘
///
/// **NOTE:** For Tensor4, "symmetric" means **minor-symmetric**
Symmetric2D,
}
impl Mandel {
/// Returns a new Mandel enum given the vector size (4, 6, 9)
pub fn new(vector_dim: usize) -> Self {
match vector_dim {
4 => Mandel::Symmetric2D,
6 => Mandel::Symmetric,
_ => Mandel::General,
}
}
/// Returns the dimension of the Mandel vector
pub fn dim(&self) -> usize {
match self {
Mandel::General => 9,
Mandel::Symmetric => 6,
Mandel::Symmetric2D => 4,
}
}
/// Returns whether the space dimension is 2D or not
///
/// Note: only Symmetric2D yields "true".
pub fn two_dim(&self) -> bool {
match self {
Mandel::General => false,
Mandel::Symmetric => false,
Mandel::Symmetric2D => true,
}
}
/// Returns whether the Mandel vector or matrix corresponds a symmetric tensor or not
pub fn symmetric(&self) -> bool {
if *self == Mandel::General { false } else { true }
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[cfg(test)]
mod tests {
use super::Mandel;
#[test]
fn derive_works() {
let mandel = Mandel::General.clone();
assert_eq!(mandel, Mandel::General);
assert_eq!(format!("{:?}", mandel), "General");
assert_eq!(mandel, Mandel::General);
}
#[test]
fn new_works() {
assert_eq!(Mandel::new(4), Mandel::Symmetric2D);
assert_eq!(Mandel::new(6), Mandel::Symmetric);
assert_eq!(Mandel::new(9), Mandel::General);
assert_eq!(Mandel::new(123), Mandel::General);
}
#[test]
fn member_functions_work() {
// dim
assert_eq!(Mandel::General.dim(), 9);
assert_eq!(Mandel::Symmetric.dim(), 6);
assert_eq!(Mandel::Symmetric2D.dim(), 4);
// two_dim
assert_eq!(Mandel::General.two_dim(), false);
assert_eq!(Mandel::Symmetric.two_dim(), false);
assert_eq!(Mandel::Symmetric2D.two_dim(), true);
// symmetric
assert_eq!(Mandel::General.symmetric(), false);
assert_eq!(Mandel::Symmetric.symmetric(), true);
assert_eq!(Mandel::Symmetric2D.symmetric(), true);
}
}