CASM  1.1.0
A Clusters Approach to Statistical Mechanics
SupercellInfoInterface.cc
Go to the documentation of this file.
2 
4 #include "casm/casm_io/Log.hh"
10 #include "casm/clex/PrimClex.hh"
11 #include "casm/clex/Supercell.hh"
16 
17 namespace CASM {
18 
19 namespace {
20 
21 std::shared_ptr<Structure const> open_shared_prim(fs::path root) {
22  ProjectSettings settings = open_project_settings(root);
23  return std::make_shared<Structure const>(
24  read_prim(settings.dir().prim(), settings.crystallography_tol()));
25 }
26 
28 struct SupercellInfoData {
29  SupercellInfoData(std::shared_ptr<Structure const> _shared_prim,
30  SupercellSymInfo const &_supercell_sym_info)
31  : shared_prim(_shared_prim), supercell_sym_info(_supercell_sym_info) {}
32 
33  std::shared_ptr<Structure const> shared_prim;
34 
35  SupercellSymInfo const &supercell_sym_info;
36 };
37 
38 // use for ValueType=bool, int, double, std::string, jsonParser
39 template <typename ValueType>
40 using SupercellInfoFormatter =
41  GenericDatumFormatter<ValueType, SupercellInfoData>;
42 
43 SupercellInfoFormatter<std::string> supercell_name() {
44  return SupercellInfoFormatter<std::string>(
45  "supercell_name",
46  "A name given to all equivalent super lattices of the prim lattice. See "
47  "the input option `supercell_name` for a more detailed description.",
48  [](SupercellInfoData const &data) -> std::string {
49  return make_supercell_name(data.shared_prim->point_group(),
50  data.supercell_sym_info.prim_lattice(),
51  data.supercell_sym_info.supercell_lattice());
52  });
53 }
54 
55 SupercellInfoFormatter<std::string> canonical_supercell_name() {
56  return SupercellInfoFormatter<std::string>(
57  "canonical_supercell_name",
58  "Name of the canonical equivalent supercell. See the input option "
59  "`supercell_name` for a more detailed description.",
60  [](SupercellInfoData const &data) -> std::string {
62  data.shared_prim->point_group(),
63  data.supercell_sym_info.prim_lattice(),
64  data.supercell_sym_info.supercell_lattice());
65  });
66 }
67 
68 } // namespace
69 
70 namespace adapter {
71 
72 template <typename ToType, typename FromType>
73 struct Adapter;
74 
75 template <>
76 struct Adapter<SupercellSymInfo, SupercellInfoData> {
77  SupercellSymInfo const &operator()(SupercellInfoData const &adaptable) const {
78  return adaptable.supercell_sym_info;
79  }
80 };
81 
82 } // namespace adapter
83 
84 namespace {
85 
86 DataFormatterDictionary<SupercellInfoData> make_supercell_info_dict() {
87  DataFormatterDictionary<SupercellInfoData> supercell_info_dict;
88 
89  // properties that require prim and supercell_sym_info
90  supercell_info_dict.insert(supercell_name(), canonical_supercell_name());
91 
92  // properties that only require supercell_sym_info
93  auto sym_info_dict = make_dictionary<SupercellSymInfo>();
94  for (auto it = sym_info_dict.begin(); it != sym_info_dict.end(); ++it) {
95  if (it->type() == DatumFormatterClass::Property) {
96  supercell_info_dict.insert(
97  make_datum_formatter_adapter<SupercellInfoData, SupercellSymInfo>(
98  *it));
99  }
100  }
101 
102  return supercell_info_dict;
103 }
104 
105 } // namespace
106 
107 std::string SupercellInfoInterface::desc() const {
108  std::string description =
109  "Get information about a supercell. The supercell is specified by \n"
110  "the prim and one of the following (else the primitive cell is \n"
111  "used): \n"
112  "- transformation_matrix_to_super \n"
113  "- supercell_lattice_vectors \n"
114  "- supercell_lattice_column_matrix \n"
115  "- supercell_name \n\n";
116 
117  std::string custom_options =
118  " prim: JSON object (optional, default=prim of current project) \n"
119  " See `casm format --prim` for details on the prim format. \n\n"
120 
121  " transformation_matrix_to_super: 3x3 array of integer (optional) \n"
122  " Transformation matrix T, defining the supercell lattice vectors\n"
123  " S, in terms of the prim lattice vectors, P: `S = P * T`, where \n"
124  " S and P are column vector matrices. \n\n"
125 
126  " supercell_lattice_vectors: 3x3 array of integer (optional) \n"
127  " Supercell lattice vectors, as a row vector matrix. \n\n"
128 
129  " supercell_lattice_column_matrix: 3x3 array of integer (optional) \n"
130  " Supercell lattice vectors, as a column vector matrix. \n\n"
131 
132  " supercell_name: string (optional) \n"
133  " A name given to all equivalent super lattices of the prim \n"
134  " lattice. From all super lattices which are equivalent via \n"
135  " crystal point group operations of prim, the canonical super \n"
136  " lattice is the equivalent lattice in niggli form which has the \n"
137  " most favorable orientation according to the CASM orientation \n"
138  " comparision criteria. These criteria compare the lattices as \n"
139  " column vector matrices and first favor symmetric matrices and \n"
140  " then favor non-negative lattice vectors which are aligned \n"
141  " nearest to the Cartesian axes. \n\n"
142 
143  " For the canonical super lattice, the name is constructed from \n"
144  " the hermite normal form of `transformation_matrix_to_super`. \n"
145  " For a non-canonical super lattice, the name is the constructed \n"
146  " from the name of the canonical super lattice and the index of \n"
147  " the prim factor group operation that (excluding the shift) \n"
148  " transforms the canonical super lattice into this super lattice.\n"
149  " \n"
150  " Example 1: Canonical supercell name \n"
151  " \n"
152  " \"SCEL8_4_2_1_1_3_2\" \n"
153  " \n"
154  " Example 2: Non-canonical supercell name representing a \n"
155  " re-orientation by application of prim factor group operation \n"
156  " with index 2 (indexing starting at 0). \n"
157  " \n"
158  " \"SCEL8_4_2_1_1_3_2.2\" \n\n"
159 
160  " properties: array of string (optional, default=[]) \n"
161  " An array of strings specifying which supercell properties to \n"
162  " output. The default value of an empty array will print all \n"
163  " properties. The allowed options are: \n\n";
164 
165  std::stringstream ss;
166  auto dict = make_supercell_info_dict();
167  dict.print_help(ss, DatumFormatterClass::Property);
168 
169  return name() + ": \n\n" + description + custom_options + ss.str();
170 }
171 
172 std::string SupercellInfoInterface::name() const { return "SupercellInfo"; }
173 
175 void SupercellInfoInterface::run(jsonParser const &json_options,
176  PrimClex const *primclex) const {
177  Log &log = CASM::log();
178 
179  ParentInputParser parser{json_options};
180  std::runtime_error error_if_invalid{"Error reading SupercellInfo input"};
181 
182  // read "prim"
183  std::shared_ptr<Structure const> shared_prim;
184  if (parser.self.contains("prim")) {
185  // prim provided in input
186  xtal::BasicStructure basic_structure;
187  parser.optional<xtal::BasicStructure>(basic_structure, "prim", TOL);
188  if (parser.valid()) {
189  shared_prim = std::make_shared<Structure const>(basic_structure);
190  }
191  } else if (primclex != nullptr) {
192  // if project provided via api
193  shared_prim = primclex->shared_prim();
194  } else {
195  // if project contains current working directory
196  fs::path root = find_casmroot(fs::current_path());
197  if (!root.empty()) {
198  try {
199  shared_prim = open_shared_prim(root);
200  } catch (std::exception &e) {
201  parser.insert_error("prim", e.what());
202  }
203  } else {
204  std::stringstream msg;
205  msg << "Error in SupercellInfo: No \"prim\" in input and no project "
206  "provided "
207  "or found.";
208  parser.insert_error("prim", msg.str());
209  }
210  }
211 
212  // read "transformation_matrix_to_super"
213  Eigen::Matrix3l T;
214  if (parser.self.contains("transformation_matrix_to_super")) {
215  parser.optional(T, "transformation_matrix_to_super");
216 
217  // or read "supercell_lattice_vectors"
218  } else if (parser.self.contains("supercell_lattice_vectors")) {
219  Eigen::Matrix3d L_transpose;
220  parser.optional(L_transpose, "supercell_lattice_vectors");
221  Lattice super_lattice{L_transpose.transpose()};
223  super_lattice, TOL);
224 
225  // or read "supercell_lattice_column_matrix"
226  } else if (parser.self.contains("supercell_lattice_column_matrix")) {
227  Eigen::Matrix3d L;
228  parser.optional(L, "supercell_lattice_column_matrix");
229  Lattice super_lattice{L};
231  super_lattice, TOL);
232 
233  // or read "supercell_name"
234  } else if (parser.self.contains("supercell_name")) {
235  std::string supercell_name;
236  parser.optional(supercell_name, "supercell_name");
238  shared_prim->factor_group(), shared_prim->lattice(), supercell_name);
239  T = superlattice.transformation_matrix_to_super();
240 
241  // else use Identity (prim cell)
242  } else {
244  }
245 
246  // read "properties"
247  std::vector<std::string> properties;
248  parser.optional(properties, "properties");
249  report_and_throw_if_invalid(parser, log, error_if_invalid);
250 
251  // construct SupercellSymInfo
252  Lattice super_lattice = make_superlattice(shared_prim->lattice(), T);
254  make_supercell_sym_info(*shared_prim, super_lattice);
255 
256  DataFormatterDictionary<SupercellInfoData> supercell_info_dict =
257  make_supercell_info_dict();
258 
259  // output all properties if empty
260  if (properties.empty()) {
261  auto it = supercell_info_dict.begin();
262  for (; it != supercell_info_dict.end(); ++it) {
263  if (it->type() == DatumFormatterClass::Property) {
264  properties.push_back(it->name());
265  }
266  }
267  }
268 
269  // format
270  auto formatter = supercell_info_dict.parse(properties);
271  jsonParser json;
272  SupercellInfoData data{shared_prim, supercell_sym_info};
273  formatter.to_json(data, json);
274  log << json << std::endl;
275 }
276 
277 } // namespace CASM
SupercellSymInfo const & supercell_sym_info
std::shared_ptr< Structure const > shared_prim
Parsing dictionary for constructing a DataFormatter<DataObject> object.
DataFormatter< DataObject > parse(const std::string &input) const
Use the vector of strings to build a DataFormatter<DataObject>
Definition: Log.hh:48
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
void run(jsonParser const &json_options, PrimClex const *primclex=nullptr) const override
Run prim info method.
std::string desc() const override
std::string name() const override
Enumeration method name (i.e. "prim", "supercell", "dof_space", etc.)
A class that collects all symmetry information for for performing symmetry transformations on the sit...
BasicStructure specifies the lattice and atomic basis of a crystal.
const Eigen::Matrix3l & transformation_matrix_to_super() const
Definition: Superlattice.hh:24
iterator begin()
Definition: unique_map.hh:213
Lattice make_superlattice(const Lattice &lat, const Eigen::Matrix< IntegralType, 3, 3, Options > &transf_mat)
Returns a super Lattice. Transformation matrix must be integer.
Definition: Lattice.hh:287
ProjectSettings open_project_settings(fs::path path_in_project)
xtal::Superlattice make_superlattice_from_supercell_name(Structure const &prim, std::string supercell_name)
Construct a Superlattice from the supercell name.
Definition: Supercell.cc:350
std::string make_canonical_supercell_name(Structure const &prim, xtal::Superlattice const &superlattice)
Make the canonical supercell name from a Superlattice.
Definition: Supercell.cc:343
std::string make_supercell_name(Structure const &prim, xtal::Superlattice const &superlattice)
Make the supercell name from a Superlattice.
Definition: Supercell.cc:336
ConfigIO::GenericConfigFormatter< jsonParser > properties()
Definition: ConfigIO.cc:785
IdentitySymRepBuilder Identity()
Eigen::Matrix3l make_transformation_matrix_to_super(const Lattice &tiling_unit, const Lattice &superlattice, double tol)
Definition: Lattice.cc:848
Main CASM namespace.
Definition: APICommand.hh:8
std::string description(const SymOp &op, const xtal::Lattice &lat, SymInfoOptions opt=SymInfoOptions())
Print SymInfo to string.
Log & log()
Definition: Log.hh:424
Eigen::Matrix3d Matrix3d
const double TOL
Definition: definitions.hh:30
xtal::BasicStructure read_prim(fs::path filename, double xtal_tol, ParsingDictionary< AnisoValTraits > const *_aniso_val_dict=nullptr)
fs::path find_casmroot(const fs::path &cwd)
void report_and_throw_if_invalid(KwargsParser const &parser, Log &log, ErrorType error)
SupercellSymInfo make_supercell_sym_info(Structure const &prim, Lattice const &super_lattice)
Definition: Structure.cc:419
Matrix< long int, 3, 3 > Matrix3l
Definition: eigen.hh:12
PrimClex * primclex
Definition: settings.cc:135
SupercellSymInfo const & operator()(SupercellInfoData const &adaptable) const