Skip to content

Commit f5776f8

Browse files
committed
Added tests for distribution output.
1 parent 232f5c6 commit f5776f8

File tree

3 files changed

+224
-13
lines changed

3 files changed

+224
-13
lines changed

.github/workflows/rustbca_compile_check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
sudo apt install libhdf5-dev
3838
- name: Test RustBCA
3939
run: |
40-
cargo test --features cpr_rootfinder_netlib,hdf5_input
40+
cargo test --features cpr_rootfinder_netlib,hdf5_input,distributions
4141
- name: Run Examples
4242
run: |
4343
cargo run --release 0D examples/boron_nitride_0D.toml

src/output.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@ use ndarray::prelude::*;
3030
#[derive(Serialize)]
3131
#[cfg(feature = "distributions")]
3232
pub struct Distributions {
33-
energies: Array1<f64>,
34-
angles: Array1<f64>,
35-
x_range: Array1<f64>,
36-
y_range: Array1<f64>,
37-
z_range: Array1<f64>,
38-
reflected_ead: Array2<usize>,
39-
sputtered_ead: Array2<usize>,
40-
implanted_x: Array1<usize>,
41-
implanted_y: Array1<usize>,
42-
implanted_z: Array1<usize>,
43-
electronic_energy_loss_x: Array1<f64>,
44-
nuclear_energy_loss_x: Array1<f64>,
33+
pub energies: Array1<f64>,
34+
pub angles: Array1<f64>,
35+
pub x_range: Array1<f64>,
36+
pub y_range: Array1<f64>,
37+
pub z_range: Array1<f64>,
38+
pub reflected_ead: Array2<usize>,
39+
pub sputtered_ead: Array2<usize>,
40+
pub implanted_x: Array1<usize>,
41+
pub implanted_y: Array1<usize>,
42+
pub implanted_z: Array1<usize>,
43+
pub electronic_energy_loss_x: Array1<f64>,
44+
pub nuclear_energy_loss_x: Array1<f64>,
4545
}
4646

4747
#[cfg(feature = "distributions")]

src/tests.rs

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,141 @@ use super::*;
33
#[cfg(test)]
44
use float_cmp::*;
55

6+
#[test]
7+
#[cfg(feature = "distributions")]
8+
fn test_distributions() {
9+
10+
let options = Options {
11+
name: "test".to_string(),
12+
track_trajectories: false,
13+
track_recoils: false,
14+
track_recoil_trajectories: false,
15+
write_buffer_size: 8000,
16+
weak_collision_order: 0,
17+
suppress_deep_recoils: false,
18+
high_energy_free_flight_paths: false,
19+
electronic_stopping_mode: ElectronicStoppingMode::INTERPOLATED,
20+
mean_free_path_model: MeanFreePathModel::LIQUID,
21+
interaction_potential: vec![vec![InteractionPotential::KR_C]],
22+
scattering_integral: vec![vec![ScatteringIntegral::MENDENHALL_WELLER]],
23+
num_threads: 1,
24+
num_chunks: 1,
25+
use_hdf5: false,
26+
root_finder: vec![vec![Rootfinder::NEWTON{max_iterations: 100, tolerance: 1E-3}]],
27+
track_displacements: false,
28+
track_energy_losses: true,
29+
energy_min: 0.0,
30+
energy_max: 10.0,
31+
energy_num: 11,
32+
angle_min: 0.0,
33+
angle_max: 90.0,
34+
angle_num: 11,
35+
x_min: 0.0,
36+
y_min: -10.0,
37+
z_min: -10.0,
38+
x_max: 10.0,
39+
y_max: 10.0,
40+
z_max: 10.0,
41+
x_num: 11,
42+
y_num: 11,
43+
z_num: 11,
44+
};
45+
46+
let output_units = OutputUnits {
47+
length_unit: 1.0,
48+
energy_unit: 1.0,
49+
mass_unit: 1.0,
50+
};
51+
52+
let mass = 1.0;
53+
let Z = 1.0;
54+
let E = 1.5;
55+
let Ec = 0.0;
56+
let Es = 0.0;
57+
let x = 0.0;
58+
let y = 0.0;
59+
let z = 0.0;
60+
let cosx = 0.0;
61+
let cosy = 0.0;
62+
let cosz = 0.0;
63+
let mut particle = particle::Particle::new(mass, Z, E, Ec, Es, x, y, z, cosx, cosy, cosz, false, false, 0);
64+
65+
66+
67+
let mut distributions = output::Distributions::new(&options);
68+
assert_eq!(distributions.x_range[0], 0.);
69+
assert_eq!(distributions.x_range[distributions.x_range.len() - 1], 10.);
70+
assert_eq!(distributions.y_range[0], -10.);
71+
assert_eq!(distributions.y_range[distributions.y_range.len() - 1], 10.);
72+
assert_eq!(distributions.z_range[0], -10.);
73+
assert_eq!(distributions.z_range[distributions.z_range.len() - 1], 10.);
74+
assert_eq!(distributions.x_range.len(), 11);
75+
assert_eq!(distributions.y_range.len(), 11);
76+
assert_eq!(distributions.z_range.len(), 11);
77+
78+
particle.incident = true;
79+
particle.stopped = true;
80+
particle.pos.x = 0.0;
81+
distributions.update(&particle, &output_units, &options, 1);
82+
assert_eq!(distributions.implanted_x[0], 1);
83+
84+
particle.pos.x = 10.0;
85+
distributions.update(&particle, &output_units, &options, 1);
86+
assert_eq!(distributions.implanted_x[10], 1);
87+
88+
distributions.update(&particle, &output_units, &options, 1);
89+
assert_eq!(distributions.implanted_y[5], 3);
90+
assert_eq!(distributions.implanted_z[5], 3);
91+
92+
particle.incident = false;
93+
particle.stopped = false;
94+
particle.left = true;
95+
particle.E = 0.0;
96+
particle.dir.x = -0.999;
97+
particle.dir.y = 0.001;
98+
particle.dir.z = 0.0;
99+
particle.dir.normalize();
100+
101+
distributions.update(&particle, &output_units, &options, 1);
102+
assert_eq!(distributions.sputtered_ead[[0, 0]], 1);
103+
104+
particle.E = -0.1;
105+
distributions.update(&particle, &output_units, &options, 1);
106+
assert_eq!(distributions.sputtered_ead[[0, 0]], 1);
107+
108+
particle.E = 10.0;
109+
distributions.update(&particle, &output_units, &options, 1);
110+
assert_eq!(distributions.sputtered_ead[[10, 0]], 1);
111+
112+
particle.dir = Vector::new(-0.707, 0.707, 0.0);
113+
particle.dir.normalize();
114+
distributions.update(&particle, &output_units, &options, 1);
115+
assert_eq!(distributions.sputtered_ead[[10, 5]], 1);
116+
117+
particle.incident = true;
118+
particle.E = 0.0;
119+
particle.dir.x = -0.999;
120+
particle.dir.y = 0.001;
121+
particle.dir.z = 0.0;
122+
particle.dir.normalize();
123+
124+
distributions.update(&particle, &output_units, &options, 1);
125+
assert_eq!(distributions.reflected_ead[[0, 0]], 1);
126+
127+
particle.E = -0.1;
128+
distributions.update(&particle, &output_units, &options, 1);
129+
assert_eq!(distributions.reflected_ead[[0, 0]], 1);
130+
131+
particle.E = 10.0;
132+
distributions.update(&particle, &output_units, &options, 1);
133+
assert_eq!(distributions.reflected_ead[[10, 0]], 1);
134+
135+
particle.dir = Vector::new(-0.707, 0.707, 0.0);
136+
particle.dir.normalize();
137+
distributions.update(&particle, &output_units, &options, 1);
138+
assert_eq!(distributions.reflected_ead[[10, 5]], 1);
139+
}
140+
6141
#[test]
7142
fn test_spherical_geometry() {
8143
let mass = 1.;
@@ -442,6 +577,7 @@ fn test_momentum_conservation() {
442577

443578
let mut particle_1 = particle::Particle::new(m1, Z1, E1, Ec1, Es1, x1, y1, z1, cosx, cosy, cosz, false, false, 0);
444579

580+
#[cfg(not(feature = "distributions"))]
445581
let options = Options {
446582
name: "test".to_string(),
447583
track_trajectories: false,
@@ -463,6 +599,43 @@ fn test_momentum_conservation() {
463599
track_energy_losses: false,
464600
};
465601

602+
#[cfg(feature = "distributions")]
603+
let options = Options {
604+
name: "test".to_string(),
605+
track_trajectories: false,
606+
track_recoils: true,
607+
track_recoil_trajectories: false,
608+
write_buffer_size: 8000,
609+
weak_collision_order: 0,
610+
suppress_deep_recoils: false,
611+
high_energy_free_flight_paths: high_energy_free_flight_paths,
612+
electronic_stopping_mode: ElectronicStoppingMode::INTERPOLATED,
613+
mean_free_path_model: MeanFreePathModel::LIQUID,
614+
interaction_potential: vec![vec![potential]],
615+
scattering_integral: vec![vec![scattering_integral]],
616+
num_threads: 1,
617+
num_chunks: 1,
618+
use_hdf5: false,
619+
root_finder: vec![vec![root_finder]],
620+
track_displacements: false,
621+
track_energy_losses: false,
622+
energy_min: 0.0,
623+
energy_max: 10.0,
624+
energy_num: 11,
625+
angle_min: 0.0,
626+
angle_max: 90.0,
627+
angle_num: 11,
628+
x_min: 0.0,
629+
y_min: -10.0,
630+
z_min: -10.0,
631+
x_max: 10.0,
632+
y_max: 10.0,
633+
z_max: 10.0,
634+
x_num: 11,
635+
y_num: 11,
636+
z_num: 11,
637+
};
638+
466639
let binary_collision_geometries = bca::determine_mfp_phi_impact_parameter(&mut particle_1, &material_1, &options);
467640

468641
println!("Phi: {} rad p: {} Angstrom mfp: {} Angstrom", binary_collision_geometries[0].phi_azimuthal,
@@ -602,6 +775,29 @@ fn test_quadrature() {
602775
let p = 1.*ANGSTROM;
603776
let a = interactions::screening_length(Za, Zb, InteractionPotential::KR_C);
604777

778+
#[cfg(not(feature = "distributions"))]
779+
let options = Options {
780+
name: "test".to_string(),
781+
track_trajectories: false,
782+
track_recoils: true,
783+
track_recoil_trajectories: false,
784+
write_buffer_size: 8000,
785+
weak_collision_order: 0,
786+
suppress_deep_recoils: false,
787+
high_energy_free_flight_paths: false,
788+
electronic_stopping_mode: ElectronicStoppingMode::INTERPOLATED,
789+
mean_free_path_model: MeanFreePathModel::LIQUID,
790+
interaction_potential: vec![vec![InteractionPotential::KR_C]],
791+
scattering_integral: vec![vec![ScatteringIntegral::MENDENHALL_WELLER]],
792+
num_threads: 1,
793+
num_chunks: 1,
794+
use_hdf5: false,
795+
root_finder: vec![vec![Rootfinder::NEWTON{max_iterations: 100, tolerance: 1E-14}]],
796+
track_displacements: false,
797+
track_energy_losses: false,
798+
};
799+
800+
#[cfg(feature = "distributions")]
605801
let options = Options {
606802
name: "test".to_string(),
607803
track_trajectories: false,
@@ -621,6 +817,21 @@ fn test_quadrature() {
621817
root_finder: vec![vec![Rootfinder::NEWTON{max_iterations: 100, tolerance: 1E-14}]],
622818
track_displacements: false,
623819
track_energy_losses: false,
820+
energy_min: 0.0,
821+
energy_max: 10.0,
822+
energy_num: 11,
823+
angle_min: 0.0,
824+
angle_max: 90.0,
825+
angle_num: 11,
826+
x_min: 0.0,
827+
y_min: -10.0,
828+
z_min: -10.0,
829+
x_max: 10.0,
830+
y_max: 10.0,
831+
z_max: 10.0,
832+
x_num: 11,
833+
y_num: 11,
834+
z_num: 11,
624835
};
625836

626837
let x0_newton = bca::newton_rootfinder(Za, Zb, Ma, Mb, E0, p, InteractionPotential::KR_C, 100, 1E-12).unwrap();

0 commit comments

Comments
 (0)