CASM  1.1.0
A Clusters Approach to Statistical Mechanics
VaspIO.cc
Go to the documentation of this file.
2 
3 #include <iomanip>
4 
5 #include "casm/casm_io/Log.hh"
10 
11 namespace CASM {
12 namespace VaspIO {
13 
14 // --- Definitions -------------------------------------------------------- //
15 
34  : m_title(std::move(_title)),
35  m_species_mode(_mode),
36  m_struc(std::move(_struc)),
37  m_permute(sequence<Index>(0, m_struc.info(_mode).size() - 1)),
38  m_scale(1.0),
39  m_coord_mode(FRAC),
40  m_atom_names(true),
41  m_sel_dynamics(false),
42  m_append_atom_names(true),
43  m_ignore{"VA", "Va", "va"} {
45  _struc.info(m_species_mode)
47 }
48 
52 }
53 
56 void PrintPOSCAR::print(std::ostream &sout) const {
57  Log log(sout);
58  this->print(log);
59 }
60 
61 // TODO: Why Log? This just drags in more unnecessary dependencies. Just use
62 // ostream? Shouldn't all these precision values be part of the printer and NOT
63 // the Log?
66 void PrintPOSCAR::print(Log &sout) const {
67  int tprec = sout.ostream().precision();
68  std::ios::fmtflags tflags = sout.ostream().flags();
69  int prec = 8;
70  sout.ostream().precision(prec);
71 
72  auto const &info = m_struc.info(m_species_mode);
73 
74  if (m_permute.size() != info.size()) {
75  throw std::runtime_error(
76  "Error in PrintPOSCAR::print: m_permute.size() != info.size()");
77  }
78 
79  // first filter out all atoms we are going to ignore, indices of the remaining
80  // atoms get put in 'atom'
81  std::vector<Index> atom;
82 
83  // Count size of each contiguous block of non-ignored species
84  std::vector<std::pair<std::string, Index> > atom_count;
85 
86  for (Index i : m_permute) {
87  // if Atom's name is not found in the ignore list, add it to 'atom'
88  if (ignore().count(info.names[i]) == 0) {
89  atom.push_back(i);
90  if (atom_count.empty() || info.names[i] != atom_count.back().first)
91  atom_count.emplace_back(info.names[i], 0);
92 
93  atom_count.back().second++;
94  }
95  }
96 
97  // Initialize coordinate transformation matrix
98  Eigen::Matrix3d c2f;
99  if (m_coord_mode == CART)
100  c2f.setIdentity();
101  else
102  c2f = m_struc.lat_column_mat.inverse();
103 
104  // Determine printing width and construct Eigen::IOFormat object
105  int width = 12;
106  width = print_matrix_width(sout, m_struc.lat_column_mat.transpose(), width);
107  for (Index i : atom) {
108  Eigen::Vector3d vec = c2f * info.cart_coord(i);
109  width = print_matrix_width(sout, vec.transpose(), width);
110  }
111  Eigen::IOFormat format(prec, width + 1);
112 
113  // Begin printing:
114  // print title, scale, and lattice
115  sout << sout.indent_str() << m_title << "\n";
116  sout << sout.indent_str() << std::fixed << std::setprecision(prec) << m_scale
117  << "\n";
118 
119  sout.ostream().flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
120 
121  for (Index i = 0; i < 3; ++i)
122  sout << sout.indent_str()
123  << m_struc.lat_column_mat.col(i).transpose().format(format) << '\n';
124 
125  // if after filtering out ignored atoms none are left, return
126  if (atom.size() == 0) {
127  return;
128  }
129 
130  // optionally print atom names line
131 
132  if (m_atom_names) {
133  sout << sout.indent_str();
134  for (auto const &p : atom_count) {
135  sout << p.first << " ";
136  }
137  sout << "\n";
138  }
139 
140  sout << sout.indent_str();
141  for (auto const &p : atom_count) {
142  sout << p.second << " ";
143  }
144  sout << "\n";
145 
146  // print 'Selective Dynamics' if using selective dynamics
147  if (m_sel_dynamics) {
148  sout << sout.indent_str() << "Selective Dynamics\n";
149  }
150 
151  // print coord mode
152  sout << sout.indent_str() << xtal::COORD_MODE::NAME(m_coord_mode) << "\n";
153 
154  // print all coordinates, and seletive dynamics settings, and atom names if
155  // applicable
156  for (Index i : atom) {
157  sout << sout.indent_str()
158  << (c2f * info.cart_coord(i)).transpose().format(format);
159 
160  if (m_sel_dynamics) {
161  Eigen::Vector3i sd =
162  iround(info.properties.at(AnisoValTraits::selective_dynamics().name())
163  .col(i));
164  sout << " ";
165  for (Index j = 0; j < 3; ++j) sout << (sd[j] ? "T " : "F ");
166  }
167 
168  if (m_append_atom_names) {
169  sout << " " << info.names[i];
170  }
171  sout << "\n";
172  }
173  sout << "\n";
174 
175  sout.ostream().precision(tprec);
176  sout.ostream().flags(tflags);
177 }
178 
179 } // namespace VaspIO
180 } // namespace CASM
Index count
std::string const & name() const
Const access of name.
static AnisoValTraits selective_dynamics()
Named constructor for selective_dynamics AnisoValTraits.
Definition: Log.hh:48
std::string indent_str() const
Definition: Log.hh:273
std::ostream & ostream()
Definition: Log.hh:262
SpeciesMode m_species_mode
Definition: VaspIO.hh:115
xtal::SimpleStructure m_struc
Definition: VaspIO.hh:117
std::set< std::string > & ignore()
Access set of atom names which should not be printed, such as for vacancies.
Definition: VaspIO.hh:98
void sort()
Default sort is by atom name.
Definition: VaspIO.cc:50
COORD_TYPE m_coord_mode
Definition: VaspIO.hh:121
PrintPOSCAR(xtal::SimpleStructure _struc, std::string _title="", SpeciesMode _mode=SpeciesMode::ATOM)
Construct PrintPOSCAR object.
Definition: VaspIO.cc:32
void print(std::ostream &sout) const
Print POSCAR to stream.
Definition: VaspIO.cc:56
std::vector< Index > m_permute
Definition: VaspIO.hh:118
static std::string NAME()
get a string with the name of the active mode
Representation of a crystal of molecular and/or atomic occupants, and any additional properties....
Info & info(SpeciesMode _mode)
Info of specified context (atomic/molecular)
Eigen::CwiseUnaryOp< decltype(Local::iround_l< typename Derived::Scalar >), const Derived > iround(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd to Eigen::MatrixXi.
SpeciesMode
enum to refer to a particular representation of the occupants (atomic or molecular)
Main CASM namespace.
Definition: APICommand.hh:8
Log & log()
Definition: Log.hh:424
Eigen::Matrix3d Matrix3d
const COORD_TYPE FRAC
Definition: enum.hh:8
std::vector< T > sequence(T first, T last)
Definition: algorithm.hh:9
GenericDatumFormatter< std::string, DataObject > name()
const COORD_TYPE CART
Definition: enum.hh:9
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
Index print_matrix_width(std::ostream &s, const Derived &m, Index width)
Definition: stream_io.hh:24
std::map< std::string, Eigen::MatrixXd > properties
map of [property name, (m x names.size()) matrix] for all numerical site properties properties are as...
std::vector< Index > sort_by_name()
permutation that results in sites sorted alphabetically by species Guaranteed stable: will not change...