CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
composition.cc
Go to the documentation of this file.
1 #include<cstring>
2 
4 #include "casm/clex/PrimClex.hh"
7 #include "casm/app/AppIO.hh"
9 
10 namespace CASM {
11 
12  void display(std::ostream &sout, const CompositionAxes &opt) {
13 
14  if(opt.standard.size()) {
15  sout << "Standard composition axes:\n\n";
17  }
18 
19  if(opt.custom.size()) {
20  sout << "Custom composition axes:\n\n";
22  }
23 
24  sout << "\n";
25  if(opt.has_current_axes) {
26  sout << "Currently selected composition axes: " << opt.curr_key << "\n";
27 
28  sout << "\n";
29  sout << "Parametric composition:\n";
30  display_comp(sout, opt.curr, 2);
31 
32  sout << "\n";
33  sout << "Composition:\n";
34  display_comp_n(sout, opt.curr, 2);
35 
36  sout << "\n";
37  sout << "Parametric chemical potentials:\n";
38  display_param_chem_pot(sout, opt.curr, 2);
39  }
40 
41 
42  }
43 
44  namespace Completer {
45 
47 
50  m_desc.add_options()
51  ("display,d", "Display composition axes file")
52  ("calc,c", "Calculate the standard composition axes")
53  ("select,s", po::value<std::string>(&m_axis_choice_str), "Select composition axes");
54 
55  return;
56  }
57 
58  const std::string &CompositionOption::axis_choice_str() const {
59  return m_axis_choice_str;
60  }
61 
62 
63  }
64 
65  // ///////////////////////////////////////
66  // 'composition' function for casm
67  // (add an 'if-else' statement in casm.cpp to call this)
68 
69  int composition_command(const CommandArgs &args) {
70  po::variables_map vm;
71 
73  //("update,u", "Update composition and references based on current 'composition_axes.json' file");
74 
75  try {
76  po::store(po::parse_command_line(args.argc, args.argv, comp_opt.desc()), vm);
77 
78  bool call_help = false;
79 
80  //quit out if there are no arguments
81  if(!vm.count("help") && !vm.count("desc")) {
82  if(vm.count("calc") + vm.count("select") + vm.count("display") + vm.count("update") != 1) {
83  args.log << "Error in 'casm composition'. You need to use either --calc, --select, --display, or --update." << std::endl;
84  call_help = true;
85  }
86  }
87 
90  if(vm.count("help") || call_help) {
91  args.log << std::endl;
92  args.log << comp_opt.desc() << std::endl;
93 
94  return 0;
95  }
96 
97  if(vm.count("desc")) {
98  args.log << std::endl;
99  args.log << comp_opt.desc() << std::endl;
100 
101  args.log << "DESCRIPTION" << std::endl;
102  args.log << " Setup the composition axes.\n";
103  args.log << " - expects a PRIM file in the project root directory \n";
104  args.log << " - custom composition axes can be added to the 'composition_axes.json' file \n";
105  args.log << " and then compositions and references updated with 'casm composition --update'\n";
106  args.log << " (word of caution: compatibility with PRIM is currently not checked for.)\n";
107  args.log << " \n";
108  args.log << " Examples:\n";
109  args.log << " casm composition --calc \n";
110  args.log << " - Calculate standard composition axes, but does not select any. \n";
111  args.log << "\n";
112  args.log << " casm composition --display \n";
113  args.log << " - Display the possible composition axes\n";
114  args.log << " - Possible axes are stored in the 'composition_axes.json' file.\n";
115  args.log << "\n";
116  args.log << " casm composition --select 0 \n";
117  args.log << " - Select the composition axes by key name.\n";
118  args.log << " - Updates and writes compositions and reference properties.\n";
119  args.log << "\n";
120  /*args.log << " casm composition --update \n";
121  args.log << " - Updates and writes compositions and reference properties based.\n";
122  args.log << " on the contents of the 'composition_axes.json' file.\n";
123  args.log << "\n";*/
124  if(call_help)
125  return ERR_INVALID_ARG;
126 
127  return 0;
128  }
129 
130  po::notify(vm);
131 
132 
133  }
134  catch(po::error &e) {
135  args.err_log << "ERROR: " << e.what() << std::endl << std::endl;
136  args.err_log << comp_opt.desc() << std::endl;
137  return ERR_INVALID_ARG;
138  }
139  catch(std::exception &e) {
140  args.err_log << "Unhandled Exception reached the top of main: "
141  << e.what() << ", application will now exit" << std::endl;
142  return ERR_UNKNOWN;
143 
144  }
145 
146  const fs::path &root = args.root;
147  if(root.empty()) {
148  args.err_log.error("No casm project found");
149  args.err_log << std::endl;
150  return ERR_NO_PROJ;
151  }
152 
153  // If 'args.primclex', use that, else construct PrimClex in 'uniq_primclex'
154  // Then whichever exists, store reference in 'primclex'
155  std::unique_ptr<PrimClex> uniq_primclex;
156  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
157 
158  const DirectoryStructure &dir = primclex.dir();
159  fs::path comp_axes = dir.composition_axes();
160 
161  CompositionAxes opt;
162  if(fs::exists(comp_axes)) {
163  opt.read(comp_axes);
164  }
165 
166  if(vm.count("display")) {
167 
168  args.log << "\n***************************\n\n";
169 
170  display(args.log, opt);
171 
172  args.log << "\n\n";
173 
174  if(opt.err_code) {
175  args.log << opt.err_message << std::endl;
176  }
177  else if(opt.standard.size() && !opt.has_current_axes) {
178  args.log << "Please use 'casm composition --select' to choose your composition axes.\n\n";
179  }
180  else if(!opt.standard.size() && !opt.has_current_axes) {
181  args.log << "Please use 'casm composition --calc' to calculate standard composition axes.\n\n";
182  }
183 
184  return 0;
185  }
186  else {
187 
188  if(vm.count("calc")) {
189 
190  args.log << "\n***************************\n\n";
191 
192  args.log << "Using the PRIM to enumerate standard composition axes for this space.\n\n";
193 
194  if(opt.standard.size()) {
195  args.log << "Overwriting existing standard composition axes.\n\n";
196  }
197 
198  opt.standard.clear();
199  std::vector<CompositionConverter> v;
200  standard_composition_axes(primclex.get_prim(), std::back_inserter(v));
201  for(int i = 0; i < v.size(); i++) {
202  opt.standard[std::to_string(i)] = v[i];
203  }
204 
205  display(args.log, opt);
206 
207  args.log << "\n\n";
208 
209 
210  opt.write(comp_axes);
211 
212  args.log << "Wrote: " << comp_axes << "\n\n";
213 
214  if(!opt.has_current_axes) {
215  args.log << "Please use 'casm composition --select' to choose your composition axes.\n\n";
216  }
217  }
218 
219  if(vm.count("select")) {
220 
221  args.log << "\n***************************\n\n";
222 
223  if(opt.standard.size() + opt.custom.size() == 0) {
224 
225  args.log << "Error: No composition axes found.\n\n";
226 
227  args.log << "Please use 'casm composition --calc' to calculate standard composition axes,\n" <<
228  "or add custom composition axes to " << comp_axes << "\n\n";
229 
230  return ERR_MISSING_DEPENDS;
231 
232  }
233 
234  if(opt.standard.find(comp_opt.axis_choice_str()) != opt.standard.end() &&
235  opt.custom.find(comp_opt.axis_choice_str()) != opt.custom.end()) {
236 
237  args.log << "Error: The selected composition axes '" << comp_opt.axis_choice_str() << "' can be \n" <<
238  "found in both the standard and custom compostion axes. Please \n" <<
239  "edit the custom composition axes to remove this ambiguity. \n\n" <<
240 
241  "File: " << comp_axes << "\n\n";
242 
243  return ERR_INVALID_INPUT_FILE;
244 
245  }
246  else if(opt.standard.find(comp_opt.axis_choice_str()) == opt.standard.end() &&
247  opt.custom.find(comp_opt.axis_choice_str()) == opt.custom.end()) {
248 
249  args.log << "Error: The selected composition axes '" << comp_opt.axis_choice_str() << "' can not \n" <<
250  "be found in either the standard or custom compostion axes. Please\n" <<
251  "re-select composition axes. \n\n";
252 
253  return ERR_INVALID_INPUT_FILE;
254 
255  }
256 
257  opt.select(comp_opt.axis_choice_str());
258 
259  display(args.log, opt);
260 
261  args.log << "\n\n";
262 
263  opt.write(comp_axes);
264 
265  args.log << "Wrote: " << comp_axes << "\n\n";
266 
267  if(args.primclex) {
268  args.primclex->refresh(false, true, true, false);
269  };
270 
271  }
272 
273  return 0;
274  }
275  }
276 
277 }
Data structure holding basic CASM command info.
void display_comp_n(std::ostream &stream, const CompositionConverter &f, int indent=0)
Pretty-print comp_n in terms of comp.
CompositionConverter curr
Definition: AppIO.hh:95
void display_composition_axes(std::ostream &stream, const std::map< std::string, CompositionConverter > &map)
Pretty-print map of name/CompositionConverter pairs.
std::map< std::string, CompositionConverter > standard
Definition: AppIO.hh:91
#define ERR_UNKNOWN
fs::path composition_axes() const
Return composition axes file path.
const std::string & axis_choice_str() const
Definition: composition.cc:58
#define ERR_INVALID_ARG
Specification of CASM project directory structure.
const DirectoryStructure & dir() const
Definition: PrimClex.hh:112
void select(std::string key)
Set this->curr using key.
Definition: AppIO.cc:372
PrimClex * primclex
Definition: settings.cc:101
void add_help_suboption()
Add a plain –help suboption.
Definition: Handlers.cc:276
void refresh(bool read_settings=false, bool read_composition=false, bool read_chem_ref=false, bool read_configs=false, bool clear_clex=false)
Reload PrimClex data from settings.
Definition: PrimClex.cc:90
void display_param_chem_pot(std::ostream &stream, const CompositionConverter &f, int indent=0)
Pretty-print param_chem_pot in terms of chem_pot.
void initialize() override
Fill in the options descriptions accordingly.
Definition: composition.cc:48
Main CASM namespace.
Definition: complete.cpp:8
std::string to_string(ENUM val)
Return string representation of enum class.
Definition: EnumIO.hh:83
std::string curr_key
Definition: AppIO.hh:94
void display(std::ostream &sout, const CompositionAxes &opt)
Definition: composition.cc:12
const po::options_description & desc()
Get the program options, filled with the initialized values.
Definition: Handlers.cc:160
void read(fs::path _filename)
Read CompositionAxes from file.
Definition: AppIO.cc:293
po::options_description m_desc
Boost program options. All the derived classes have them, but will fill them up themselves.
Definition: Handlers.hh:126
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
OutputIterator standard_composition_axes(const Structure &prim, OutputIterator result)
Generate CompositionConverter specifying standard composition axes for a prim Structure.
DirectoryStructure & dir
Definition: settings.cc:102
PrimClex & make_primclex_if_not(const CommandArgs &args, std::unique_ptr< PrimClex > &uniq_primclex)
If !_primclex, construct new PrimClex stored in uniq_primclex, then return reference to existing or c...
void display_comp(std::ostream &stream, const CompositionConverter &f, int indent=0)
Pretty-print comp in terms of comp_n.
void error(const std::string &what)
Definition: Log.hh:86
void write(fs::path _filename)
Write CompositionAxes to file.
Definition: AppIO.cc:339
std::map< std::string, CompositionConverter > custom
Definition: AppIO.hh:92
std::string err_message
Definition: AppIO.hh:99
const Structure & get_prim() const
const Access to primitive Structure
Definition: PrimClex.cc:260
#define ERR_MISSING_DEPENDS
#define ERR_NO_PROJ
#define ERR_INVALID_INPUT_FILE
int composition_command(const CommandArgs &args)
Definition: composition.cc:69