castep_param_io/param/pseudopotentials/
mod.rs1use serde::{Deserialize, Serialize};
2use std::fmt::Display;
3
4use crate::param::KeywordDisplay;
5
6use derive_builder::Builder;
7pub use pspot_beta_phi_type::PSPotBetaPhiType;
8pub use pspot_nonlocal_type::PSPotNonlocalType;
9pub use relativistic_treatment::RelativisticTreatment;
10
11mod pspot_beta_phi_type;
12mod pspot_nonlocal_type;
13mod relativistic_treatment;
14
15#[derive(
16 Debug,
17 Clone,
18 Copy,
19 Hash,
20 Serialize,
21 Deserialize,
22 PartialEq,
23 Eq,
24 PartialOrd,
25 Ord,
26 Builder,
27 Default,
28)]
29#[builder(
30 setter(into, strip_option),
31 default,
32 build_fn(validate = "Self::validate")
33)]
34pub struct Pseudopotentials {
35 pub pspot_beta_phi_type: Option<PSPotBetaPhiType>,
36 pub pspot_nonlocal_type: Option<PSPotNonlocalType>,
37 pub relativistic_treatment: Option<RelativisticTreatment>,
38}
39
40impl Display for Pseudopotentials {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 let output = [
43 self.pspot_beta_phi_type.map(|v| v.output()),
44 self.pspot_nonlocal_type.map(|v| v.output()),
45 self.relativistic_treatment.map(|v| v.output()),
46 ]
47 .into_iter()
48 .flatten()
49 .collect::<Vec<String>>()
50 .join("\n");
51 write!(f, "{}", output)
52 }
53}
54impl PseudopotentialsBuilder {
55 fn validate(builder: &PseudopotentialsBuilder) -> Result<(), String> {
56 if let Some(Some(non)) = builder.pspot_nonlocal_type {
57 match non {
58 PSPotNonlocalType::Reciprocal => match builder.pspot_beta_phi_type {
59 Some(Some(b)) => match b {
60 PSPotBetaPhiType::Reciprocal => Ok(()),
61 PSPotBetaPhiType::Real => Err("The `pspot_beta_phi_type` can only take `REAL` if `pspot_nonlocal_type` is also `REAL`".to_string())
62 },
63 Some(None) => Ok(()),
64 None => Ok(()),
65 },
66 PSPotNonlocalType::Real => Ok(()),
67 }
68 } else {
69 Ok(())
70 }
71 }
72}
73
74#[cfg(test)]
75mod test {
76 use crate::param::pseudopotentials::{
77 PSPotBetaPhiType, PSPotNonlocalType, RelativisticTreatment,
78 };
79
80 use super::PseudopotentialsBuilder;
81
82 #[test]
83 fn pseudopotentials() {
84 let p = PseudopotentialsBuilder::default()
85 .pspot_beta_phi_type(PSPotBetaPhiType::Real)
86 .pspot_nonlocal_type(PSPotNonlocalType::Real)
87 .relativistic_treatment(RelativisticTreatment::Zora)
88 .build()
89 .unwrap();
90 println!("{p}");
91 let p = PseudopotentialsBuilder::default()
92 .pspot_beta_phi_type(PSPotBetaPhiType::Real)
93 .pspot_nonlocal_type(PSPotNonlocalType::Reciprocal)
94 .relativistic_treatment(RelativisticTreatment::Zora)
95 .build();
96 assert!(p.is_err());
97 let p = PseudopotentialsBuilder::default()
98 .pspot_nonlocal_type(PSPotNonlocalType::Reciprocal)
99 .relativistic_treatment(RelativisticTreatment::Zora)
100 .build();
101 assert!(p.is_ok());
102 let p = PseudopotentialsBuilder::default()
103 .pspot_beta_phi_type(PSPotBetaPhiType::Reciprocal)
104 .pspot_nonlocal_type(PSPotNonlocalType::Real)
105 .relativistic_treatment(RelativisticTreatment::Zora)
106 .build();
107 assert!(p.is_ok());
108 }
109}