21 #ifndef _libint2_src_lib_libint_atom_h_ 22 #define _libint2_src_lib_libint_atom_h_ 24 #include <libint2/util/cxxstd.h> 25 #if LIBINT2_CPLUSPLUS_STD < 2011 26 # error "libint2/atom.h requires C++11 support" 36 #include <libint2/chemistry/elements.h> 44 inline bool operator==(
const Atom& atom1,
const Atom& atom2) {
45 return atom1.atomic_number == atom2.atomic_number && atom1.x == atom2.x &&
46 atom1.y == atom2.y && atom1.z == atom2.z;
52 static constexpr
double bohr_to_angstrom = 0.52917721067;
53 static constexpr
double angstrom_to_bohr = 1 / bohr_to_angstrom;
57 static constexpr
double bohr_to_angstrom = 0.52917721092;
58 static constexpr
double angstrom_to_bohr = 1 / bohr_to_angstrom;
66 bool strcaseequal(
const std::string &a,
const std::string &b) {
67 return a.size() == b.size() &&
68 std::equal(a.begin(), a.end(), b.begin(), [](
char a,
char b) {
69 return ::tolower(a) == ::tolower(b);
76 inline std::tuple<std::vector<libint2::Atom>,
78 __libint2_read_dotxyz(std::istream &is,
const double bohr_to_angstrom,
79 const bool pbc =
false) {
81 const std::string caller = std::string(
"libint2::read_dotxyz") + (pbc ?
"_pbc" :
"");
88 std::string rest_of_line;
89 std::getline(is, rest_of_line);
93 std::getline(is, comment);
96 const auto nlines_expected = natom + (pbc ? 3 : 0);
97 std::vector<Atom> atoms(natom, Atom{0, 0.0, 0.0, 0.0});
99 bool found_abc[3] = {
false,
false,
false};
100 for (
size_t line = 0, atom_index = 0; line < nlines_expected; ++line) {
102 throw std::logic_error(caller +
": expected " +
103 std::to_string(nlines_expected) +
104 " sets of coordinates but only " +
105 std::to_string(line) +
" received");
109 std::getline(is, linestr);
110 std::istringstream iss(linestr);
112 std::string element_symbol;
114 iss >> element_symbol >> x >> y >> z;
117 const auto angstrom_to_bohr = 1 / bohr_to_angstrom;
119 auto assign_atom = [angstrom_to_bohr](Atom &atom,
int Z,
double x,
double y,
121 atom.atomic_number = Z;
122 atom.x = x * angstrom_to_bohr;
123 atom.y = y * angstrom_to_bohr;
124 atom.z = z * angstrom_to_bohr;
127 double y,
double z) {
128 xyz[0] = x * angstrom_to_bohr;
129 xyz[1] = y * angstrom_to_bohr;
130 xyz[2] = z * angstrom_to_bohr;
136 if (strcaseequal(
"AA", element_symbol))
138 if (strcaseequal(
"BB", element_symbol))
140 if (strcaseequal(
"CC", element_symbol))
143 if (found_abc[axis] ==
true)
144 throw std::logic_error(
145 caller +
": unit cell parameter along Cartesian axis " +
146 std::to_string(axis) +
" appears more than once");
147 assign_xyz(unit_cell[axis], x, y, z);
148 found_abc[axis] =
true;
155 for (
const auto &e : libint2::chemistry::get_element_info()) {
156 if (strcaseequal(e.symbol, element_symbol)) {
162 std::ostringstream oss;
163 oss << caller <<
": element symbol \"" << element_symbol
164 <<
"\" is not recognized" << std::endl;
165 throw std::logic_error(oss.str().c_str());
168 if (pbc && atom_index == atoms.size()) {
169 throw std::logic_error(caller +
": too many atoms");
171 assign_atom(atoms[atom_index++], Z, x, y, z);
177 for(
auto xyz=0; xyz!=3; ++xyz)
178 if (found_abc[xyz] ==
false) {
179 throw std::logic_error(caller +
180 ": unit cell parameter along Cartesian axis " +
181 std::to_string(xyz) +
" not given");
185 return std::make_tuple(atoms, unit_cell);
207 const double bohr_to_angstrom = constants::codata_2010::bohr_to_angstrom) {
208 std::vector<Atom> atoms;
209 std::tie(atoms, std::ignore) =
210 __libint2_read_dotxyz(is, bohr_to_angstrom,
false);
231 const double bohr_to_angstrom = constants::codata_2010::bohr_to_angstrom)
232 -> decltype(__libint2_read_dotxyz(is, bohr_to_angstrom,
true)) {
233 return __libint2_read_dotxyz(is, bohr_to_angstrom,
true);
238 const std::vector<libint2::Atom> &atoms) {
239 std::vector<std::pair<double, std::array<double, 3>>> q(atoms.size());
240 for (
const auto &atom : atoms) {
241 q.emplace_back(static_cast<double>(atom.atomic_number),
std::vector< std::pair< double, std::array< double, 3 > > > make_point_charges(const std::vector< libint2::Atom > &atoms)
converts a vector of Atoms to a vector of point charges
Definition: atom.h:237
the 2010 CODATA reference set, available at DOI 10.1103/RevModPhys.84.1527
Definition: atom.h:56
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
the 2014 CODATA reference set, available at DOI 10.1103/RevModPhys.88.035009
Definition: atom.h:51
auto read_dotxyz_pbc(std::istream &is, const double bohr_to_angstrom=constants::codata_2010::bohr_to_angstrom) -> decltype(__libint2_read_dotxyz(is, bohr_to_angstrom, true))
reads the list of atoms from a file in the PBC-extended XYZ format
Definition: atom.h:229
std::vector< Atom > read_dotxyz(std::istream &is, const double bohr_to_angstrom=constants::codata_2010::bohr_to_angstrom)
reads the list of atoms from a file in the standard XYZ format supported by most chemistry software (...
Definition: atom.h:205
Array idential to C++0X arrays.
Definition: stdarray_bits.h:14