Skip to main content

castep_cell_io/param/geometry_optimization/
geom_modulus_est.rs

1use crate::units::PressureUnit;
2use castep_cell_fmt::{Cell, CellValue, ToCell, ToCellValue};
3use castep_cell_fmt::parse::{FromCellValue, FromKeyValue};
4use castep_cell_fmt::{CResult, Error};
5use castep_cell_fmt::query::value_as_f64;
6use serde::{Deserialize, Serialize};
7
8/// Provides an estimate of the bulk modulus of the system.
9///
10/// Keyword type: Real
11///
12/// Default: 500.0 GPa
13///
14/// Example:
15/// GEOM_MODULUS_EST : 125.4 GPa
16#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
17#[serde(rename = "GEOM_MODULUS_EST")]
18pub struct GeomModulusEst {
19    /// The modulus estimate value.
20    pub value: f64,
21    /// The optional unit of the pressure value.
22    pub unit: Option<PressureUnit>,
23}
24
25impl FromCellValue for GeomModulusEst {
26    fn from_cell_value(value: &CellValue<'_>) -> CResult<Self> {
27        match value {
28            CellValue::Array(arr) => {
29                let value = value_as_f64(&arr[0])?;
30                let unit = if arr.len() > 1 {
31                    Some(PressureUnit::from_cell_value(&arr[1])?)
32                } else {
33                    None
34                };
35                Ok(Self { value, unit })
36            }
37            _ => {
38                let value = value_as_f64(value)?;
39                Ok(Self { value, unit: None })
40            }
41        }
42    }
43}
44
45impl FromKeyValue for GeomModulusEst {
46    const KEY_NAME: &'static str = "GEOM_MODULUS_EST";
47
48    fn from_cell_value_kv(value: &CellValue<'_>) -> CResult<Self> {
49        Self::from_cell_value(value)
50    }
51}
52
53impl ToCell for GeomModulusEst {
54    fn to_cell(&self) -> Cell<'_> {
55        Cell::KeyValue("GEOM_MODULUS_EST", self.to_cell_value())
56    }
57}
58
59impl ToCellValue for GeomModulusEst {
60    fn to_cell_value(&self) -> CellValue<'_> {
61        CellValue::Array(
62            [
63                CellValue::Float(self.value),
64                self.unit
65                    .as_ref()
66                    .map(|u| u.to_cell_value())
67                    .unwrap_or(CellValue::Null),
68            ]
69            .to_vec(),
70        )
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_from_cell_value_float_only() {
80        let val = CellValue::Float(125.4);
81        let result = GeomModulusEst::from_cell_value(&val).unwrap();
82        assert_eq!(result.value, 125.4);
83        assert!(result.unit.is_none());
84    }
85
86    #[test]
87    fn test_key_name() {
88        assert_eq!(GeomModulusEst::KEY_NAME, "GEOM_MODULUS_EST");
89    }
90}
91