diff --git a/src/include/tfrfme.h b/src/include/tfrfme.h index daa6e359fe6f79946ce1bd999ed990987b9e78a3..9230e72ce903cb5498c6f84787033c9e5f6a472c 100644 --- a/src/include/tfrfme.h +++ b/src/include/tfrfme.h @@ -1,6 +1,6 @@ /*! \file tfrfme.h * - * \brief Representation of the trapping configuration objects. + * \brief Representation of the trapping calculation objects. */ #ifndef INCLUDE_TFRFME_H_ @@ -97,6 +97,146 @@ public: /*! \brief Class to represent the second group of trapping swap data. */ class Swap2 { +protected: + //! Number of vector coordinates + int nkv; + //! QUESTION: definition? + double *vkv; + //! QUESTION: definition? + double **vkzm; + //! QUESTION: definition? + double apfafa; + //! QUESTION: definition? + double pmf; + //! QUESTION: definition? + double spd; + //! QUESTION: definition? + double rir; + //! QUESTION: definition? + double ftcn; + //! QUESTION: definition? + double fshmx; + //! QUESTION: definition? + double vxyzmx; + //! Cartesian displacement. QUESTION: correct? + double delxyz; + //! QUESTION: definition? + double vknmx; + //! QUESTION: definition? + double delk; + //! QUESTION: definition? + double delks; + //! NLMMT = LM * (LM + 2) * 2 + int nlmmt; + //! Number of radial vector coordinates. QUESTION: correct? + int nrvc; + + /*! \brief Load a Swap2 instance from a HDF5 binary file. + * + * \param file_name: `string` Name of the file to be loaded. + * \return instance: `Swap2 *` Pointer to a new Swap2 instance. + */ + static Swap2 *from_hdf5(std::string file_name); + + /*! \brief Load a Swap2 instance from a legacy binary file. + * + * \param file_name: `string` Name of the file to be loaded. + * \return instance: `Swap2 *` Pointer to a new Swap2 instance. + */ + static Swap2 *from_legacy(std::string file_name); + + /*! \brief Save a Swap2 instance to a HDF5 binary file. + * + * \param file_name: `string` Name of the file to be written. + */ + void write_hdf5(std::string file_name); + + /*! \brief Save a Swap2 instance to a legacy binary file. + * + * \param file_name: `string` Name of the file to be written. + */ + void write_legacy(std::string file_name); + +public: + /*! \brief Swap2 instance constructor. + * + * \param _nkv: `int` Number of vector coordinates. QUESTION: correct? + */ + Swap2(int _nkv); + + /*! \brief Swap2 instance destroyer. + */ + ~Swap2(); + + /*! \brief Load a Swap2 instance from binary file. + * + * \param file_name: `string` Name of the file. + * \param mode: `string` Format of the file (can be either "HDF5" + * or "LGEACY". Default is "LEGACY"). + * \return instance: `Swap2 *` Pointer to a newly created Swap2 instance. + */ + static Swap2* from_binary(std::string file_name, std::string mode="LEGACY"); + + /*! \brief Get an element from the VKZM matrix. + * + * \param row: `int` Index of the desired element row. + * \param col: `int` Index of the desired element column. + * \return value: `double` The value of the requested element. + */ + double get_matrix_element(int row, int col) { return vkzm[row][col]; } + + /*! \brief Get a parameter by its name. + * + * \param param_name: `string` Name of the parameter. + * \return value: `double` The value of the requested parameter. + */ + double get_param(std::string param_name); + + /*! \brief Get an element from the VKV vector. + * + * \param index: `int` Index of the desired element. + * \return value: `double` The value of the requested element. + */ + double get_vector_element(int index) { return vkv[index]; } + + /*! \brief Set an element in the VKZM matrix. + * + * \param row: `int` Index of the desired element row. + * \param col: `int` Index of the desired element column. + * \param value: `double` The value of the element to be stored. + */ + void set_matrix_element(int row, int col, double value) { vkzm[row][col] = value; } + + /*! \brief Set a parameter by its name and value. + * + * \param param_name: `string` Name of the parameter. + * \param value: `double` The value of the parameter. + */ + void set_param(std::string param_name, double value); + + /*! \brief Get an element from the VKV vector. + * + * \param index: `int` Index of the desired element. + * \param value: `double` The value of element to be stored. + */ + void set_vector_element(int index, double value) { vkv[index] = value; } + + /*! \brief Write a Swap2 instance to binary file. + * + * \param file_name: `string` Name of the file. + * \param mode: `string` Format of the file (can be either "HDF5" + * or "LGEACY". Default is "LEGACY"). + */ + void write_binary(std::string file_name, std::string mode="LEGACY"); + + /*! \brief Test whether two instances of Swap2 are equal. + * + * \param other: `Swap1 &` Reference to the instance to be compared + * with. + * \return result: `bool` True, if the two instances are equal, + * false otherwise. + */ + bool operator ==(Swap2 &other); }; /*! \brief Class to represent the trapping configuration. diff --git a/src/libnptm/tfrfme.cpp b/src/libnptm/tfrfme.cpp index ac45463bb9ddfcca18ae16f71dcb4d84abf776a3..675d90c4ccacd5297b60cce85d8a14772222670c 100644 --- a/src/libnptm/tfrfme.cpp +++ b/src/libnptm/tfrfme.cpp @@ -1,6 +1,6 @@ /*! \file tfrfme.cpp * - * \brief Implementation of the trapping configuration objects. + * \brief Implementation of the trapping calculation objects. */ #include <complex> @@ -27,6 +27,7 @@ using namespace std; +// >>> START OF Swap1 CLASS IMPLEMENTATION <<< Swap1::Swap1(int lm) { nlmmt = 2 * lm * (lm + 2); wk = new complex<double>[nlmmt](); @@ -173,7 +174,357 @@ bool Swap1::operator ==(Swap1 &other) { } return true; } +// >>> END OF Swap1 CLASS IMPLEMENTATION <<< +// >>> START OF Swap2 CLASS IMPLEMENTATION <<< +Swap2::Swap2(int _nkv) { + nkv = _nkv; + vkv = new double[nkv](); + vkzm = new double*[nkv]; + for (int vi = 0; vi < nkv; vi++) vkzm[vi] = new double[nkv](); +} + +Swap2::~Swap2() { + delete[] vkv; + for (int vi = nkv - 1; vi > -1; vi--) delete[] vkzm[vi]; + delete[] vkzm; +} + +Swap2* Swap2::from_binary(string file_name, string mode) { + Swap2 *instance = NULL; + if (mode.compare("LEGACY") == 0) { + instance = from_legacy(file_name); + } else if (mode.compare("HDF5") == 0) { + instance = from_hdf5(file_name); + } else { + string message = "Unknown format mode: \"" + mode + "\""; + throw UnrecognizedFormatException(message); + } + return instance; +} + +Swap2* Swap2::from_hdf5(string file_name) { + Swap2 *instance = NULL; + unsigned int flags = H5F_ACC_RDONLY; + HDFFile *hdf_file = new HDFFile(file_name, flags); + herr_t status = hdf_file->get_status(); + string str_type; + int _nkv, _nlmmt, _nrvc; + double value; + if (status == 0) { + status = hdf_file->read("NKV", "INT32", &_nkv); + instance = new Swap2(_nkv); + str_type = "FLOAT64_(" + to_string(_nkv) + ")"; + status = hdf_file->read("VKV", str_type, instance->vkv); + str_type = "FLOAT64_(" + to_string(_nkv) + "," + to_string(_nkv) + ")"; + status = hdf_file->read("VKZM", str_type, instance->vkzm); + status = hdf_file->read("APFAFA", "FLOAT64", &value); + instance->set_param("apfafa", value); + status = hdf_file->read("PMF", "FLOAT64", &value); + instance->set_param("pmf", value); + status = hdf_file->read("SPD", "FLOAT64", &value); + instance->set_param("spd", value); + status = hdf_file->read("RIR", "FLOAT64", &value); + instance->set_param("rir", value); + status = hdf_file->read("FTCN", "FLOAT64", &value); + instance->set_param("ftcn", value); + status = hdf_file->read("FSHMX", "FLOAT64", &value); + instance->set_param("fshmx", value); + status = hdf_file->read("VXYZMX", "FLOAT64", &value); + instance->set_param("vxyzmx", value); + status = hdf_file->read("DELXYZ", "FLOAT64", &value); + instance->set_param("delxyz", value); + status = hdf_file->read("VKNMX", "FLOAT64", &value); + instance->set_param("vknmx", value); + status = hdf_file->read("DELK", "FLOAT64", &value); + instance->set_param("delk", value); + status = hdf_file->read("DELKS", "FLOAT64", &value); + instance->set_param("delks", value); + status = hdf_file->read("NLMMT", "INT32", &_nlmmt); + instance->set_param("nlmmt", 1.0 * _nlmmt); + status = hdf_file->read("NRVC", "INT32", &_nrvc); + instance->set_param("nrvc", 1.0 * _nrvc); + status = hdf_file->close(); + delete hdf_file; + } + return instance; +} + +Swap2* Swap2::from_legacy(string file_name) { + fstream input; + Swap2 *instance = NULL; + int _nkv, _nlmmt, _nrvc; + double value; + input.open(file_name.c_str(), ios::in | ios::binary); + if (input.is_open()) { + input.read(reinterpret_cast<char *>(&_nkv), sizeof(int)); + instance = new Swap2(_nkv); + for (int vj = 0; vj < _nkv; vj++) { + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_vector_element(vj, value); + } + for (int mi = 0; mi < _nkv; ,i++) { + for (int mj = 0; mj < _nkv; mj++) { + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_matrix_element(vi, vj, value); + } + } + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("apfafa", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("pmf", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("spd", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("rir", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("ftcn", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("fshmx", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("vxyzmx", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("delxyz", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("vknmx", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("delk", value); + input.read(reinterpret_cast<char *>(&value), sizeof(double)); + instance->set_param("delks", value); + input.read(reinterpret_cast<char *>(&_nlmmt), sizeof(int)); + instance->set_param("nlmmt", 1.0 * _nlmmt); + input.read(reinterpret_cast<char *>(&_nrvc), sizeof(int)); + instance->set_param("nrvc", 1.0 * _nrvc); + input.close(); + } else { + printf("ERROR: could not open input file \"%s\"\n", file_name.c_str()); + } + return instance; +} + +double Swap2::get_param(string param_name) { + double value; + if (param_name.compare("nkv") == 0) value = 1.0 * nkv; + else if (param_name.compare("apfafa") == 0) value = apfafa; + else if (param_name.compare("pmf") == 0) value = pmf; + else if (param_name.compare("spd") == 0) value = spd; + else if (param_name.compare("rir") == 0) value = rir; + else if (param_name.compare("ftcn") == 0) value = ftcn; + else if (param_name.compare("fshmx") == 0) value = fshmx; + else if (param_name.compare("vxyzmx") == 0) value = vxyzmx; + else if (param_name.compare("delxyz") == 0) value = delxyz; + else if (param_name.compare("vknmx") == 0) value = vknmx; + else if (param_name.compare("delk") == 0) value = delk; + else if (param_name.compare("delks") == 0) value = delks; + else if (param_name.compare("nlmmt") == 0) value = 1.0 * nlmmt; + else if (param_name.compare("nrvc") == 0) value = 1.0 * nrvc; + else { + string message = "Unrecognized parameter name \"" + param_name + "\""; + throw UnrecognizedParameterException(message); + } + return value; +} + +void Swap2::set_param(string param_name, double value) { + if (param_name.compare("nkv") == 0) nkv = (int)value; + else if (param_name.compare("apfafa") == 0) apfafa = value; + else if (param_name.compare("pmf") == 0) pmf = value; + else if (param_name.compare("spd") == 0) spd = value; + else if (param_name.compare("rir") == 0) rir = value; + else if (param_name.compare("ftcn") == 0) ftcn = value; + else if (param_name.compare("fshmx") == 0) fshmx = value; + else if (param_name.compare("vxyzmx") == 0) vxyzmx = value; + else if (param_name.compare("delxyz") == 0) delxyz = value; + else if (param_name.compare("vknmx") == 0) vknmx = value; + else if (param_name.compare("delk") == 0) delk = value; + else if (param_name.compare("delks") == 0) delks = value; + else if (param_name.compare("nlmmt") == 0) nlmmt = (int)value; + else if (param_name.compare("nrvc") == 0) nrvc = (int)value; + else { + string message = "Unrecognized parameter name \"" + param_name + "\""; + throw UnrecognizedParameterException(message); + } +} + +void Swap2::write_binary(string file_name, string mode) { + if (mode.compare("LEGACY") == 0) { + write_legacy(file_name); + } else if (mode.compare("HDF5") == 0) { + write_hdf5(file_name); + } else { + string message = "Unknown format mode: \"" + mode + "\""; + throw UnrecognizedFormatException(message); + } +} + +void Swap2::write_hdf5(string file_name) { + List<string> rec_name_list(1); + List<string> rec_type_list(1); + List<void *> rec_ptr_list(1); + herr_t status; + string str_type; + rec_name_list.set(0, "NKV"); + rec_type_list.set(0, "INT32_(1)"); + rec_ptr_list.set(0, &nkv); + rec_name_list.append("VKV"); + str_type = "FLOAT64_(" + to_string(nkv) + ")"; + rec_type_list.append(str_type); + rec_ptr_list.append(vkv); + rec_name_list.append("VKZM"); + str_type = "FLOAT64_(" + to_string(nkv) + "," + to_string(nkv) + ")"; + rec_type_list.append(str_type); + rec_ptr_list.append(vkzm); + rec_name_list.append("APFAFA"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&apfafa); + rec_name_list.append("PMF"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&pmf); + rec_name_list.append("SPD"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&spd); + rec_name_list.append("RIR"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&rir); + rec_name_list.append("FTCN"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&ftcn); + rec_name_list.append("FSHMX"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&fshmx); + rec_name_list.append("VXYZMX"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&vxyzmx); + rec_name_list.append("delxyz"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&delxyz); + rec_name_list.append("VKNMX"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&vknmx); + rec_name_list.append("DELK"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&delk); + rec_name_list.append("DELKS"); + rec_type_list.append("FLOAT64_(1)"); + rec_ptr_list.append(&delks); + rec_name_list.append("NLMMT"); + rec_type_list.append("INT32_(1)"); + rec_ptr_list.append(&nlmmt); + rec_name_list.append("NRVC"); + rec_type_list.append("INT32_(1)"); + rec_ptr_list.append(&nrvc); + + string *rec_names = rec_name_list.to_array(); + string *rec_types = rec_type_list.to_array(); + void **rec_pointers = rec_ptr_list.to_array(); + const int rec_num = rec_name_list.length(); + FileSchema schema(rec_num, rec_types, rec_names); + HDFFile *hdf_file = HDFFile::from_schema(schema, file_name, H5F_ACC_TRUNC); + for (int ri = 0; ri < rec_num; ri++) + status = hdf_file->write(rec_names[ri], rec_types[ri], rec_pointers[ri]); + status = hdf_file->close(); + + delete[] rec_names; + delete[] rec_types; + delete[] rec_pointers; + delete hdf_file; +} + +void Swap2::write_legacy(string file_name) { + fstream output; + double value + output.open(file_name.c_str(), ios::out | ios::binary); + if (output.is_open()) { + output.write(reinterpret_cast<char *>(&nkv), sizeof(int)); + for (int j = 0; j < nkv; j++){ + value = vkv[j]; + output.write(reinterpret_cast<const char*>(&value), sizeof(double)); + } + for (int mi = 0; mi < nkv; mi++) { + for (int mj = 0; mj < nkv; mj++) { + value = vkzm[mi][mj]; + output.write(reinterpret_cast<const char*>(&value), sizeof(double)); + } + } + output.write(reinterpret_cast<const char*>(&apfafa), sizeof(double)); + output.write(reinterpret_cast<const char*>(&pmf), sizeof(double)); + output.write(reinterpret_cast<const char*>(&spd), sizeof(double)); + output.write(reinterpret_cast<const char*>(&rir), sizeof(double)); + output.write(reinterpret_cast<const char*>(&ftcn), sizeof(double)); + output.write(reinterpret_cast<const char*>(&fshmx), sizeof(double)); + output.write(reinterpret_cast<const char*>(&vxyzmx), sizeof(double)); + output.write(reinterpret_cast<const char*>(&delxyz), sizeof(double)); + output.write(reinterpret_cast<const char*>(&vknmx), sizeof(double)); + output.write(reinterpret_cast<const char*>(&delk), sizeof(double)); + output.write(reinterpret_cast<const char*>(&delks), sizeof(double)); + output.write(reinterpret_cast<const char*>(&nlmmt), sizeof(int)); + output.write(reinterpret_cast<const char*>(&nrvc), sizeof(int)); + output.close(); + } else { // Should never occur + printf("ERROR: could not open output file \"%s\"\n", file_name.c_str()); + } +} + +bool Swap2::operator ==(Swap2 &other) { + if (nlmmt != other.nlmmt) { + return false; + } + if (nrvc != other.nrvc) { + return false; + } + if (nkv != other.nkv) { + return false; + } + if (apfafa != other.apfafa) { + return false; + } + if (pmf != other.pmf) { + return false; + } + if (spd != other.spd) { + return false; + } + if (rir != other.rir) { + return false; + } + if (ftcn != other.ftcn) { + return false; + } + if (fshmx != other.fshmx) { + return false; + } + if (vxyzmx != other.vxyzmx) { + return false; + } + if (delxyz != other.delxyz) { + return false; + } + if (vknmx != other.vknmx) { + return false; + } + if (delk != other.delk) { + return false; + } + if (delks != other.delks) { + return false; + } + for (int vi = 0; vi < nkv; vi++) { + if (vkv[vi] != other.vkv[vi]) { + return false; + } + } + for (int mi = 0; mi < nkv; mi++) { + for (int mj = 0; mj < nkv; mj++) { + if (vkzm[mi][mj] != other.vkzm[mi][mj]) { + return false; + } + } + } + return true; +} +// >>> END OF Swap2 CLASS IMPLEMENTATION <<< + +// >>> START OF TFRFME CLASS IMPLEMENTATION <<< TFRFME::TFRFME(int _lmode, int _lm, int _nkv, int _nxv, int _nyv, int _nzv) { lmode = _lmode; lm = _lm; @@ -611,3 +962,4 @@ bool TFRFME::operator ==(TFRFME &other) { } // wi loop return true; } +// >>> END OF TFRFME CLASS IMPLEMENTATION <<<