CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
init.cc
Go to the documentation of this file.
1 #include <cstring>
2 
9 
10 namespace CASM {
11 
12  namespace Completer {
14 
17 
18  m_desc.add_options()
19  ("force,f", "Force using a non-reduced, non-primitive, or left-handed PRIM");
20  return;
21  }
22  }
23 
24  // ///////////////////////////////////////
25  // 'init' function for casm
26  // (add an 'if-else' statement in casm.cpp to call this)
27 
28  int init_command(const CommandArgs &args) {
29 
30  std::string name;
31  po::variables_map vm;
32 
34  Completer::InitOption init_opt;
35 
36  try {
37  po::store(po::parse_command_line(args.argc, args.argv, init_opt.desc()), vm); // can throw
38 
41  if(vm.count("help")) {
42  args.log << "\n";
43  args.log << init_opt.desc() << std::endl;
44 
45  return 0;
46  }
47 
48  if(vm.count("desc")) {
49  args.log << "\n";
50  args.log << init_opt.desc() << std::endl;
51 
52  args.log << "DESCRIPTION \n" <<
53  " Initialize a new CASM project in the current directory.\n" <<
54  " - Expects a prim.json file in the current directory \n" <<
55  " - If not found, looks for a PRIM file in the current \n" <<
56  " directory and creates prim.json. \n\n";
57 
58  return 0;
59  }
60 
61  po::notify(vm); // throws on error, so do after help in case
62  // there are any problems
63  }
64  catch(po::error &e) {
65  args.err_log << "ERROR: " << e.what() << std::endl << std::endl;
66  args.err_log << init_opt.desc() << std::endl;
67  return ERR_INVALID_ARG;
68  }
69  catch(std::exception &e) {
70  args.err_log << "Unhandled Exception reached the top of main: "
71  << e.what() << ", application will now exit" << std::endl;
72  return ERR_UNKNOWN;
73 
74  }
75 
76  if(fs::current_path() == find_casmroot(fs::current_path())) {
77  args.log << "Already in a casm project." << std::endl;
78  return ERR_OTHER_PROJ;
79  }
80 
81  args.log << "\n***************************\n" << std::endl;
82 
83  fs::path root = fs::current_path();
84 
85  DirectoryStructure dir(root);
86  Structure prim;
87 
88 
89  // if prim.json does not exist, try to read PRIM and create prim.json
90  if(!fs::is_regular_file(dir.prim())) {
91 
92  if(!fs::is_regular_file(dir.PRIM())) {
93  args.log << "Error in 'casm init': Neither 'prim.json' nor 'PRIM' found.\n\n";
94 
95  args.log << "Run 'casm format --prim' for the format of the 'prim.json' file.\n\n";
96 
97  args.log << "For step by step help use: 'casm status -n'\n\n";
98 
100  }
101 
102  try {
103  fs::ifstream poscar_prim;
104  poscar_prim.open(dir.PRIM());
105  prim.read(poscar_prim);
106  poscar_prim.close();
107  }
108  catch(std::runtime_error &e) {
109 
110  args.err_log << "ERROR: No prim.json exists. PRIM exists, but it could not be read.\n";
111  args.err_log << e.what() << std::endl;
112  return ERR_INVALID_INPUT_FILE;
113  }
114 
115 
116  std::string poscar_prim_title = prim.title;
117  args.log << "Converting 'PRIM' to 'prim.json'.\n\n" << std::endl;
118 
119  args.log << "Please enter a short title for this project.\n";
120  args.log << " Use something suitable as a prefix for files specific to this project, such as 'ZrO' or 'TiAl'.\n\n";
121 
122  args.log << "Title: ";
123  std::cin >> prim.title;
124  args.log << "\n\n";
125 
126  jsonParser json;
127  write_prim(prim, json, FRAC);
128  json["description"] = poscar_prim_title;
129  fs::ofstream primfile(dir.prim());
130  json.print(primfile);
131  primfile.close();
132 
133  }
134 
135  jsonParser prim_json;
136 
137  try {
138 
139  prim_json = jsonParser(dir.prim());
140 
141  prim = Structure(read_prim(prim_json));
142  }
143  catch(std::runtime_error &e) {
144  args.err_log << e.what() << std::endl;
145 
146  return ERR_INVALID_INPUT_FILE;
147  }
148 
150  BasicStructure<Site> true_prim;
151  true_prim.title = prim.title;
152  if(!prim.is_primitive(true_prim)) {
153  if(!vm.count("force")) {
154  args.err_log << "ERROR: The structure in the prim.json file is not primitive. Writing the most \n"
155  << " primitive structure to file 'prim.true.json'.\n\n";
156 
157  Structure tmp(true_prim);
158  Lattice lat_niggli = canonical_equivalent_lattice(true_prim.lattice(), tmp.point_group(), TOL);
159  tmp.set_lattice(lat_niggli, CART);
160 
161  fs::ofstream primfile(root / "prim.true.json");
162  jsonParser json;
163  write_prim(tmp, json, FRAC);
164  json["description"] = prim_json["description"];
165  json.print(primfile);
166  primfile.close();
167 
168  args.err_log << "If you want to use the current prim.json anyway, re-run with the --force option. Some\n"
169  << "CASM features cannot be used with a non-primitive starting structure.\n";
170  return ERR_INVALID_INPUT_FILE;
171  }
172  else {
173  args.err_log << "WARNING: The structure in the prim.json file is not primitive. Continuing anyway \n"
174  << " because the --force option is on.\n\n";
175  }
176  }
177 
179  Lattice niggli_lat = canonical_equivalent_lattice(prim.lattice(), prim.point_group(), TOL);
180 
181  bool is_standard_niggli = almost_equal(niggli_lat.lat_column_mat(), prim.lattice().lat_column_mat());
182 
183  if(!is_standard_niggli) {
184  if(!vm.count("force")) {
185  if(!is_standard_niggli) {
186  args.err_log << "ERROR: The structure in the prim.json file is not the niggli cell in the CASM standard\n"
187  << " orientation. Writing the suggested structure to 'prim.niggli.json'.\n\n"
188  << " If you want to use the current prim.json anyway, re-run with the --force option.\n";
189  }
190 
191  Structure tmp(true_prim);
192  Lattice lat_niggli = canonical_equivalent_lattice(true_prim.lattice(), tmp.point_group(), TOL);
193  tmp.set_lattice(lat_niggli, CART);
194 
195  fs::ofstream primfile(root / "prim.niggli.json");
196  jsonParser json;
197  write_prim(tmp, json, FRAC);
198  json["description"] = prim_json["description"];
199  json.print(primfile);
200  primfile.close();
201 
202  return ERR_INVALID_INPUT_FILE;
203  }
204  else {
205  args.err_log << "WARNING: The structure in the prim.json file is not the standard orientation Niggli\n"
206  << " cell. Continuing anyway because the --force option is on.\n\n";
207  //return 1;
208  }
209 
210  }
211 
212  //Check if the lattice is right handed, and if not print PRIM.right_handed.json
213  if(!prim.lattice().is_right_handed()) {
214  if(!vm.count("force")) {
215  args.err_log << "ERROR: The structure in prim.json is not right-handed. Some electronic-"
216  << "structure codes will not accept this input. If you would like to "
217  << "keep this PRIM, re-run with the --force option. Writing the "
218  << "right-handed structure to PRIM.right_handed.json" << std::endl;
219 
220  prim.set_lattice(Lattice(prim.lattice()).make_right_handed(), CART);
221  prim.within();
222 
223  fs::ofstream primfile(root / "prim.right_handed.json");
224  jsonParser json;
225  write_prim(prim, json, FRAC);
226  json["description"] = prim_json["description"];
227  json.print(primfile);
228  primfile.close();
229  return ERR_INVALID_INPUT_FILE;
230  }
231  else {
232  args.err_log << "WARNING: The structure in the prim.json file is not right-handed. Continuing anyway \n"
233  << " because the --force option is on.\n\n";
234  }
235  }
236 
237  try {
238  args.log << "Initializing CASM project '" << prim.title << "'" << std::endl;
239  ProjectBuilder builder(root, prim.title, "formation_energy");
240  builder.build();
241  }
242  catch(std::runtime_error &e) {
243  args.err_log << "ERROR: Could not build CASM project.\n";
244  args.err_log << e.what() << std::endl;
245  return ERR_INVALID_INPUT_FILE;
246  }
247 
248  args.log << " DONE" << std::endl;
249  args.log << std::endl;
250 
251  return 0;
252  };
253 
254 }
255 
Data structure holding basic CASM command info.
#define ERR_UNKNOWN
#define ERR_INVALID_ARG
Specification of CASM project directory structure.
const SymGroup & point_group() const
Definition: Structure.cc:101
void initialize() override
Fill in the options descriptions accordingly.
Definition: init.cc:15
Structure specifies the lattice and atomic basis of a crystal.
Definition: Structure.hh:29
bool is_primitive(double prim_tol=TOL) const
void add_help_suboption()
Add a plain –help suboption.
Definition: Handlers.cc:276
void write_prim(const BasicStructure< Site > &prim, fs::path filename, COORD_TYPE mode)
Write prim.json to file.
Definition: AppIO.cc:107
Main CASM namespace.
Definition: complete.cpp:8
const Lattice & lattice() const
int init_command(const CommandArgs &args)
Definition: init.cc:28
const double TOL
fs::path prim() const
Return prim.json path.
const Eigen::Matrix3d & lat_column_mat() const
3x3 matrix with lattice vectors as its columne
Definition: Lattice.hh:104
fs::path find_casmroot(const fs::path &cwd)
BasicStructure< Site > read_prim(fs::path filename)
Definition: AppIO.cc:11
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
Definition: jsonParser.cc:185
const po::options_description & desc()
Get the program options, filled with the initialized values.
Definition: Handlers.cc:160
Sets up directories and files for a new CASM project.
Lattice canonical_equivalent_lattice(const Lattice &in_lat, const SymGroup &point_grp, double compare_tol)
Find the niggli, most standard oriented version of the given orbit (defined by the given SymGroup) of...
Definition: Niggli.cc:276
fs::path PRIM() const
Return PRIM path.
po::options_description m_desc
Boost program options. All the derived classes have them, but will fill them up themselves.
Definition: Handlers.hh:126
void set_lattice(const Lattice &lattice, COORD_TYPE mode)
Definition: Structure.cc:664
std::string title
User-specified name of this Structure.
void build() const
Builds a new CASM project.
virtual void read(std::istream &stream)
Print intpolated images in seperate directries.
DirectoryStructure & dir
Definition: settings.cc:102
bool is_right_handed() const
Check if the lattice is right handed.
Definition: Lattice.cc:1096
void within()
Translate all basis sites so that they are inside the unit cell.
#define ERR_OTHER_PROJ
#define ERR_MISSING_INPUT_FILE
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
#define ERR_INVALID_INPUT_FILE