castep_cell_io/parsing/
cell_parser.rs1use crate::{
2 cell_document::{CellDocument, CellEntries, CellEssentials},
3 keywords::{
4 DocumentSections, KPointKeywords, KeywordType, LatticeBlockType, PositionsKeywords,
5 SpeciesKeywords,
6 },
7 parsing::helpers::{
8 current_sections, get_block_data, get_field_data, parse_bs_kpoint_list,
9 parse_ionic_positions, parse_kpoint_list, parse_lattice_param, parse_species_mass_block,
10 parse_species_pot_block,
11 },
12 CellParseError, CellParser,
13};
14
15use super::helpers::{
16 parse_bs_kpoint_path, parse_kpoint_mp_grid_field, parse_kpoint_mp_spacing_field,
17 parse_species_lcao_block,
18};
19
20impl<'a, S: AsRef<str>> From<&'a S> for CellParser<'a> {
21 fn from(value: &'a S) -> Self {
22 Self {
23 input: value.as_ref(),
24 lattice_param: None,
25 ionic_positions: None,
26 other_entries: Vec::new(),
27 }
28 }
29}
30
31impl CellParser<'_> {
32 pub fn parse(&mut self) -> Result<CellDocument, CellParseError> {
33 while let Ok(section) = current_sections(&mut self.input) {
34 match section {
35 DocumentSections::CellLatticeVectors(lat_keyword) => {
36 self.parse_lattice_param_section(lat_keyword)?;
37 }
38 DocumentSections::IonicPositions(pos_keyword) => {
39 self.parse_ionic_pos_section(pos_keyword)?;
40 }
41 DocumentSections::KPoint(kpt_keyword) => {
42 let kpt_setting = self.parse_kpt_section(kpt_keyword)?;
43 self.other_entries.push(kpt_setting);
44 }
45 DocumentSections::Species(spec_keyword) => {
46 let entry = self.parse_species_section(spec_keyword)?;
47 self.other_entries.push(entry);
48 }
49 DocumentSections::Misc(ref misc_keyword) => match misc_keyword {
50 KeywordType::Block(_) => {
51 get_block_data(&mut self.input)
52 .map_err(|_| CellParseError::GetBlockDataFailure)?;
53 #[cfg(debug_assertions)]
54 dbg!(&self.input);
55 }
56 KeywordType::Field(field_kw) => {
57 let field_data = get_field_data(&mut self.input)
58 .map_err(|_| CellParseError::GetBlockDataFailure)?;
59 #[cfg(debug_assertions)]
60 {
61 dbg!((field_kw, field_data));
62 }
63 }
64 },
65 DocumentSections::End => {
66 break;
67 }
68 _ => {
69 #[cfg(debug_assertions)]
70 println!("{:?}", section)
71 }
72 }
73 }
74 if self.lattice_param.is_some() && self.ionic_positions.is_some() {
75 let model_description = CellEssentials::new(
76 self.lattice_param.unwrap(),
77 self.ionic_positions.as_ref().unwrap().to_owned(),
78 );
79 let mut cell_doc = CellDocument::new(model_description);
80 cell_doc.set_entries(Some(self.other_entries.clone()));
81 cell_doc
83 .model_description_mut()
84 .ionic_pos_block_mut()
85 .set_spin_polarised(true);
86 Ok(cell_doc)
87 } else {
88 Err(CellParseError::RequiredSectionMissing)
89 }
90 }
91 fn parse_lattice_param_section(
92 &mut self,
93 lat_keyword: LatticeBlockType,
94 ) -> Result<(), CellParseError> {
95 let param = parse_lattice_param(&mut self.input, lat_keyword)?;
96 self.lattice_param = Some(param);
97 Ok(())
98 }
99 fn parse_ionic_pos_section(
100 &mut self,
101 pos_keyword: PositionsKeywords,
102 ) -> Result<(), CellParseError> {
103 let positions = parse_ionic_positions(&mut self.input, pos_keyword)?;
104 self.ionic_positions = Some(positions);
105 Ok(())
106 }
107 fn parse_species_section(
108 &mut self,
109 species_keyword: SpeciesKeywords,
110 ) -> Result<CellEntries, CellParseError> {
111 match species_keyword {
112 SpeciesKeywords::SPECIES_LCAO_STATES => Ok(CellEntries::SpeciesLCAOStates(
113 parse_species_lcao_block(&mut self.input)?,
114 )),
115 SpeciesKeywords::SPECIES_MASS => Ok(CellEntries::SpeciesMass(
116 parse_species_mass_block(&mut self.input)?,
117 )),
118 SpeciesKeywords::SPECIES_POT => Ok(CellEntries::SpeciesPot(parse_species_pot_block(
119 &mut self.input,
120 )?)),
121 }
122 }
123 fn parse_kpt_section(
124 &mut self,
125 kpt_keyword: KPointKeywords,
126 ) -> Result<CellEntries, CellParseError> {
127 match kpt_keyword {
128 KPointKeywords::KPOINT_LIST => Ok(CellEntries::KpointSettings(parse_kpoint_list(
129 &mut self.input,
130 )?)),
131 KPointKeywords::KPOINT_MP_GRID => Ok(CellEntries::KpointSettings(
132 parse_kpoint_mp_grid_field(&mut self.input)?,
133 )),
134 KPointKeywords::KPOINT_MP_SPACING => Ok(CellEntries::KpointSettings(
135 parse_kpoint_mp_spacing_field(&mut self.input)?,
136 )),
137 KPointKeywords::KPOINT_MP_OFFSET => todo!(),
138 KPointKeywords::SPECTRAL_KPOINT_LIST => Ok(CellEntries::NCKpointSettings(
139 parse_bs_kpoint_list(&mut self.input)?,
140 )),
141 KPointKeywords::SPECTRAL_KPOINT_PATH => Ok(CellEntries::NCKpointSettings(
142 parse_bs_kpoint_path(&mut self.input)?,
143 )),
144 KPointKeywords::SPECTRAL_KPOINT_PATH_SPACING => todo!(),
145 }
146 }
147}