CASM  1.1.0
A Clusters Approach to Statistical Mechanics
composition.cc
Go to the documentation of this file.
2 
3 #include <boost/filesystem.hpp>
4 #include <cstring>
5 
9 #include "casm/casm_io/Log.hh"
11 #include "casm/clex/PrimClex.hh"
17 
18 namespace CASM {
19 
20 void display(std::ostream &sout, const CompositionAxes &comp_axes) {
21  if (comp_axes.all_axes.size()) {
22  sout << "Possible composition axes:\n\n";
23  display_composition_axes(sout, comp_axes.all_axes);
24  }
25  sout << "\n";
26 
27  if (comp_axes.has_current_axes()) {
28  sout << "Currently selected composition axes: " << comp_axes.curr_key
29  << "\n";
30 
31  sout << "\n";
32  sout << "Parametric composition:\n";
33  display_comp(sout, comp_axes.curr, 2);
34 
35  sout << "\n";
36  sout << "Composition:\n";
37  display_comp_n(sout, comp_axes.curr, 2);
38 
39  sout << "\n";
40  sout << "Parametric chemical potentials:\n";
41  display_param_chem_pot(sout, comp_axes.curr, 2);
42  }
43 }
44 
45 namespace Completer {
46 
48 
51  m_desc.add_options()("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),
54  "Select composition axes");
55 
56  return;
57 }
58 
59 const std::string &CompositionOption::axis_choice_str() const {
60  return m_axis_choice_str;
61 }
62 
63 } // namespace Completer
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
74  //'composition_axes.json' file");
75 
76  try {
77  po::store(po::parse_command_line(args.argc(), args.argv(), comp_opt.desc()),
78  vm);
79 
80  bool call_help = false;
81 
82  // quit out if there are no arguments
83  if (!vm.count("help") && !vm.count("desc")) {
84  if (vm.count("calc") + vm.count("select") + vm.count("display") +
85  vm.count("update") !=
86  1) {
87  log() << "Error in 'casm composition'. You need to use either --calc, "
88  "--select, --display, or --update."
89  << std::endl;
90  call_help = true;
91  }
92  }
93 
96  if (vm.count("help") || call_help) {
97  log() << std::endl;
98  log() << comp_opt.desc() << std::endl;
99 
100  return 0;
101  }
102 
103  if (vm.count("desc")) {
104  log() << std::endl;
105  log() << comp_opt.desc() << std::endl;
106 
107  log() << "DESCRIPTION" << std::endl;
108  log() << " Setup the composition axes.\n";
109  log() << " - expects a PRIM file in the project root directory \n";
110  log() << " - custom composition axes can be added to the "
111  "'composition_axes.json' file \n";
112  log() << " and then compositions and references updated with 'casm "
113  "composition --update'\n";
114  log() << " (word of caution: compatibility with PRIM is currently "
115  "not checked for.)\n";
116  log() << " \n";
117  log() << " Examples:\n";
118  log() << " casm composition --calc \n";
119  log() << " - Calculate standard composition axes, but does not "
120  "select any. \n";
121  log() << "\n";
122  log() << " casm composition --display \n";
123  log() << " - Display the possible composition axes\n";
124  log() << " - Possible axes are stored in the "
125  "'composition_axes.json' file.\n";
126  log() << "\n";
127  log() << " casm composition --select 0 \n";
128  log() << " - Select the composition axes by key name.\n";
129  log() << " - Updates and writes compositions and reference "
130  "properties.\n";
131  log() << "\n";
132  /*log() << " casm composition --update \n";
133  log() << " - Updates and writes compositions and reference properties
134  based.\n"; log() << " on the contents of the
135  'composition_axes.json' file.\n"; log() << "\n";*/
136  if (call_help) return ERR_INVALID_ARG;
137 
138  return 0;
139  }
140 
141  po::notify(vm);
142 
143  } catch (po::error &e) {
144  err_log() << "ERROR: " << e.what() << std::endl << std::endl;
145  err_log() << comp_opt.desc() << std::endl;
146  return ERR_INVALID_ARG;
147  } catch (std::exception &e) {
148  err_log() << "Unhandled Exception reached the top of main: " << e.what()
149  << ", application will now exit" << std::endl;
150  return ERR_UNKNOWN;
151  }
152 
153  const fs::path &root = args.root;
154  if (root.empty()) {
155  err_log().error("No casm project found");
156  err_log() << std::endl;
157  return ERR_NO_PROJ;
158  }
159 
160  // If 'args.primclex', use that, else construct PrimClex in 'uniq_primclex'
161  // Then whichever exists, store reference in 'primclex'
162  std::unique_ptr<PrimClex> uniq_primclex;
163  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
164 
165  const DirectoryStructure &dir = primclex.dir();
166  fs::path comp_axes_path = dir.composition_axes();
167 
168  CompositionAxes comp_axes;
169  if (fs::exists(comp_axes_path)) {
170  comp_axes = read_composition_axes(comp_axes_path);
171  }
172 
173  if (vm.count("display")) {
174  log() << "\n***************************\n\n";
175 
176  display(log(), comp_axes);
177 
178  log() << "\n\n";
179 
180  if (comp_axes.err_code) {
181  log() << comp_axes.err_message << std::endl;
182  } else if (comp_axes.all_axes.size() && !comp_axes.has_current_axes()) {
183  log() << "Please use 'casm composition --select' to choose your "
184  "composition axes.\n\n";
185  } else if (!comp_axes.all_axes.size()) {
186  log() << "Please use 'casm composition --calc' to calculate standard "
187  "composition axes.\n\n";
188  }
189 
190  return 0;
191  } else {
192  if (vm.count("calc")) {
193  log() << "\n***************************\n\n";
194 
195  log() << "Using the PRIM to enumerate standard composition axes for this "
196  "space.\n\n";
197 
198  if (comp_axes.enumerated.size()) {
199  log() << "Overwriting existing standard composition axes.\n\n";
200  }
201 
202  comp_axes.erase_enumerated();
203 
204  std::vector<CompositionConverter> v;
206  std::back_inserter(v));
207  comp_axes.insert_enumerated(v.begin(), v.end());
208 
209  display(log(), comp_axes);
210 
211  log() << "\n\n";
212 
213  write_composition_axes(comp_axes_path, comp_axes);
214 
215  log() << "Wrote: " << comp_axes_path << "\n\n";
216 
217  if (!comp_axes.has_current_axes()) {
218  log() << "Please use 'casm composition --select' to choose your "
219  "composition axes.\n\n";
220  }
221  }
222 
223  if (vm.count("select")) {
224  log() << "\n***************************\n\n";
225 
226  if (comp_axes.all_axes.empty()) {
227  log() << "Error: No composition axes found.\n\n";
228 
229  log() << "Please use 'casm composition --calc' to calculate standard "
230  "composition axes,\n"
231  << "or add custom composition axes to " << comp_axes_path
232  << "\n\n";
233 
234  return ERR_MISSING_DEPENDS;
235  }
236 
237  if (comp_axes.all_axes.count(comp_opt.axis_choice_str()) == 0) {
238  log() << "Error: The selected composition axes '"
239  << comp_opt.axis_choice_str() << "' can not \n"
240  << "be found in either the standard or custom compostion axes. "
241  "Please\n"
242  << "re-select composition axes. "
243  " \n\n";
244 
245  return ERR_INVALID_INPUT_FILE;
246  }
247 
248  comp_axes.select(comp_opt.axis_choice_str());
249 
250  display(log(), comp_axes);
251 
252  log() << "\n\n";
253 
254  write_composition_axes(comp_axes_path, comp_axes);
255 
256  log() << "Wrote: " << comp_axes_path << "\n\n";
257 
258  if (args.primclex) {
259  args.primclex->refresh(false, true, true, false);
260  };
261  }
262 
263  return 0;
264  }
265 }
266 
267 } // namespace CASM
#define ERR_NO_PROJ
Definition: errors.hh:13
#define ERR_MISSING_DEPENDS
Definition: errors.hh:26
#define ERR_UNKNOWN
Definition: errors.hh:10
#define ERR_INVALID_ARG
Definition: errors.hh:7
#define ERR_INVALID_INPUT_FILE
Definition: errors.hh:16
int argc() const
Definition: CLIParse.hh:20
char ** argv() const
Definition: CLIParse.hh:22
void initialize() override
Fill in the options descriptions accordingly.
Definition: composition.cc:49
const std::string & axis_choice_str() const
Definition: composition.cc:59
const po::options_description & desc()
Get the program options, filled with the initialized values.
Definition: Handlers.cc:321
void add_help_suboption()
Add a plain –help and –desc suboptions.
Definition: Handlers.cc:561
po::options_description m_desc
Definition: Handlers.hh:260
Specification of CASM project directory structure.
fs::path composition_axes() const
Return composition axes file path.
void error(const std::string &what)
Definition: Log.hh:129
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
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...
const DirectoryStructure & dir() const
Access DirectoryStructure object. Throw if not set.
Definition: PrimClex.cc:230
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:156
const PrimType & prim() const
const Access to primitive Structure
Definition: PrimClex.cc:262
std::vector< std::vector< std::string > > allowed_molecule_names(BasicStructure const &_struc)
Returns a vector with a list of allowed molecule names at each site.
Main CASM namespace.
Definition: APICommand.hh:8
void display_comp_n(std::ostream &stream, const CompositionConverter &f, int indent=0)
Pretty-print comp_n in terms of comp.
void write_composition_axes(fs::path _filename, CompositionAxes const &composition_axes)
Write CompositionAxes to file.
void display(std::ostream &sout, const CompositionAxes &comp_axes)
Definition: composition.cc:20
void display_param_chem_pot(std::ostream &stream, const CompositionConverter &f, int indent=0)
Pretty-print param_chem_pot in terms of chem_pot.
Log & log()
Definition: Log.hh:424
void display_composition_axes(std::ostream &stream, const std::map< std::string, CompositionConverter > &map)
Pretty-print map of name/CompositionConverter pairs.
CompositionAxes read_composition_axes(fs::path _filename)
void display_comp(std::ostream &stream, const CompositionConverter &f, int indent=0)
Pretty-print comp in terms of comp_n.
OutputIterator standard_composition_axes(ParamComposition::AllowedOccupants _allowed_occs, OutputIterator result)
Generate CompositionConverter specifying standard composition axes for a prim Structure.
Log & err_log()
Definition: Log.hh:426
int composition_command(const CommandArgs &args)
Definition: composition.cc:69
PrimClex * primclex
Definition: settings.cc:135
DirectoryStructure const & dir
Definition: settings.cc:136
Data structure holding basic CASM command info.
bool has_current_axes() const
True if curr_key is set.
std::set< std::string > enumerated
void select(std::string key)
Set this->curr using key.
CompositionConverter curr
std::map< std::string, CompositionConverter > all_axes
void insert_enumerated(IterType begin, IterType end)
Iterate over list of CompositionConverter and insert each one as an enumerated axes set with a unique...
void erase_enumerated()
Erase all enumerated axes and clear this->enumerated.