diff --git a/include/tadah/mlip/dataset_readers/castep_geom_reader.h b/include/tadah/mlip/dataset_readers/castep_geom_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..f44dc7231d6e6abad416b5f22ea01ab3893d94c4 --- /dev/null +++ b/include/tadah/mlip/dataset_readers/castep_geom_reader.h @@ -0,0 +1,66 @@ +#ifndef CASTEP_GEOM_READER_H +#define CASTEP_GEOM_READER_H + +#include <tadah/mlip/structure.h> +#include <tadah/mlip/structure_db.h> +#include <tadah/mlip/dataset_readers/castep_md_reader.h> + +#include <iostream> +#include <fstream> +#include <sstream> +#include <vector> +#include <stdexcept> + +/** + * @class CastepGeomReader + * @brief A class for reading and parsing CASTEP .geom files. + * + * Implements data extraction and processing from geometry optimisation runs. + * Data are converted from atomic units to common units: + * eV for energy, Ångström for distance, eV/Å for force, and eV/ų + * for pressure. + * + * Example usage: + * @code + * StructureDB my_db; + * // Using the basic constructor + * CastepGeomReader reader1(my_db); + * reader1.read_data("test.geom"); + * reader1.parse_data(); + * reader1.print_summary(); + * + * // Using the constructor with filename + * CastepGeomReader reader2(my_db, "test.geom"); + * reader2.print_summary(); + * @endcode + */ +class CastepGeomReader : public CastepMDReader { +public: + /** + * @brief Constructs a CastepGeomReader with a StructureDB reference. + * @param db Reference to a StructureDB object for storing parsed data. + */ + CastepGeomReader(StructureDB& db); + + /** + * @brief Constructs a CastepGeomReader and reads the specified file. + * @param db Reference to a StructureDB object for storing parsed data. + * @param filename Name of the .geom file to read. + */ + CastepGeomReader(StructureDB& db, const std::string& filename); + +private: + + /** + * @brief Dummy ideal gas pressure. + * @return zero. + */ + double calc_P_ideal(Structure &, double ) override; + + std::string get_first_label(std::string &) override; + std::string get_label(std::string &) override; + +}; + +#endif // CASTEP_GEOM_READER_H + diff --git a/include/tadah/mlip/dataset_readers/castep_md_reader.h b/include/tadah/mlip/dataset_readers/castep_md_reader.h index 3730aa23e7ef846952039ccf16d7f984b780ffd2..147f54d366b75dd50fd8fc2ea24533a8bb06ef5e 100644 --- a/include/tadah/mlip/dataset_readers/castep_md_reader.h +++ b/include/tadah/mlip/dataset_readers/castep_md_reader.h @@ -17,8 +17,11 @@ * * Implements data extraction and processing for molecular dynamics * simulations by converting data from atomic units to common units: - * eV for energy, Ångström for distance, eV/Å for force, and eV/ų - * for pressure. + * eV for energy, Ångström for distance, eV/Å for force, eV/ų + * for pressure and ps for time. + * + * The virial stress tensor is extracted from full pressure tensor + * by removing kinetic contributions. * * Example usage: * @code @@ -53,19 +56,27 @@ public: * @brief Reads data from a specified .md file. * @param filename The name of the .md file to read data from. */ - void read_data(const std::string& filename) override; + virtual void read_data(const std::string& filename) override; /** * @brief Parses the data read from the .md file. */ - void parse_data() override; + virtual void parse_data() override; /** * @brief Prints a summary of the parsed .md data. */ - void print_summary() const override; + virtual void print_summary() const override; + + /** + * @brief Checks if a string ends with a given suffix. + * @param str The string to check. + * @param suffix The suffix to check for. + * @return True if str ends with suffix, otherwise false. + */ + bool ends_with(const std::string& str, const std::string& suffix); -private: +protected: std::string raw_data_; /**< Stores raw file data */ std::string filename_; /**< Filename of the .md file */ @@ -78,13 +89,6 @@ private: double k_b = 8.617333262145e-5 / e_conv; /**< Boltzmann constant in atomic units (Hartree/K) */ // Helper methods - /** - * @brief Checks if a string ends with a given suffix. - * @param str The string to check. - * @param suffix The suffix to check for. - * @return True if str ends with suffix, otherwise false. - */ - bool ends_with(const std::string& str, const std::string& suffix); /** * @brief Calculates the ideal gas pressure. @@ -92,7 +96,7 @@ private: * @param T Temperature in atomic units. * @return Calculated ideal gas pressure. */ - double calc_P_ideal(Structure &s, double T); + virtual double calc_P_ideal(Structure &s, double T); /** * @brief Performs post-processing on the given structure. @@ -102,6 +106,10 @@ private: double T = 0; /**< Temperature in atomic units (Hartree/k_B) */ bool stress_tensor_bool = false; /**< Indicates presence of a stress tensor */ + + virtual std::string get_first_label(std::string &); + virtual std::string get_label(std::string &); + }; #endif // CASTEP_MD_READER_H diff --git a/src/castep_geom_reader.cpp b/src/castep_geom_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9cd0894ea5435131b2c0c196b74eada4f36461eb --- /dev/null +++ b/src/castep_geom_reader.cpp @@ -0,0 +1,20 @@ +#include <tadah/core/utils.h> +#include <tadah/mlip/dataset_readers/castep_geom_reader.h> +#include <tadah/mlip/dataset_readers/castep_md_reader.h> + +CastepGeomReader::CastepGeomReader(StructureDB& db) +: CastepMDReader(db) {} + +CastepGeomReader::CastepGeomReader(StructureDB& db, const std::string& filename) +: CastepMDReader(db, filename) {} + +double CastepGeomReader::calc_P_ideal(Structure &, double ) { + return 0; // dummy as geom stress tensor os virial +} + +std::string CastepGeomReader::get_first_label(std::string &step) { + return "Filename: "+filename_+ " | Units: (eV, Angstrom) | Step: " + step; +} +std::string CastepGeomReader::get_label(std::string &step) { + return "Step: " + step; +} diff --git a/src/castep_md_reader.cpp b/src/castep_md_reader.cpp index 38628edd790ccfb3b2184e329cfa6419ae25425d..43809c1383b441354b9e2d10f4f75b556518ca8b 100644 --- a/src/castep_md_reader.cpp +++ b/src/castep_md_reader.cpp @@ -57,6 +57,14 @@ void CastepMDReader::postproc_structure(Structure &s) { s = Structure(); } +std::string CastepMDReader::get_first_label(std::string &time) { + return "Filename: "+filename_+ " | Units: (eV, Angstrom) | Time: " + + std::to_string(std::stod(time)*t_conv) + " ps"; +} +std::string CastepMDReader::get_label(std::string &time) { + return "Time: " + std::to_string(std::stod(time)*t_conv) + " ps"; +} + void CastepMDReader::parse_data() { std::istringstream stream(raw_data_); std::string line; @@ -72,8 +80,7 @@ void CastepMDReader::parse_data() { while (std::getline(stream, line)) { std::istringstream iss(line); if (ends_with(line,"<-- E")) { - s.label = "Filename: "+filename_+ " | Units: (eV, Angstrom) | Time: " - + std::to_string(std::stod(time)*t_conv) + " ps"; + s.label = get_first_label(time); iss >> s.energy; s.energy *= e_conv; break; @@ -136,7 +143,7 @@ void CastepMDReader::parse_data() { std::string time; std::istringstream iss(line); iss >> time; - s.label = "Time: " + std::to_string(std::stod(time)*t_conv) + " ps"; + s.label = get_label(time); } cell_idx=0;