12 struct ClexDescription;
16 std::string _wdefaultval(std::string
name, std::pair<std::string, std::string> val) {
17 return name +
": '" + val.first +
"' (" + val.second +
")\n";
20 std::string _wdefaultval(std::string
name, std::pair<fs::path, std::string> val) {
21 return _wdefaultval(name, std::make_pair(val.first.string(), val.second));
40 (
"list,l",
"List project settings")
41 (
"new-property", po::value<std::string>(&
m_input_str),
"Create cluster expansions for a new property")
42 (
"new-bset", po::value<std::string>(&
m_input_str),
"Create a new basis set")
43 (
"new-calctype", po::value<std::string>(&
m_input_str),
"Create a new calculation type")
44 (
"new-ref", po::value<std::string>(&
m_input_str),
"Create a new calculation reference")
45 (
"new-eci", po::value<std::string>(&
m_input_str),
"Create a new set of effective cluster interactions (ECI)")
46 (
"set-formation-energy", po::value<std::string>(&
m_input_str),
"Specify the cluster expansion to use for formation energy")
47 (
"new-clex", po::value<std::string>(&
m_input_str),
"Create a new cluster expansion")
48 (
"set-default-clex", po::value<std::string>(&
m_input_str),
"Set the cluster expansion that CASM uses or acts on by default")
49 (
"erase-clex", po::value<std::string>(&
m_input_str),
"Erase the specified cluster expansion. Does not erase underlying bset, eci, etc.")
50 (
"clex", po::value<std::string>(),
"The cluster expansion for which to set property, bset, calctype, ref, or eci")
51 (
"set-property", po::value<std::string>(&
m_input_str),
"Set the current basis set")
52 (
"set-bset", po::value<std::string>(&
m_input_str),
"Set the basis set")
53 (
"set-calctype", po::value<std::string>(&
m_input_str),
"Set the calculation type")
54 (
"set-ref", po::value<std::string>(&
m_input_str),
"Set the calculation reference")
55 (
"set-eci", po::value<std::string>(&
m_input_str),
"Set the effective cluster interactions (ECI)")
56 (
"set-all", po::value<std::vector<std::string> >(&
m_input_vec)->multitoken(),
"Set the current property, calctype, ref, bset, and eci all at once.")
57 (
"set-view-command", po::value<std::string>(&
m_input_str),
"Set the command used by 'casm view'.")
58 (
"set-cxx", po::value<std::string>(&
m_input_str),
"Set the c++ compiler. Use '' to revert to default.")
59 (
"set-cxxflags", po::value<std::string>(&
m_input_str),
"Set the c++ compiler options. Use '' to revert to default.")
60 (
"set-soflags", po::value<std::string>(&
m_input_str),
"Set the shared library compilation options. Use '' to revert to default.")
61 (
"set-casm-prefix", po::value<std::string>(&
m_input_str),
"Set the casm prefix. Use '' to revert to default.")
62 (
"set-casm-includedir", po::value<std::string>(&
m_input_str),
"Set the casm includedir. Use '' to revert to default.")
63 (
"set-casm-libdir", po::value<std::string>(&
m_input_str),
"Set the casm libdir. Use '' to revert to default.")
64 (
"set-boost-prefix", po::value<std::string>(&
m_input_str),
"Set the boost prefix. Use '' to revert to default.")
65 (
"set-boost-includedir", po::value<std::string>(&
m_input_str),
"Set the boost includedir. Use '' to revert to default.")
66 (
"set-boost-libdir", po::value<std::string>(&
m_input_str),
"Set the boost libdir. Use '' to revert to default.");
76 enum create_mode {create, do_not_create};
81 typedef std::pair<std::string, create_mode> pair_type;
83 Data(PrimClex *_primclex,
84 DirectoryStructure &_dir,
85 ProjectSettings &_set,
86 ClexDescription &_desc,
117 ClexDescription tdesc(desc.name, property.first, calctype.first, ref.first, bset.first, eci.first);
119 bool res = try_new(
"property", property,
121 return contains(dir.all_property(), tdesc.property);
124 return set.new_clex_dir(tdesc.property);
126 try_new(
"calctype", calctype,
128 return contains(dir.all_calctype(), tdesc.calctype);
131 return set.new_calc_settings_dir(tdesc.calctype);
135 return contains(dir.all_ref(tdesc.calctype), tdesc.ref);
138 return set.new_ref_dir(tdesc.calctype, tdesc.ref);
140 try_new(
"bset", bset,
142 return contains(dir.all_bset(), tdesc.bset);
145 return set.new_bset_dir(tdesc.bset);
149 return contains(dir.all_eci(tdesc.property, tdesc.calctype, tdesc.ref, tdesc.bset), tdesc.eci);
152 return set.new_eci_dir(tdesc.property, tdesc.calctype, tdesc.ref, tdesc.bset, tdesc.eci);
160 if(
clex_exists(dir, tdesc) && set.set_default_clex(tdesc)) {
163 bool read_settings =
true;
164 bool read_composition =
false;
166 bool read_chem_ref =
false;
167 bool read_configs =
false;
168 if((desc.property != tdesc.property) ||
169 (desc.calctype != tdesc.calctype) ||
170 (desc.ref != tdesc.ref)) {
171 read_chem_ref =
true;
175 bool clear_clex =
false;
176 if((desc.property != tdesc.property) ||
177 (desc.bset != tdesc.bset) ||
178 (desc.eci != tdesc.eci)) {
183 log <<
"Updated default settings:\n";
184 bool is_default =
true;
186 desc.print(log, is_default, indent);
189 primclex->refresh(read_settings, read_composition, read_chem_ref, read_configs, clear_clex);
194 err_log <<
"Unknown error: Could not switch settings." << std::endl;
195 err_log <<
"Tried to switch to:\n";
196 tdesc.print(err_log,
false, 0);
216 bool try_new(std::string set_name, pair_type set, std::function<
bool ()> check_f, std::function<
bool ()> new_f) {
218 create_mode _cmode = set.second;
220 if(_cmode == create && check_f()) {
223 if(_cmode == create && !check_f()) {
226 log <<
"Created new " << set_name <<
": '" << set.first <<
"'\n";
230 err_log <<
"Could not create new " << set_name <<
": '" << set.first <<
"'\n";
235 if(_cmode == do_not_create && !check_f()) {
236 err_log <<
"Error: The " << set_name <<
" named '" << set.first <<
"' does not exist.\n";
237 err_log <<
" Check your input or use --new-" << set_name <<
" to create it first.\n";
242 if(_cmode == do_not_create && check_f()) {
247 throw std::runtime_error(
"Unknown error updating CASM settings");
260 std::string single_input;
261 std::vector<std::string> multi_input;
262 po::variables_map vm;
268 const po::options_description &desc = settings_opt.
desc();
271 po::store(po::parse_command_line(args.
argc, args.
argv, desc), vm);
273 bool call_help =
false;
275 std::vector<std::string> all_opt = {
"list",
"desc",
276 "new-property",
"new-bset",
"new-calctype",
"new-ref",
"new-eci",
277 "new-clex",
"set-formation-energy",
"erase-clex",
278 "set-default-clex",
"set-property",
"set-bset",
"set-calctype",
"set-ref",
"set-eci",
"set-all",
279 "set-cxx",
"set-cxxflags",
"set-soflags",
280 "set-casm-prefix",
"set-casm-includedir",
"set-casm-libdir",
281 "set-boost-prefix",
"set-boost-includedir",
"set-boost-libdir",
284 int option_count = 0;
285 for(
int i = 0; i < all_opt.size(); i++) {
286 option_count += vm.count(all_opt[i]);
290 if(!vm.count(
"help")) {
291 if(option_count == 0) {
292 args.
log <<
"Error in 'casm settings'. No option selected." << std::endl;
295 else if(option_count > 1) {
296 args.
log <<
"Error in 'casm settings'. Use one option (other than --clex) at a time." << std::endl;
302 if(vm.count(
"help") || call_help) {
304 args.
log << desc << std::endl;
309 if(vm.count(
"desc")) {
311 args.
log << desc << std::endl;
312 args.
log <<
"DESCRIPTION" << std::endl;
314 args.
log <<
" Often it is useful to try multiple different basis sets, \n" <<
315 " calculation settings, references, or ECI fits in a single\n" <<
316 " project. The 'casm settings' option helps to organize \n" <<
317 " these within a project and quickly switch between \n" <<
318 " different settings. \n";
320 args.
log <<
" Examples:\n";
322 " casm settings --list \n" <<
323 " - List all settings, with '*' for current settings \n\n" <<
325 " casm settings --new-clex 'my_newclex' \n" <<
326 " casm settings --set-default-clex 'other_clex' \n" <<
327 " - Creates a new group of settings for a cluster \n" <<
329 " - Includes property, calctype, ref, bset, and eci \n" <<
330 " - Can be used in Monte Carlo input files, and as \n" <<
331 " arguments to 'casm select' and 'casm query' \n" <<
332 " properties such as 'clex' and 'corr' to specify which\n" <<
333 " basis functions and eci to use. \n\n" <<
335 " casm settings --set-formation-energy 'other_clex' \n" <<
336 " - The cluster expansion 'other_clex' is copied to one \n" <<
337 " named 'formation_energy' which is used as the default\n" <<
338 " for grand canoncial Monte Carlo calculations and \n" <<
339 " cluster expansion convex hull calculations. \n\n" <<
341 " casm settings --new-property 'my_new_property' \n" <<
342 " casm settings --new-bset 'my_new_bset' \n" <<
343 " casm settings --new-calctype 'my_new_calctype' \n" <<
344 " casm settings --new-ref 'my_new_ref' \n" <<
345 " casm settings --new-eci 'my_new_eci' \n" <<
346 " - Creates new settings directories with appropriate \n" <<
348 " - For --new-property, new 'default' calctype, ref, and \n" <<
349 " eci are created. \n" <<
350 " - For --new-calctype, a new 'default' ref is created. \n" <<
351 " - For --new-ref, a new reference is created for the \n" <<
352 " current calctype \n" <<
353 " - For --new-eci, a new eci directory is created for the\n" <<
354 " current clex, calctype and ref. \n\n" <<
356 " casm settings --set-property 'other_property' \n" <<
357 " casm settings --set-bset 'other_bset' \n" <<
358 " casm settings --set-calctype 'other_calctype' \n" <<
359 " casm settings --set-ref 'other_ref' \n" <<
360 " casm settings --set-eci 'other_eci' \n" <<
361 " casm settings --set-all 'property' 'calctype', 'ref', 'bset', 'eci'\n" <<
362 " - Switch the current settings \n" <<
363 " - For --set-property, standard options are: \n" <<
364 " - 'formation_energy' (the only standard option for now)\n" <<
365 " After switching, the 'default' calctype, ref, bset, \n" <<
367 " - For --set-calctype, the current property and bset are\n" <<
368 " maintained, and the 'default' ref, and eci are used. \n" <<
369 " - For --set-ref, the current property, calctype, and \n" <<
370 " bset are maintained, and the 'default' eci is used. \n" <<
371 " - For --set-bset, the current property, calctype, and \n" <<
372 " ref are maintained, and the 'default' eci is used. \n" <<
373 " - For --set-eci, the current property, calctype, ref, \n" <<
374 " and bset are maintained. \n" <<
375 " - For --set-all, all settings are switched at once. \n\n" <<
377 " casm settings --set-cxx 'cxx' \n" <<
378 " - Specifies compiler to use. In order of priority: \n"
379 " 1) User specified by 'casm settings --set-cxx' \n"
380 " (use '' to clear) \n"
385 " casm settings --set-cxxflags 'cxxflags' \n"
386 " - Specifies compiler options. In order of priority: \n"
387 " 1) User specified by 'casm settings --set-cxxflags' \n"
388 " (use '' to clear) \n"
389 " 2) $CASM_CXXFLAGS \n"
390 " 3) \"-O3 -Wall -fPIC --std=c++11\" \n\n"
392 " casm settings --set-soflags 'soflags' \n"
393 " - Specifies shared object construction flags. In order \n"
395 " 1) User specified by 'casm settings --set-soflags' \n"
396 " (use '' to clear) \n"
397 " 2) $CASM_SOFLAGS \n"
398 " 3) \"-shared -lboost_system\" \n\n"
400 " casm settings --set-casm-prefix 'casm_prefix' \n"
401 " casm settings --set-casm-includedir 'casm_includedir' \n"
402 " casm settings --set-casm-libdir 'casm_libdir' \n"
403 " - Specifies location to find CASM header files and shared\n"
404 " libraries for runtime compilation and linking. \n"
405 " In order of priority: \n"
406 " 1) User specified by via 'casm settings' (use '' to clear) \n"
407 " 2) $CASM_INCLUDEDIR and $CASM_LIBDIR \n"
408 " 3) $CASM_PREFIX/include and $CASM_PREFIX/lib \n"
409 " 4) (default search paths) \n\n"
411 " casm settings --set-boost-prefix 'boost_prefix' \n"
412 " casm settings --set-boost-includedir 'boost_includedir' \n"
413 " casm settings --set-boost-libdir 'boost_libdir' \n"
414 " - Specifies location to find boost header files and shared\n"
415 " libraries for runtime compilation and linking. \n"
416 " In order of priority: \n"
417 " 1) User specified by via 'casm settings' (use '' to clear) \n"
418 " 2) $CASM_BOOST_INCLUDEDIR and $CASM_BOOST_LIBDIR \n"
419 " 3) $CASM_BOOST_PREFIX/include and $CASM_BOOST_PREFIX/lib \n"
420 " 4) (default search paths) \n\n"
422 " casm settings --set-view-command 'casm.view \"open -a /Applications/VESTA/VESTA.app\"'\n" <<
423 " - Sets the command used by 'casm view' to open \n" <<
424 " visualization software. \n" <<
425 " - Will be executed with '/path/to/POSCAR' as an \n" <<
426 " argument, the location of a POSCAR for a configuration\n" <<
427 " selected for visualization. \n" <<
443 catch(po::error &e) {
444 args.
err_log <<
"ERROR: " << e.what() << std::endl << std::endl;
445 args.
err_log << desc << std::endl;
449 catch(std::exception &e) {
450 args.
err_log <<
"Unhandled Exception reached the top of main: "
451 << e.what() <<
", application will now exit" << std::endl;
459 args.
err_log <<
"current_path: " << fs::current_path() << std::endl;
468 if(vm.count(
"clex")) {
472 args.
err_log << vm[
"clex"].as<std::string>() <<
" not found. expected basis set specifications file at: " << dir.
bspecs(clex_desc.bset) <<
"\n" << std::endl;
475 clex_desc = it->second;
480 typedef Data::pair_type pair_type;
483 if(vm.count(
"list")) {
489 else if(vm.count(
"new-property")) {
491 d.property = pair_type(single_input, create);
492 d.calctype = pair_type(
"default", create);
493 d.ref = pair_type(
"default", create);
494 d.bset = pair_type(
"default", create);
495 d.eci = pair_type(
"default", create);
501 else if(vm.count(
"new-bset")) {
503 d.bset = pair_type(single_input, create);
504 d.eci = pair_type(
"default", create);
510 else if(vm.count(
"new-calctype")) {
512 d.calctype = pair_type(single_input, create);
513 d.ref = pair_type(
"default", create);
514 d.eci = pair_type(
"default", create);
520 else if(vm.count(
"new-ref")) {
522 d.ref = pair_type(single_input, create);
523 d.eci = pair_type(
"default", create);
529 else if(vm.count(
"new-eci")) {
531 d.eci = pair_type(single_input, create);
537 else if(vm.count(
"new-clex")) {
538 clex_desc.name = single_input;
540 args.
log <<
"Created new cluster expansion named '" << single_input <<
"'\n\n";
543 args.
log <<
"Could not create new cluster expansion named '" << single_input <<
"'.\n\n";
552 args.
log <<
"Set '" << clex_desc.name <<
"' as default cluster expansion.\n\n";
556 args.
log <<
"Could not set '" << clex_desc.name <<
"' as default cluster expansion.\n\n";
562 else if(vm.count(
"erase-clex")) {
564 args.
log <<
"Coult not erase the cluster expansion named '" << single_input <<
"' "
565 <<
"because it is the default cluster expansion.\n\n";
570 args.
log <<
"Could not erase the cluster expansion named '" << single_input <<
"' "
571 <<
"because it is the only cluster expansion.\n\n";
580 args.
log <<
"Erased cluster expansion named '" << single_input <<
"'\n\n";
584 args.
log <<
"Could not erase cluster expansion named '" << single_input <<
"'.\n\n";
590 else if(vm.count(
"set-formation-energy")) {
592 if(clex_desc.property !=
"formation_energy") {
593 args.
err_log <<
"Attempting to use cluster expansion '" << clex_desc.name
594 <<
"' for formation_energy, but it has 'property' value '"
595 << clex_desc.property <<
"'.\n\n";
603 clex_desc.name =
"formation_energy";
609 args.
log <<
"Now using cluster expansion '" << single_input
610 <<
"' as the default for formation_energy.\n\n";
614 args.
log <<
"Could not use cluster expansion '" << single_input
615 <<
"' as the default for formation_energy.\n\n";
621 else if(vm.count(
"set-default-clex")) {
627 args.
log <<
"Switched to cluster expansion '" << single_input <<
"'.\n\n";
631 args.
log <<
"Could not switch to cluster expansion '" << single_input <<
"'.\n\n";
637 else if(vm.count(
"set-property")) {
639 d.property = pair_type(single_input, do_not_create);
640 d.calctype = pair_type(
"default", do_not_create);
641 d.ref = pair_type(
"default", do_not_create);
642 d.bset = pair_type(
"default", do_not_create);
643 d.eci = pair_type(
"default", create);
649 else if(vm.count(
"set-bset")) {
651 d.bset = pair_type(single_input, do_not_create);
652 d.eci = pair_type(
"default", create);
658 else if(vm.count(
"set-calctype")) {
660 d.calctype = pair_type(single_input, do_not_create);
661 d.ref = pair_type(
"default", do_not_create);
662 d.eci = pair_type(
"default", create);
668 else if(vm.count(
"set-ref")) {
670 d.ref = pair_type(single_input, do_not_create);
671 d.eci = pair_type(
"default", create);
677 else if(vm.count(
"set-eci")) {
679 d.eci = pair_type(single_input, do_not_create);
685 else if(vm.count(
"set-all")) {
687 if(multi_input.size() != 5) {
688 args.
log <<
"Error using --set-all: Expected 5 arguments: 'property' 'calctype' 'ref' 'bset' 'eci'" << std::endl;
692 d.property = pair_type(multi_input[0], do_not_create);
693 d.calctype = pair_type(multi_input[1], do_not_create);
694 d.ref = pair_type(multi_input[2], do_not_create);
695 d.bset = pair_type(multi_input[3], do_not_create);
696 d.eci = pair_type(multi_input[4], create);
702 else if(vm.count(
"set-cxx")) {
709 args.
log <<
"Set " << _wdefaultval(
"cxx", set.
cxx());
711 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
717 else if(vm.count(
"set-cxxflags")) {
724 args.
log <<
"Set " << _wdefaultval(
"cxxflags", set.
cxxflags());
731 else if(vm.count(
"set-soflags")) {
738 args.
log <<
"Set " << _wdefaultval(
"soflags", set.
soflags());
739 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
745 else if(vm.count(
"set-casm-prefix")) {
753 args.
log <<
"Set " << _wdefaultval(
"casm_libdir", set.
casm_libdir());
755 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
761 else if(vm.count(
"set-casm-includedir")) {
770 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
776 else if(vm.count(
"set-casm-libdir")) {
783 args.
log <<
"Set " << _wdefaultval(
"casm_libdir", set.
casm_libdir());
785 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
791 else if(vm.count(
"set-boost-prefix")) {
799 args.
log <<
"Set " << _wdefaultval(
"boost_libdir", set.
boost_libdir());
801 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
807 else if(vm.count(
"set-boost-includedir")) {
816 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
822 else if(vm.count(
"set-boost-libdir")) {
829 args.
log <<
"Set " << _wdefaultval(
"boost_libdir", set.
boost_libdir());
831 args.
log <<
"Shared object compile command is now: '" << set.
so_options() <<
"'\n\n";
837 else if(vm.count(
"set-view-command")) {
849 args.
log << std::endl;
Data structure holding basic CASM command info.
const std::vector< std::string > & input_vec() const
Specifies a particular cluster expansion.
void commit() const
Save settings to project settings file.
std::pair< std::string, std::string > cxxflags() const
Get c++ compiler options.
std::vector< std::string > m_input_vec
bool set_casm_prefix(fs::path dir)
Set casm prefix (empty string to use default)
std::pair< fs::path, std::string > boost_includedir() const
Get boost includedir.
Specification of CASM project directory structure.
const std::string & input_str() const
void add_help_suboption()
Add a plain –help suboption.
std::string so_options() const
Get current shared library options string.
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.
bool set_default_clex(const std::string &clex_name)
void initialize() override
Fill in the options descriptions accordingly.
void print_summary(Log &log) const
Print summary of ProjectSettings, as for 'casm settings -l'.
bool set_view_command(std::string opt)
Set command used by 'casm view'.
bool set_cxx(std::string opt)
Set c++ compiler (empty string to use default)
bool clex_exists(const DirectoryStructure &dir, const ClexDescription &desc)
fs::path bspecs(std::string bset) const
Return basis function specs (bspecs.json) file path.
const ClexDescription & clex(std::string name) const
const po::options_description & desc()
Get the program options, filled with the initialized values.
Read/modify settings of an already existing CASM project.
std::pair< fs::path, std::string > casm_libdir() const
Get casm libdir.
std::pair< fs::path, std::string > casm_includedir() const
Get casm includedir.
bool set_boost_prefix(fs::path dir)
Set boost prefix (empty string to use default)
bool set_boost_libdir(fs::path dir)
Set boost libdir (empty string to use default)
po::options_description m_desc
Boost program options. All the derived classes have them, but will fill them up themselves.
std::string compile_options() const
Get current compilation options string.
bool set_casm_libdir(fs::path dir)
Set casm libdir (empty string to use default)
bool set_soflags(std::string opt)
Set shared object options (empty string to use default)
const std::map< std::string, ClexDescription > & cluster_expansions() const
bool set_casm_includedir(fs::path dir)
Set casm includedir (empty string to use default)
bool erase_clex(const ClexDescription &desc)
void error(const std::string &what)
std::pair< fs::path, std::string > boost_libdir() const
Get boost libdir.
bool new_clex(const ClexDescription &desc)
std::string view_command() const
Get current command used by 'casm view'.
std::tuple< fs::path, jsonParser, std::string, std::pair< bool, double > > Data
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value) ...
std::pair< std::string, std::string > soflags() const
Get shared object options.
std::pair< std::string, std::string > cxx() const
Get c++ compiler.
int settings_command(const CommandArgs &args)
const ClexDescription & default_clex() const
bool set_boost_includedir(fs::path dir)
Set boost includedir (empty string to use default)
bool set_cxxflags(std::string opt)
Set c++ compiler options (empty string to use default)