1 #include <boost/filesystem.hpp>
14 struct ClexDescription;
18 std::string _wdefaultval(std::string
name,
19 std::pair<std::string, std::string> val) {
20 return name +
": '" + val.first +
"' (" + val.second +
")\n";
23 std::string _wdefaultval(std::string
name,
24 std::pair<fs::path, std::string> val) {
25 return _wdefaultval(
name, std::make_pair(val.first.string(), val.second));
41 m_desc.add_options()(
"list,l",
"List project settings")(
42 "new-property", po::value<std::string>(&
m_input_str),
43 "Create cluster expansions for a new property")(
45 "Create a new basis set")(
"new-calctype",
47 "Create a new calculation type")(
49 "Create a new calculation reference")(
51 "Create a new set of effective cluster interactions (ECI)")(
52 "set-formation-energy", po::value<std::string>(&
m_input_str),
53 "Specify the cluster expansion to use for formation energy")(
55 "Create a new cluster expansion")(
58 "Set the cluster expansion that CASM uses or acts on by default")(
61 "Erase the specified cluster expansion. Does not erase underlying bset, "
64 "The cluster expansion for which to set property, bset, "
65 "calctype, ref, or eci")(
68 "Set the property being cluster expanded")(
74 "Set the calculation type")(
77 "Set the calculation reference")(
80 "Set the effective cluster interactions (ECI)")(
82 po::value<std::vector<std::string> >(&
m_input_vec)->multitoken(),
83 "Set the current property, calctype, ref, bset, and eci all at once.")(
84 "set-view-command", po::value<std::string>(&
m_input_str),
85 "Set the command used by 'casm view'.")(
86 "set-view-command-video", po::value<std::string>(&
m_input_str),
87 "Set the command used by 'casm view' for videos.")(
89 "Set the c++ compiler. Use '' to revert to default.")(
90 "set-cxxflags", po::value<std::string>(&
m_input_str),
91 "Set the c++ compiler options. Use '' to revert to default.")(
92 "set-soflags", po::value<std::string>(&
m_input_str),
93 "Set the shared library compilation options. Use '' to revert to "
94 "default.")(
"set-casm-prefix", po::value<std::string>(&
m_input_str),
95 "Set the casm prefix. Use '' to revert to default.")(
96 "set-casm-includedir", po::value<std::string>(&
m_input_str),
97 "Set the casm includedir. Use '' to revert to default.")(
98 "set-casm-libdir", po::value<std::string>(&
m_input_str),
99 "Set the casm libdir. Use '' to revert to default.")(
100 "set-boost-prefix", po::value<std::string>(&
m_input_str),
101 "Set the boost prefix. Use '' to revert to default.")(
102 "set-boost-includedir", po::value<std::string>(&
m_input_str),
103 "Set the boost includedir. Use '' to revert to default.")(
104 "set-boost-libdir", po::value<std::string>(&
m_input_str),
105 "Set the boost libdir. Use '' to revert to default.");
115 enum create_mode { create, do_not_create };
119 typedef std::pair<std::string, create_mode> pair_type;
121 Data(PrimClex *_primclex, DirectoryStructure
const &_dir,
122 ProjectSettings &_set, ClexDescription &_desc)
136 DirectoryStructure
const &
dir;
156 [&]() {
return contains(
dir.all_property(), tdesc.property); },
157 [&]() {
return dir.new_clex_dir(tdesc.property); }) &&
160 [&]() {
return contains(
dir.all_calctype(), tdesc.calctype); },
161 [&]() {
return dir.new_calc_settings_dir(tdesc.calctype); }) &&
164 [&]() {
return contains(
dir.all_ref(tdesc.calctype), tdesc.ref); },
165 [&]() {
return dir.new_ref_dir(tdesc.calctype, tdesc.ref); }) &&
168 [&]() {
return contains(
dir.all_bset(), tdesc.bset); },
169 [&]() {
return dir.new_bset_dir(tdesc.bset); }) &&
173 return contains(
dir.all_eci(tdesc.property, tdesc.calctype,
174 tdesc.ref, tdesc.bset),
178 return dir.new_eci_dir(tdesc.property, tdesc.calctype, tdesc.ref,
179 tdesc.bset, tdesc.eci);
190 bool read_settings =
true;
191 bool read_composition =
false;
193 bool read_chem_ref =
false;
194 bool read_configs =
false;
195 if ((
desc.property != tdesc.property) ||
196 (
desc.calctype != tdesc.calctype) || (
desc.ref != tdesc.ref)) {
197 read_chem_ref =
true;
201 bool clear_clex =
false;
202 if ((
desc.property != tdesc.property) || (
desc.bset != tdesc.bset) ||
203 (
desc.eci != tdesc.eci)) {
208 log <<
"Updated default settings:\n";
209 bool is_default =
true;
211 desc.print(
log, is_default, indent);
214 primclex->refresh(read_settings, read_composition, read_chem_ref,
215 read_configs, clear_clex);
219 err_log <<
"Unknown error: Could not switch settings." << std::endl;
220 err_log <<
"Tried to switch to:\n";
241 bool try_new(std::string set_name, pair_type
set,
242 std::function<
bool()> check_f, std::function<
bool()> new_f) {
243 create_mode _cmode =
set.second;
245 if (_cmode == create && check_f()) {
248 if (_cmode == create && !check_f()) {
251 log <<
"Created new " << set_name <<
": '" <<
set.first <<
"'\n";
254 err_log <<
"Could not create new " << set_name <<
": '" <<
set.first
260 if (_cmode == do_not_create && !check_f()) {
261 err_log <<
"Error: The " << set_name <<
" named '" <<
set.first
262 <<
"' does not exist.\n";
263 err_log <<
" Check your input or use --new-" << set_name
264 <<
" to create it first.\n";
269 if (_cmode == do_not_create && check_f()) {
274 throw std::runtime_error(
"Unknown error updating CASM settings");
284 std::string single_input;
285 std::vector<std::string> multi_input;
286 po::variables_map vm;
291 const po::options_description &
desc =
296 po::store(po::parse_command_line(args.
argc(), args.
argv(),
desc),
299 bool call_help =
false;
301 std::vector<std::string> all_opt = {
"list",
309 "set-formation-energy",
322 "set-casm-includedir",
325 "set-boost-includedir",
328 "set-view-command-video"};
329 int option_count = 0;
330 for (
int i = 0; i < all_opt.size(); i++) {
331 option_count += vm.count(all_opt[i]);
335 if (!vm.count(
"help")) {
336 if (option_count == 0) {
337 log() <<
"Error in 'casm settings'. No option selected." << std::endl;
339 }
else if (option_count > 1) {
340 log() <<
"Error in 'casm settings'. Use one option (other than "
348 if (vm.count(
"help") || call_help) {
355 if (vm.count(
"desc")) {
358 log() <<
"DESCRIPTION" << std::endl;
361 <<
" Often it is useful to try multiple different basis sets, \n"
362 <<
" calculation settings, references, or ECI fits in a single\n"
363 <<
" project. The 'casm settings' option helps to organize \n"
364 <<
" these within a project and quickly switch between \n"
365 <<
" different settings. "
368 log() <<
" Examples:\n";
371 <<
" casm settings --list \n"
372 <<
" - List all settings, with '*' for current settings "
376 " casm settings --new-clex 'my_newclex' \n"
377 <<
" casm settings --set-default-clex 'other_clex' \n"
378 <<
" - Creates a new group of settings for a cluster \n"
380 <<
" - Includes property, calctype, ref, bset, and eci \n"
381 <<
" - Can be used in Monte Carlo input files, and as \n"
382 <<
" arguments to 'casm select' and 'casm query' \n"
383 <<
" properties such as 'clex' and 'corr' to specify which\n"
384 <<
" basis functions and eci to use. "
388 " casm settings --set-formation-energy 'other_clex' \n"
389 <<
" - The cluster expansion 'other_clex' is copied to one \n"
390 <<
" named 'formation_energy' which is used as the default\n"
391 <<
" for grand canoncial Monte Carlo calculations and \n"
392 <<
" cluster expansion convex hull calculations. "
396 " casm settings --new-property 'my_new_property' \n"
397 <<
" casm settings --new-bset 'my_new_bset' \n"
398 <<
" casm settings --new-calctype 'my_new_calctype' \n"
399 <<
" casm settings --new-ref 'my_new_ref' \n"
400 <<
" casm settings --new-eci 'my_new_eci' \n"
401 <<
" - Creates new settings directories with appropriate \n"
403 <<
" - For --new-property, new 'default' calctype, ref, and \n"
404 <<
" eci are created. \n"
405 <<
" - For --new-calctype, a new 'default' ref is created. \n"
406 <<
" - For --new-ref, a new reference is created for the \n"
407 <<
" current calctype \n"
408 <<
" - For --new-eci, a new eci directory is created for the\n"
409 <<
" current clex, calctype and ref. "
413 " casm settings --set-property 'other_property' \n"
414 <<
" casm settings --set-bset 'other_bset' \n"
415 <<
" casm settings --set-calctype 'other_calctype' \n"
416 <<
" casm settings --set-ref 'other_ref' \n"
417 <<
" casm settings --set-eci 'other_eci' \n"
418 <<
" casm settings --set-all 'property' 'calctype', 'ref', "
420 <<
" - Switch the current settings \n"
421 <<
" - For --set-property, standard options are: \n"
422 <<
" - 'formation_energy' (the only standard option for "
424 <<
" After switching, the 'default' calctype, ref, bset, \n"
425 <<
" and eci are used"
426 " - For --set-calctype, the current property and bset are\n"
427 <<
" maintained, and the 'default' ref, and eci are used. \n"
428 <<
" - For --set-ref, the current property, calctype, and \n"
429 <<
" bset are maintained, and the 'default' eci is used. \n"
430 <<
" - For --set-bset, the current property, calctype, and \n"
431 <<
" ref are maintained, and the 'default' eci is used. \n"
432 <<
" - For --set-eci, the current property, calctype, ref, \n"
433 <<
" and bset are maintained. \n"
434 <<
" - For --set-all, all settings are switched at once. "
438 " casm settings --set-cxx 'cxx' \n"
439 <<
" - Specifies compiler to use. In order of priority: \n"
440 " 1) User specified by 'casm settings --set-cxx' \n"
441 " (use '' to clear) \n"
446 " casm settings --set-cxxflags 'cxxflags' \n"
447 " - Specifies compiler options. In order of priority: \n"
448 " 1) User specified by 'casm settings --set-cxxflags' \n"
449 " (use '' to clear) \n"
450 " 2) $CASM_CXXFLAGS \n"
451 " 3) \"-O3 -Wall -fPIC --std=c++17\" \n\n"
453 " casm settings --set-soflags 'soflags' \n"
454 " - Specifies shared object construction flags. In order \n"
456 " 1) User specified by 'casm settings --set-soflags' \n"
457 " (use '' to clear) \n"
458 " 2) $CASM_SOFLAGS \n"
459 " 3) \"-shared -lboost_system\" \n\n"
461 " casm settings --set-casm-prefix 'casm_prefix' \n"
462 " casm settings --set-casm-includedir 'casm_includedir' \n"
463 " casm settings --set-casm-libdir 'casm_libdir' \n"
464 " - Specifies location to find CASM header files and "
466 " libraries for runtime compilation and linking. "
468 " In order of priority: \n"
469 " 1) User specified by via 'casm settings' (use '' to "
471 " 2) $CASM_INCLUDEDIR and $CASM_LIBDIR \n"
472 " 3) $CASM_PREFIX/include and $CASM_PREFIX/lib \n"
473 " 4) (default search paths) \n\n"
475 " casm settings --set-boost-prefix 'boost_prefix' \n"
476 " casm settings --set-boost-includedir 'boost_includedir' "
478 " casm settings --set-boost-libdir 'boost_libdir' \n"
479 " - Specifies location to find boost header files and "
481 " libraries for runtime compilation and linking. "
483 " In order of priority: \n"
484 " 1) User specified by via 'casm settings' (use '' to "
486 " 2) $CASM_BOOST_INCLUDEDIR and $CASM_BOOST_LIBDIR \n"
487 " 3) $CASM_BOOST_PREFIX/include and "
488 "$CASM_BOOST_PREFIX/lib \n"
489 " 4) (default search paths) \n\n"
490 " casm settings --set-view-command 'casm.view \"open -a "
491 "/Applications/VESTA/VESTA.app\"'\n"
492 <<
" - Sets the command used by 'casm view' to open \n"
493 <<
" visualization software. \n"
494 <<
" - Will be executed with '/path/to/POSCAR' as an \n"
495 <<
" argument, the location of a POSCAR for a "
497 <<
" selected for visualization. \n"
498 <<
" casm settings --set-view-command-video 'casm.view \"open "
499 "-a /Applications/Ovito/ovito.app\"'\n"
500 <<
" - Sets the command used by 'casm view' to open \n"
501 <<
" visualization software. \n"
502 <<
" - Will be executed with '/path/to/POSCAR' as an \n"
503 <<
" argument, the location of a POSCAR for a "
504 "diff_trans_config\n"
505 <<
" selected for visualization. \n"
508 if (call_help)
return 1;
519 }
catch (po::error &e) {
520 err_log() <<
"ERROR: " << e.what() << std::endl << std::endl;
524 }
catch (std::exception &e) {
525 err_log() <<
"Unhandled Exception reached the top of main: " << e.what()
526 <<
", application will now exit" << std::endl;
530 const fs::path &root = args.
root;
533 err_log() <<
"current_path: " << fs::current_path() << std::endl;
542 if (vm.count(
"clex")) {
546 err_log() << vm[
"clex"].as<std::string>()
547 <<
" not found. expected basis set specifications file at: "
552 clex_desc = it->second;
557 typedef Data::pair_type pair_type;
560 if (vm.count(
"list")) {
566 else if (vm.count(
"new-property")) {
567 d.property = pair_type(single_input, create);
568 d.calctype = pair_type(
"default", create);
569 d.ref = pair_type(
"default", create);
570 d.bset = pair_type(
"default", create);
571 d.eci = pair_type(
"default", create);
577 else if (vm.count(
"new-bset")) {
578 d.bset = pair_type(single_input, create);
579 d.eci = pair_type(
"default", create);
585 else if (vm.count(
"new-calctype")) {
586 d.calctype = pair_type(single_input, create);
587 d.ref = pair_type(
"default", create);
588 d.eci = pair_type(
"default", create);
594 else if (vm.count(
"new-ref")) {
595 d.ref = pair_type(single_input, create);
596 d.eci = pair_type(
"default", create);
602 else if (vm.count(
"new-eci")) {
603 d.eci = pair_type(single_input, create);
609 else if (vm.count(
"new-clex")) {
610 clex_desc.name = single_input;
612 log() <<
"Created new cluster expansion named '" << single_input
615 log() <<
"Could not create new cluster expansion named '" << single_input
625 log() <<
"Set '" << clex_desc.name
626 <<
"' as default cluster expansion.\n\n";
629 log() <<
"Could not set '" << clex_desc.name
630 <<
"' as default cluster expansion.\n\n";
636 else if (vm.count(
"erase-clex")) {
638 log() <<
"Coult not erase the cluster expansion named '" << single_input
640 <<
"because it is the default cluster expansion.\n\n";
645 log() <<
"Could not erase the cluster expansion named '" << single_input
647 <<
"because it is the only cluster expansion.\n\n";
656 log() <<
"Erased cluster expansion named '" << single_input <<
"'\n\n";
659 log() <<
"Could not erase cluster expansion named '" << single_input
666 else if (vm.count(
"set-formation-energy")) {
667 if (clex_desc.property !=
"formation_energy") {
668 err_log() <<
"Attempting to use cluster expansion '" << clex_desc.name
669 <<
"' for formation_energy, but it has 'property' value '"
670 << clex_desc.property <<
"'.\n\n";
678 clex_desc.name =
"formation_energy";
684 log() <<
"Now using cluster expansion '" << single_input
685 <<
"' as the default for formation_energy.\n\n";
688 log() <<
"Could not use cluster expansion '" << single_input
689 <<
"' as the default for formation_energy.\n\n";
695 else if (vm.count(
"set-default-clex")) {
701 log() <<
"Switched to cluster expansion '" << single_input <<
"'.\n\n";
704 log() <<
"Could not switch to cluster expansion '" << single_input
711 else if (vm.count(
"set-property")) {
712 d.property = pair_type(single_input, do_not_create);
713 d.calctype = pair_type(
"default", do_not_create);
714 d.ref = pair_type(
"default", do_not_create);
715 d.bset = pair_type(
"default", do_not_create);
716 d.eci = pair_type(
"default", create);
722 else if (vm.count(
"set-bset")) {
723 d.bset = pair_type(single_input, do_not_create);
724 d.eci = pair_type(
"default", create);
730 else if (vm.count(
"set-calctype")) {
731 d.calctype = pair_type(single_input, do_not_create);
732 d.ref = pair_type(
"default", do_not_create);
733 d.eci = pair_type(
"default", create);
739 else if (vm.count(
"set-ref")) {
740 d.ref = pair_type(single_input, do_not_create);
741 d.eci = pair_type(
"default", create);
747 else if (vm.count(
"set-eci")) {
748 d.eci = pair_type(single_input, do_not_create);
754 else if (vm.count(
"set-all")) {
755 if (multi_input.size() != 5) {
756 log() <<
"Error using --set-all: Expected 5 arguments: 'property' "
757 "'calctype' 'ref' 'bset' 'eci'"
762 d.property = pair_type(multi_input[0], do_not_create);
763 d.calctype = pair_type(multi_input[1], do_not_create);
764 d.ref = pair_type(multi_input[2], do_not_create);
765 d.bset = pair_type(multi_input[3], do_not_create);
766 d.eci = pair_type(multi_input[4], create);
772 else if (vm.count(
"set-cxx")) {
779 log() <<
"Set " << _wdefaultval(
"cxx",
set.
cxx());
788 else if (vm.count(
"set-cxxflags")) {
802 else if (vm.count(
"set-soflags")) {
817 else if (vm.count(
"set-casm-prefix")) {
834 else if (vm.count(
"set-casm-includedir")) {
850 else if (vm.count(
"set-casm-libdir")) {
866 else if (vm.count(
"set-boost-prefix")) {
883 else if (vm.count(
"set-boost-includedir")) {
899 else if (vm.count(
"set-boost-libdir")) {
915 else if (vm.count(
"set-view-command")) {
928 else if (vm.count(
"set-view-command-video")) {
static std::string calctype()
Get value_type string for calctype mode completion.
static std::string property()
Get value_type string for property mode completion.
static std::string eci()
Get value_type string for eci mode completion.
static std::string ref()
Get value_type string for ref mode completion.
static std::string bset()
Get value_type string for bset mode completion.
static std::string clex()
Get value_type string for clex mode completion.
const po::options_description & desc()
Get the program options, filled with the initialized values.
void add_help_suboption()
Add a plain –help and –desc suboptions.
po::options_description m_desc
std::vector< std::string > m_input_vec
void initialize() override
Fill in the options descriptions accordingly.
const std::string & input_str() const
const std::vector< std::string > & input_vec() const
Specification of CASM project directory structure.
fs::path bspecs(std::string bset) const
Return basis function specs (bspecs.json) file path.
void error(const std::string &what)
std::pair< fs::path, std::string > boost_includedir() const
Get boost includedir (pair of value and source for the value)
ClexDescription const & clex(std::string clex_name) const
Get a ClexDescription by name.
std::string view_command() const
Get current command used by 'casm view'.
bool set_view_command(std::string opt)
Set command used by 'casm view'.
std::pair< fs::path, std::string > casm_libdir() const
Get casm libdir (pair of value and source for the value)
bool insert_clex(ClexDescription const &desc)
std::map< std::string, ClexDescription > const & cluster_expansions() const
Const access map of all ClexDescription.
bool set_cxxflags(std::string opt)
Set c++ compiler options (empty string to use default)
bool set_boost_libdir(fs::path dir)
Set boost libdir (empty string to use default)
DirectoryStructure const & dir() const
Access DirectoryStructure object. Throw if not set.
std::string compile_options() const
bool set_boost_prefix(fs::path dir)
Set boost prefix (empty string to use default)
std::pair< fs::path, std::string > casm_includedir() const
Get casm includedir (pair of value and source for the value)
bool set_default_clex_name(std::string const &clex_name)
Set default ClexDescription by name.
std::pair< fs::path, std::string > boost_libdir() const
Get boost libdir (pair of value and source for the value)
bool set_casm_includedir(fs::path dir)
Set casm includedir (empty string to use default)
bool set_casm_prefix(fs::path dir)
Set casm prefix (empty string to use default)
ClexDescription const & default_clex() const
Get default ClexDescription.
std::pair< std::string, std::string > soflags() const
Get shared object options (pair of value and source for the value)
bool set_view_command_video(std::string opt)
Set video viewing command used by 'casm view'.
std::string so_options() const
std::pair< std::string, std::string > cxx() const
Get c++ compiler (pair of value and source for the value)
bool set_default_clex(ClexDescription const &desc)
bool set_soflags(std::string opt)
Set shared object options (empty string to use default)
bool erase_clex(ClexDescription const &desc)
bool set_casm_libdir(fs::path dir)
Set casm libdir (empty string to use default)
bool set_boost_includedir(fs::path dir)
Set boost includedir (empty string to use default)
bool set_cxx(std::string opt)
Set c++ compiler (empty string to use default)
std::pair< std::string, std::string > cxxflags() const
Get c++ compiler options (pair of value and source for the value)
std::string view_command_video() const
Get current video viewing command used by 'casm view'.
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.
void commit(ProjectSettings const &set)
ProjectSettings open_project_settings(fs::path path_in_project)
void print_summary(ProjectSettings const &set, Log &log)
Print summary of ProjectSettings, as for 'casm settings -l'.
bool clex_exists(const DirectoryStructure &dir, const ClexDescription &desc)
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
int settings_command(const CommandArgs &args)
DirectoryStructure const & dir
Specifies a particular cluster expansion.
Data structure holding basic CASM command info.