castep_cell_io/param/geometry_optimization/
geom_method.rs1use castep_cell_fmt::{Cell, CellValue, ToCell, ToCellValue};
2use castep_cell_fmt::parse::{FromCellValue, FromKeyValue};
3use castep_cell_fmt::{CResult, Error};
4use castep_cell_fmt::query::value_as_str;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename = "GEOM_METHOD")]
17#[derive(Default)]
18pub enum GeomMethod {
19 #[serde(alias = "bfgs", alias = "BFGS")]
21 #[default]
22 Bfgs,
23 #[serde(alias = "lbfgs", alias = "LBFGS")]
25 Lbfgs,
26 #[serde(rename = "Delocalized", alias = "delocalized", alias = "DELOCALIZED")]
28 #[serde(alias = "Delocalised", alias = "delocalised", alias = "DELOCALISED")]
29 Delocalized,
31 #[serde(alias = "dampedmd", alias = "DAMPEDMD", alias = "DampedMD")]
33 DampedMd,
34 #[serde(alias = "tpsd", alias = "TPSD")]
36 Tpsd,
37}
38
39impl FromCellValue for GeomMethod {
40 fn from_cell_value(value: &CellValue<'_>) -> CResult<Self> {
41 match value_as_str(value)?.to_ascii_lowercase().as_str() {
42 "bfgs" => Ok(Self::Bfgs),
43 "lbfgs" => Ok(Self::Lbfgs),
44 "delocalized" | "delocalised" => Ok(Self::Delocalized),
45 "dampedmd" => Ok(Self::DampedMd),
46 "tpsd" => Ok(Self::Tpsd),
47 other => Err(Error::Message(format!("unknown GeomMethod: {other}"))),
48 }
49 }
50}
51
52impl FromKeyValue for GeomMethod {
53 const KEY_NAME: &'static str = "GEOM_METHOD";
54
55 fn from_cell_value_kv(value: &CellValue<'_>) -> CResult<Self> {
56 Self::from_cell_value(value)
57 }
58}
59
60
61impl ToCell for GeomMethod {
62 fn to_cell(&self) -> Cell<'_> {
63 Cell::KeyValue("GEOM_METHOD", self.to_cell_value())
64 }
65}
66
67impl ToCellValue for GeomMethod {
68 fn to_cell_value(&self) -> CellValue<'_> {
69 CellValue::String(
70 match self {
71 GeomMethod::Bfgs => "BFGS",
72 GeomMethod::Lbfgs => "LBFGS",
73 GeomMethod::Delocalized => "Delocalized",
74 GeomMethod::DampedMd => "DampedMD",
75 GeomMethod::Tpsd => "TPSD",
76 }
77 .to_string(),
78 )
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use castep_cell_fmt::CellValue;
86
87 #[test]
88 fn test_case_insensitive() {
89 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("bfgs")).unwrap(), GeomMethod::Bfgs);
90 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("BFGS")).unwrap(), GeomMethod::Bfgs);
91 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("lbfgs")).unwrap(), GeomMethod::Lbfgs);
92 }
93
94 #[test]
95 fn test_all_variants() {
96 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("delocalized")).unwrap(), GeomMethod::Delocalized);
97 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("delocalised")).unwrap(), GeomMethod::Delocalized);
98 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("dampedmd")).unwrap(), GeomMethod::DampedMd);
99 assert_eq!(GeomMethod::from_cell_value(&CellValue::Str("tpsd")).unwrap(), GeomMethod::Tpsd);
100 }
101
102 #[test]
103 fn test_invalid() {
104 assert!(GeomMethod::from_cell_value(&CellValue::Str("invalid")).is_err());
105 }
106
107 #[test]
108 fn test_key_name() {
109 assert_eq!(GeomMethod::KEY_NAME, "GEOM_METHOD");
110 }
111}
112