CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
FCCTernaryProj.hh
Go to the documentation of this file.
1 #ifndef CASMtest_FCCTernaryProj
2 #define CASMtest_FCCTernaryProj
3 
4 #include "Proj.hh"
8 #include "casm/casm_io/Log.hh"
9 #include "casm/clex/PrimClex.hh"
11 
12 
13 using namespace CASM;
14 
15 
16 namespace test {
17 
19 
20  // lattice vectors as cols
21  Eigen::Matrix3d lat;
22  lat << 0.0, 2.0, 2.0,
23  2.0, 0.0, 2.0,
24  2.0, 2.0, 0.0;
25 
26  BasicStructure<Site> struc {Lattice{lat}};
27  struc.title = "FCC_ternary";
28 
29  Molecule A = make_atom("A", struc.lattice());
30  Molecule B = make_atom("B", struc.lattice());
31  Molecule C = make_atom("C", struc.lattice());
32 
33  struc.basis.push_back(Site(Coordinate(Eigen::Vector3d::Zero(), struc.lattice(), CART), {A, B, C}));
34 
35  return struc;
36 
37  }
38 
39  class FCCTernaryProj : public Proj {
40 
41  public:
42 
44  //Use PID to get unique naming. Otherwise different tests might obliterate your directory mid testing if you run in parallel
45  Proj(proj_dir("tests/unit/test_projects/FCC_ternary"),
47  "FCC_ternary",
48  "FCC Ternary with A, B, C occupation") {}
49 
50  static jsonParser bspecs() {
51 
52  std::string str = R"({
53 "basis_functions" : {
54 "site_basis_functions" : "occupation"
55 },
56 "orbit_branch_specs" : {
57 "2" : {"max_length" : 4.01},
58 "3" : {"max_length" : 3.01}
59 },
60 "orbit_specs" : [
61 {
62 "coordinate_mode" : "Direct",
63 "prototype" : [
64 [ 0.000000000000, 0.000000000000, 0.000000000000 ],
65 [ 1.000000000000, 0.000000000000, 0.000000000000 ],
66 [ 2.000000000000, 0.000000000000, 0.000000000000 ],
67 [ 3.000000000000, 0.000000000000, 0.000000000000 ]
68 ],
69 "include_subclusters" : true
70 },
71 {
72 "coordinate_mode" : "Direct",
73 "prototype" : [
74 [ 0.000000000000, 0.000000000000, 0.000000000000 ],
75 [ 0.000000000000, 1.000000000000, 0.000000000000 ],
76 [ 0.000000000000, 0.000000000000, 1.000000000000 ],
77 [ 1.000000000000, 1.000000000000, 1.000000000000 ]
78 ],
79 "include_subclusters" : true
80 }
81 ]
82 })";
83 
84  return jsonParser::parse(str);
85 
86  }
87 
88  std::string invalid_bspecs() const {
89 
90  std::string str = R"({
91 "basis_functions" : {
92 "site_basis_functions" : "occupation"
93 },
94 "orbit_branch_specs" : {
95 "2" : {"max_length" : 4.01},
96 "3" : {"max_length" : 3.01}
97 },
98 "orbit_specs" : [
99 {
100 "coordinate_mode" : "Direct",
101 "prototype" : [
102 [ 0.000000000000, 0.000000000000, 0.000000000000 ],
103 [ 1.000000000000, 0.000000000000, 0.000000000000 ],
104 [ 2.000000000000, 0.000000000000, 0.000000000000 ],
105 [ 3.000000000000, 0.000000000000, 0.000000000000 ],
106 ],
107 "include_subclusters" : true
108 },
109 {
110 "coordinate_mode" : "Direct",
111 "prototype" : [
112 [ 0.000000000000, 0.000000000000, 0.000000000000 ],
113 [ 0.000000000000, 1.000000000000, 0.000000000000 ],
114 [ 0.000000000000, 0.000000000000, 1.000000000000 ],
115 [ 1.000000000000, 1.000000000000, 1.000000000000 ]
116 ],
117 "include_subclusters" : true
118 }
119 ]
120 })";
121 
122  return str;
123 
124  }
125 
127  void check_symmetry() override {
128  _check_symmetry(48, 10, 48, 10, 48, 10, "Oh", "Oh");
129  }
130 
131  void check_composition() override {
132  std::vector<std::string> axes = {
133  R"(\s+0\s+A\s+B\s+C\s+A\(1-a-b\)B\(a\)C\(b\))",
134  R"(\s+1\s+B\s+A\s+C\s+A\(a\)B\(1-a-b\)C\(b\))",
135  R"(\s+2\s+C\s+A\s+B\s+A\(a\)B\(b\)C\(1-a-b\))"
136  };
137 
138  _check_composition_axes(axes.begin(), axes.end());
139  }
140 
143  void check_bset() override {
144 
145  // check for failure with bspecs with invalid JSON
146  fs::ofstream file(dir / "basis_sets" / "bset.default" / "bspecs.json");
147  file << invalid_bspecs() << "\n";
148  file.close();
149  m_p.popen(cd_and() + "ccasm bset -u");
150  BOOST_CHECK_MESSAGE(m_p.exit_code() == 4, m_p.gets());
151 
152  // check for success with a valid bspecs
153  bspecs().write(dir / "basis_sets" / "bset.default" / "bspecs.json");
154 
155  m_p.popen(cd_and() + "ccasm bset -u");
156  BOOST_CHECK_MESSAGE(m_p.exit_code() == 0, m_p.gets());
157 
158  BOOST_CHECK_MESSAGE(boost::regex_search(m_p.gets(), m_match, boost::regex(R"(write:.*clust\.json)")) == true, m_p.gets());
159  BOOST_CHECK_MESSAGE(boost::regex_search(m_p.gets(), m_match, boost::regex(R"(write:.*basis\.json)")) == true, m_p.gets());
160  BOOST_CHECK_MESSAGE(boost::regex_search(m_p.gets(), m_match, boost::regex(R"(write:.*)" + title + R"(_Clexulator\.cc)")) == true, m_p.gets());
161 
162  BOOST_CHECK_MESSAGE(true == fs::exists(m_dirs.clust(m_set->default_clex().bset)), m_p.gets());
163  BOOST_CHECK_MESSAGE(true == fs::exists(m_dirs.clexulator_src(m_set->name(), m_set->default_clex().bset)), m_p.gets());
164 
165  std::string str;
166 
167  // check that 5 branches are created (null - 4-pt)
168  // check that --orbits, --clusters, --functions all execute
169  // (derived Proj would have to check the actual results)
170  std::string pattern = R"(\*\* Branch [0-9]+ \*\*)";
171  boost::regex re(pattern);
172 
173  std::vector<std::string> checks = {
174  "ccasm bset --orbits",
175  "ccasm bset --clusters",
176  "ccasm bset --functions"
177  };
178 
179  for(auto it = checks.begin(); it != checks.end(); ++it) {
180  m_p.popen(cd_and() + *it);
181  str = m_p.gets();
182 
183  auto begin = boost::sregex_iterator(str.begin(), str.end(), re);
184  auto end = boost::sregex_iterator();
185  auto count = std::distance(begin, end);
186 
187  BOOST_CHECK_MESSAGE(count == 5, m_p.gets());
188  }
189 
190  // check that you can't overwrite without using -f
191  m_p.popen(cd_and() + "ccasm bset -u");
192  BOOST_CHECK_EQUAL(m_p.exit_code(), 6);
193 
194  m_p.popen(cd_and() + "ccasm bset -uf");
195  BOOST_CHECK_EQUAL(m_p.exit_code(), 0);
196 
197  }
198 
200  void check_enum() override {
201 
202  {
203  m_p.popen(cd_and() + "ccasm enum --method ScelEnum --max 10");
204  std::stringstream ss;
205  Log log(ss);
206  PrimClex primclex(dir, log);
207  BOOST_CHECK_MESSAGE(primclex.get_supercell_list().size() == 87, m_p.gets());
208  }
209 
210  {
211  m_p.popen(cd_and() + "ccasm enum --method ConfigEnumAllOccupations --max 6");
212  std::stringstream ss;
213  Log log(ss);
214  PrimClex primclex(dir, log);
215  BOOST_CHECK_MESSAGE(std::distance(primclex.config_begin(), primclex.config_end()) == 1081, m_p.gets());
216  }
217  }
218 
219  };
220 
221 }
222 
223 #endif
boost::container::stable_vector< Supercell > & get_supercell_list()
Access entire supercell_list.
Definition: PrimClex.cc:299
void check_symmetry() override
Check symmetry.
void check_composition() override
Check "casm composition".
void push_back(const T &toPush)
Definition: Array.hh:513
void check_bset() override
Uses bspecs() and checks that 5 branches are generated, and that –orbits, –clusters, and –functions run without error.
PrimClex * primclex
Definition: settings.cc:101
Definition: Common.hh:7
Main CASM namespace.
Definition: complete.cpp:8
Log & log
Definition: settings.cc:105
Molecule make_atom(std::string atom_name, const Lattice &lat)
Return an atomic Molecule with specified name and Lattice.
Definition: Molecule.cc:279
config_iterator config_begin()
Configuration iterator: begin.
Definition: PrimClex.cc:371
config_iterator config_end()
Configuration iterator: end.
Definition: PrimClex.cc:379
fs::path proj_dir(fs::path init)
Create a new project directory, appending ".(#)" to ensure it is a new project.
Represents cartesian and fractional coordinates.
Definition: Coordinate.hh:34
BasicStructure< Site > FCC_ternary_prim()
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
void check_enum() override
Check "ccasm enum".
std::string invalid_bspecs() const
Eigen::Matrix3d Matrix3d
DirectoryStructure & dir
Definition: settings.cc:102
static jsonParser parse(const std::string &str)
Construct a jsonParser from a string containing JSON data.
Definition: jsonParser.hh:312
static jsonParser bspecs()
Definition: Log.hh:9