Skip to content

Commit 63b7a02

Browse files
committed
Add SphereInCuboid geometry
1 parent 7a65204 commit 63b7a02

File tree

4 files changed

+218
-0
lines changed

4 files changed

+218
-0
lines changed

src/enums.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub enum MaterialType {
55
MESH1D(material::Material<geometry::Mesh1D>),
66
MESH2D(material::Material<geometry::Mesh2D>),
77
SPHERE(material::Material<sphere::Sphere>),
8+
SPHEREINCUBOID(material::Material<sphereincuboid::SphereInCuboid>),
89
#[cfg(feature = "parry3d")]
910
BALL(material::Material<parry::ParryBall>),
1011
#[cfg(feature = "parry3d")]
@@ -26,6 +27,7 @@ pub enum GeometryType {
2627
MESH1D,
2728
MESH2D,
2829
SPHERE,
30+
SPHEREINCUBOID,
2931
#[cfg(feature = "parry3d")]
3032
BALL,
3133
#[cfg(feature = "parry3d")]

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub mod enums;
6666
pub mod consts;
6767
pub mod structs;
6868
pub mod sphere;
69+
pub mod sphereincuboid;
6970

7071
#[cfg(feature = "parry3d")]
7172
pub mod parry;
@@ -77,6 +78,7 @@ pub use crate::input::{Input2D, InputHomogeneous2D, Input1D, Input0D, Options, I
7778
pub use crate::output::{OutputUnits};
7879
pub use crate::geometry::{Geometry, GeometryElement, Mesh0D, Mesh1D, Mesh2D};
7980
pub use crate::sphere::{Sphere, SphereInput, InputSphere};
81+
pub use crate::sphereincuboid::{SphereInCuboid, SphereInCuboidInput, InputSphereInCuboid};
8082

8183
#[cfg(feature = "parry3d")]
8284
pub use crate::parry::{ParryBall, ParryBallInput, InputParryBall, ParryTriMesh, ParryTriMeshInput, InputParryTriMesh};

src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub mod enums;
4848
pub mod consts;
4949
pub mod structs;
5050
pub mod sphere;
51+
pub mod sphereincuboid;
5152
pub mod physics;
5253

5354
#[cfg(feature = "parry3d")]
@@ -60,6 +61,7 @@ pub use crate::input::{Input2D, InputHomogeneous2D, Input1D, Input0D, Options, I
6061
pub use crate::output::{OutputUnits};
6162
pub use crate::geometry::{Geometry, GeometryElement, Mesh0D, Mesh1D, Mesh2D, HomogeneousMesh2D};
6263
pub use crate::sphere::{Sphere, SphereInput, InputSphere};
64+
pub use crate::sphereincuboid::{SphereInCuboid, SphereInCuboidInput, InputSphereInCuboid};
6365
pub use crate::physics::{physics_loop};
6466

6567
#[cfg(feature = "parry3d")]
@@ -77,6 +79,7 @@ fn main() {
7779
"1D" => GeometryType::MESH1D,
7880
"2D" => GeometryType::MESH2D,
7981
"SPHERE" => GeometryType::SPHERE,
82+
"SPHEREINCUBOID" => GeometryType::SPHEREINCUBOID,
8083
#[cfg(feature = "parry3d")]
8184
"BALL" => GeometryType::BALL,
8285
#[cfg(feature = "parry3d")]
@@ -104,6 +107,10 @@ fn main() {
104107
let (particle_input_array, material, options, output_units) = input::input::<Sphere>(input_file);
105108
physics_loop::<Sphere>(particle_input_array, material, options, output_units);
106109
},
110+
GeometryType::SPHEREINCUBOID => {
111+
let (particle_input_array, material, options, output_units) = input::input::<SphereInCuboid>(input_file);
112+
physics_loop::<SphereInCuboid>(particle_input_array, material, options, output_units);
113+
},
107114
#[cfg(feature = "parry3d")]
108115
GeometryType::BALL => {
109116
let (particle_input_array, material, options, output_units) = input::input::<ParryBall>(input_file);

src/sphereincuboid.rs

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
use super::*;
2+
3+
#[derive(Deserialize, Clone)]
4+
pub struct InputSphereInCuboid {
5+
pub options: Options,
6+
pub material_parameters: material::MaterialParameters,
7+
pub particle_parameters: particle::ParticleParameters,
8+
pub geometry_input: sphereincuboid::SphereInCuboidInput,
9+
}
10+
11+
impl InputFile for InputSphereInCuboid {
12+
13+
fn new(string: &str) -> InputSphereInCuboid {
14+
toml::from_str(string).context("Could not parse TOML file. Be sure you are using the correct input file mode (e.g., ./RustBCA SPHERE sphere.toml or RustBCA.exe 0D mesh_0d.toml).").unwrap()
15+
}
16+
17+
fn get_options(&self) -> &Options{
18+
&self.options
19+
}
20+
fn get_material_parameters(&self) -> &material::MaterialParameters{
21+
&self.material_parameters
22+
}
23+
fn get_particle_parameters(&self) -> &particle::ParticleParameters{
24+
&self.particle_parameters
25+
}
26+
fn get_geometry_input(&self) -> &Self::GeometryInput{
27+
&self.geometry_input
28+
}
29+
}
30+
31+
#[derive(Deserialize, Clone)]
32+
pub struct SphereInCuboidInput {
33+
pub length_unit: String,
34+
35+
pub sphere_radius: f64,
36+
pub sphere_densities: Vec<f64>,
37+
pub sphere_electronic_stopping_correction_factor: f64,
38+
39+
pub cuboid_corners: Vec<(f64, f64, f64)>,
40+
pub cuboid_densities: Vec<f64>,
41+
pub cuboid_electronic_stopping_correction_factor: f64,
42+
}
43+
44+
#[derive(Clone)]
45+
pub struct SphereInCuboid {
46+
pub sphere_radius: f64,
47+
pub sphere_densities: Vec<f64>,
48+
pub sphere_concentrations: Vec<f64>,
49+
pub sphere_electronic_stopping_correction_factor: f64,
50+
51+
pub cuboid_corners: Vec<(f64, f64, f64)>,
52+
pub cuboid_densities: Vec<f64>,
53+
pub cuboid_concentrations: Vec<f64>,
54+
pub cuboid_electronic_stopping_correction_factor: f64,
55+
56+
pub energy_barrier_thickness: f64,
57+
}
58+
59+
impl GeometryInput for InputSphereInCuboid {
60+
type GeometryInput = SphereInCuboidInput;
61+
}
62+
63+
impl Geometry for SphereInCuboid {
64+
65+
type InputFileFormat = InputSphereInCuboid;
66+
67+
fn new(input: &<<Self as Geometry>::InputFileFormat as GeometryInput>::GeometryInput) -> SphereInCuboid {
68+
69+
let length_unit: f64 = match input.length_unit.as_str() {
70+
"MICRON" => MICRON,
71+
"CM" => CM,
72+
"MM" => MM,
73+
"ANGSTROM" => ANGSTROM,
74+
"NM" => NM,
75+
"M" => 1.,
76+
_ => input.length_unit.parse()
77+
.expect(format!(
78+
"Input errror: could nor parse length unit {}. Use a valid float or one of ANGSTROM, NM, MICRON, CM, MM, M",
79+
&input.length_unit.as_str()
80+
).as_str()),
81+
};
82+
83+
let sphere_radius: f64 = input.sphere_radius*length_unit;
84+
let sphere_densities: Vec<f64> = input.sphere_densities
85+
.iter().map(|element| element/(length_unit).powi(3)).collect();
86+
let sphere_total_density: f64 = sphere_densities.iter().sum();
87+
let sphere_concentrations: Vec<f64> = sphere_densities
88+
.iter().map(|&density| density/sphere_total_density).collect::<Vec<f64>>();
89+
let sphere_electronic_stopping_correction_factor: f64 = input.sphere_electronic_stopping_correction_factor;
90+
91+
let cuboid_corners: Vec<(f64, f64, f64)> = input.cuboid_corners
92+
.iter().map(
93+
|&(x, y, z)| (x * length_unit, y*length_unit, z*length_unit)
94+
).collect();
95+
let cuboid_densities: Vec<f64> = input.cuboid_densities
96+
.iter().map(|element| element/(length_unit).powi(3)).collect();
97+
let cuboid_total_density: f64 = cuboid_densities.iter().sum();
98+
let cuboid_concentrations: Vec<f64> = cuboid_densities
99+
.iter().map(|&density| density/cuboid_total_density).collect::<Vec<f64>>();
100+
let cuboid_electronic_stopping_correction_factor: f64 = input.cuboid_electronic_stopping_correction_factor;
101+
102+
let energy_barrier_thickness: f64 = cuboid_total_density.powf(-1./3.)/SQRTPI*2.;
103+
104+
SphereInCuboid {
105+
sphere_radius,
106+
sphere_densities,
107+
sphere_concentrations,
108+
sphere_electronic_stopping_correction_factor,
109+
110+
cuboid_corners,
111+
cuboid_densities,
112+
cuboid_concentrations,
113+
cuboid_electronic_stopping_correction_factor,
114+
115+
energy_barrier_thickness,
116+
}
117+
}
118+
119+
fn get_densities(&self, x: f64, y: f64, z: f64) -> &Vec<f64> {
120+
let r: f64 = (x.powi(2) + y.powi(2) + z.powi(2)).sqrt();
121+
if r > self.sphere_radius {
122+
&self.cuboid_densities
123+
} else {
124+
&self.sphere_densities
125+
}
126+
}
127+
128+
fn get_ck(&self, x: f64, y: f64, z: f64) -> f64 {
129+
let r: f64 = (x.powi(2) + y.powi(2) + z.powi(2)).sqrt();
130+
if r > self.sphere_radius {
131+
self.cuboid_electronic_stopping_correction_factor
132+
} else {
133+
self.sphere_electronic_stopping_correction_factor
134+
}
135+
}
136+
137+
fn get_total_density(&self, x: f64, y: f64, z: f64) -> f64{
138+
let r: f64 = (x.powi(2) + y.powi(2) + z.powi(2)).sqrt();
139+
if r > self.sphere_radius {
140+
self.cuboid_densities.iter().sum()
141+
} else {
142+
self.sphere_densities.iter().sum()
143+
}
144+
}
145+
146+
fn get_concentrations(&self, x: f64, y: f64, z: f64) -> &Vec<f64> {
147+
let r: f64 = (x.powi(2) + y.powi(2) + z.powi(2)).sqrt();
148+
if r > self.sphere_radius {
149+
&self.cuboid_concentrations
150+
} else {
151+
&self.sphere_concentrations
152+
}
153+
}
154+
155+
fn inside(&self, x: f64, y: f64, z: f64) -> bool {
156+
let (xlo, ylo, zlo): (f64, f64, f64) = self.cuboid_corners[0];
157+
let (xhi, yhi, zhi): (f64, f64, f64) = self.cuboid_corners[1];
158+
159+
xlo <= x && x <= xhi &&
160+
ylo <= y && y <= yhi &&
161+
zlo <= z && z <= zhi
162+
}
163+
164+
fn inside_simulation_boundary(&self, x: f64, y: f64, z: f64) -> bool {
165+
let (xlo, ylo, zlo): (f64, f64, f64) = self.cuboid_corners[0];
166+
let (xhi, yhi, zhi): (f64, f64, f64) = self.cuboid_corners[1];
167+
let ebt: f64 = self.energy_barrier_thickness;
168+
169+
(xlo - 10.0 * ebt) <= x && x <= (xhi + 10.0 * ebt) &&
170+
(ylo - 10.0 * ebt) <= y && y <= (yhi + 10.0 * ebt) &&
171+
(zlo - 10.0 * ebt) <= z && z <= (zhi + 10.0 * ebt)
172+
}
173+
174+
fn inside_energy_barrier(&self, x: f64, y: f64, z: f64) -> bool {
175+
let (xlo, ylo, zlo): (f64, f64, f64) = self.cuboid_corners[0];
176+
let (xhi, yhi, zhi): (f64, f64, f64) = self.cuboid_corners[1];
177+
let ebt: f64 = self.energy_barrier_thickness;
178+
179+
(xlo - ebt) <= x && x <= (xhi + ebt) &&
180+
(ylo - ebt) <= y && y <= (yhi + ebt) &&
181+
(zlo - ebt) <= z && z <= (zhi + ebt)
182+
}
183+
184+
fn closest_point(&self, x: f64, y: f64, z: f64) -> (f64, f64, f64) {
185+
let (xlo, ylo, zlo): (f64, f64, f64) = self.cuboid_corners[0];
186+
let (xhi, yhi, zhi): (f64, f64, f64) = self.cuboid_corners[1];
187+
188+
if self.inside(x, y, z) {
189+
let faces: [((f64, f64, f64), f64); 6] = [
190+
((xlo, y, z), x - xlo),
191+
((xhi, y, z), xhi - x),
192+
((x, ylo, z), y - ylo),
193+
((x, yhi, z), yhi - y),
194+
((x, y, zlo), z - zlo),
195+
((x, y, zhi), zhi - z),
196+
];
197+
198+
let closest: ((f64, f64, f64), f64) = *faces
199+
.iter()
200+
.min_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
201+
.unwrap();
202+
closest.0
203+
} else {
204+
(x.max(xlo).min(xhi), y.max(ylo).min(yhi), z.max(zlo).min(zhi))
205+
}
206+
}
207+
}

0 commit comments

Comments
 (0)