7 double pretty(
double value,
double tol) {
8 double pretty_value = value;
9 if (std::abs(value) < tol) {
12 if (std::abs(
std::round(value) - value) < tol) {
23 clex_basis(_clex_basis),
28 if (dofset.first !=
"occ" &&
bset.size() &&
29 bset[0]->type_name() !=
"Variable") {
31 bset.name(),
"\\phi^{(" + dofset.first +
")}_{%n,%l}"));
40 std::string indent(indent_space,
' ');
42 std::ostream nullstream(0);
44 std::vector<Orbit<PrimPeriodicSymCompare<IntegralCluster>>> asym_unit;
45 make_prim_periodic_asymmetric_unit(prim_ptr,
47 std::back_inserter(asym_unit), nullstream);
51 for (
auto const &dofset : clex_basis.
site_bases()) {
52 out <<
"Site basis functions for DoF \"" << dofset.first <<
"\":\n\n";
53 for (
Index no = 0; no < asym_unit.size(); no++) {
54 out <<
"Asymmetric unit " << no + 1 <<
":\n";
55 for (
Index ne = 0; ne < asym_unit[no].size(); ne++) {
56 Index b = asym_unit[no][ne][0].sublattice();
57 out << indent <<
"Basis site " << b <<
": ";
59 out << asym_unit[no][ne][0] <<
' ';
61 asym_unit[no][ne][0].site(prim).occupant_dof(), out);
64 asym_unit[no][ne][0].site(prim).
print(out);
67 if (dofset.second[b].size() == 0)
68 out << indent <<
"[No site basis functions]\n\n";
69 if (dofset.first ==
"occ") {
71 std::vector<std::vector<std::string>> funcstrs;
72 for (
Index f = 0; f < dofset.second[b].size(); f++) {
73 funcstrs.push_back(std::vector<std::string>());
79 std::vector<DoF::RemoteHandle> remote(
84 for (
s = 0;
s < prim.
basis()[b].occupant_dof().size();
s++) {
86 ss <<
"\\phi_{" << b <<
"," << f <<
"}["
87 << prim.
basis()[b].occupant_dof()[
s].name()
88 <<
"] = " <<
pretty(tbasis[f]->remote_eval(), 1e-10);
89 if (
s + 1 != prim.
basis()[b].occupant_dof().size()) ss <<
",";
90 funcstrs[f].push_back(ss.str());
91 if (ss.str().size() > max_length) {
92 max_length = ss.str().size();
96 for (
auto const &sublat_funcstrs : funcstrs) {
97 out << indent << indent;
98 for (
auto const &funcstr : sublat_funcstrs) {
99 out << std::setw(max_length + 3) << std::left << funcstr;
107 for (
Index f = 0; f < dofset.second[b].size(); f++) {
108 if (dofset.second[b][f]) {
109 out << indent << indent;
110 if (dofset.second[b][f]->type_name() !=
"Variable") {
111 out <<
"\\phi^{" << (dofset.first) <<
"}_{" << b <<
"," << f
114 out << dofset.second[b][f]->tex_formula() <<
"\n";
121 out << std::endl << std::endl;
129 if (!cluster.
size()) {
134 out <<
"Prototype cluster sites (Fractional coordinates):\n\n";
135 }
else if (mode ==
CART) {
136 out <<
"Prototype cluster sites (Cartesian coordinates):\n\n";
138 out <<
"Prototype cluster sites (Integral coordinates):\n\n";
143 out <<
"\\vspace{2mm}\n"
144 <<
"\\begin{tabular}{rrrrrr}\n"
147 out <<
"site index & basis index & u & v & w & occupants \\\\\n";
148 }
else if (mode ==
CART) {
149 out <<
"site index & basis index & x & y & z & occupants \\\\\n";
151 out <<
"site index & basis index & i & j & k & occupants \\\\\n";
156 for (
Index site_index = 0; site_index < cluster.
size(); site_index++) {
157 Index b = cluster[site_index].sublattice();
158 Site const &site = cluster[site_index].site(prim);
160 std::stringstream occupants_ss;
162 std::string occupants = occupants_ss.str();
165 Eigen::Vector3d frac = site.
frac();
166 out << site_index <<
" & " << b <<
" & " << frac(0) <<
" & " << frac(1)
167 <<
" & " << frac(2) <<
" & " << occupants <<
" \\\\\n";
168 }
else if (mode ==
CART) {
169 Eigen::Vector3d cart = site.
cart();
170 out << site_index <<
" & " << b <<
" & " << cart(0) <<
" & " << cart(1)
171 <<
" & " << cart(2) <<
" & " << occupants <<
" \\\\\n";
173 UnitCell ijk = cluster[site_index].unitcell();
174 out << site_index <<
" & " << b <<
" & " << ijk(0) <<
" & " << ijk(1)
175 <<
" & " << ijk(2) <<
" & " << occupants <<
" \\\\\n";
179 <<
"\\end{tabular}\n"
180 <<
"\\vspace{2mm}\n\n";
185 void print_tex_tabular_asym_unit(
186 Log &out, Orbit<PrimPeriodicSymCompare<IntegralCluster>>
const &orbit,
189 out <<
"Sites (Fractional coordinates):\n\n";
190 }
else if (mode ==
CART) {
191 out <<
"Sites (Cartesian coordinates):\n\n";
193 out <<
"Sites (Integral coordinates):\n\n";
198 out <<
"\\vspace{2mm}\n"
199 <<
"\\begin{tabular}{rrrrr}\n"
202 out <<
"basis index & u & v & w & occupants \\\\\n";
203 }
else if (mode ==
CART) {
204 out <<
"basis index & x & y & z & occupants \\\\\n";
206 out <<
"basis index & i & j & k & occupants \\\\\n";
211 for (
Index ne = 0; ne < orbit.size(); ne++) {
212 Index b = orbit[ne][0].sublattice();
213 Site
const &site = orbit[ne][0].site(prim);
215 std::stringstream occupants_ss;
217 std::string occupants = occupants_ss.str();
220 Eigen::Vector3d frac = site.frac();
221 out << b <<
" & " << frac(0) <<
" & " << frac(1) <<
" & " << frac(2)
222 <<
" & " << occupants <<
" \\\\\n";
223 }
else if (mode ==
CART) {
224 Eigen::Vector3d cart = site.cart();
225 out << b <<
" & " << cart(0) <<
" & " << cart(1) <<
" & " << cart(2)
226 <<
" & " << occupants <<
" \\\\\n";
228 UnitCell ijk = orbit[ne][0].unitcell();
229 out << b <<
" & " << ijk(0) <<
" & " << ijk(1) <<
" & " << ijk(2) <<
" & "
230 << occupants <<
" \\\\\n";
234 <<
"\\end{tabular}\n"
235 <<
"\\vspace{2mm}\n\n";
238 void print_tex_tabular_basis(Log &out, xtal::DoFSet
const &dofset,
239 BasisSet
const &basis_set) {
240 Index dim = dofset.dim();
241 Index standard_dim = dofset.basis().rows();
253 out <<
"\\vspace{2mm}\n"
254 <<
"\\begin{tabular}{rcc" << std::string(standard_dim,
'r') <<
"c}\n";
257 out <<
" axis name & & & ";
258 for (
Index i = 0; i < standard_dim; ++i) {
259 out <<
"$" << dofset.traits().standard_var_names()[i] <<
"$ & ";
263 for (
Index i = 0; i < dim; i++) {
264 out <<
"$" << dofset.component_names()[i] <<
"$ &=& [ & ";
266 for (
int s = 0;
s < standard_dim;
s++) {
267 out <<
pretty(dofset.basis()(
s, i), 1e-10) <<
" & ";
277 out <<
"\\end{tabular}\n"
278 <<
"\\vspace{2mm}\n\n";
281 void print_tex_tabular_occ_basis_funcs(Log &out, Site
const &site,
282 BasisSet
const &basis_set,
Index b) {
283 Index occ_dof_size = site.occupant_dof().size();
293 out <<
"\\vspace{2mm}\n"
294 <<
"\\begin{tabular}{rcc" << std::string(occ_dof_size,
'r') <<
"c}\n";
298 for (
Index i = 0; i < occ_dof_size; ++i) {
299 out << site.occupant_dof()[i].name() <<
" & ";
304 for (
Index f = 0; f < basis_set.size(); f++) {
305 out <<
"$\\phi_{" << b <<
"," << f <<
"}$ &=& [ & ";
308 BasisSet tbasis(basis_set);
310 std::vector<DoF::RemoteHandle> remote(1, DoF::RemoteHandle(
"occ",
"s", b));
312 tbasis.register_remotes(remote);
313 for (
s = 0;
s < occ_dof_size;
s++) {
314 out <<
pretty(tbasis[f]->remote_eval(), 1e-10) <<
" & ";
318 if (f + 1 != basis_set.size()) {
324 out <<
"\\end{tabular}\n"
325 <<
"\\vspace{2mm}\n\n";
328 void print_site_basis_set(Log &out, std::string dof_key,
329 BasisSet
const &basis_set,
Index sublattice_index) {
330 Index dim = basis_set.size();
332 Index n_functions = 0;
333 for (
Index f = 0; f < dim; f++) {
334 if (basis_set[f]->
type_name() !=
"Variable") {
340 out <<
"\\begin{align*}\n";
342 for (
Index f = 0; f < dim; f++) {
344 if (basis_set[f]->
type_name() !=
"Variable") {
345 out <<
"\\phi^{" << dof_key <<
"}_{" << sublattice_index <<
"," << f
348 out << basis_set[f]->tex_formula() <<
"\n";
354 out <<
"\\end{align*}\n\n";
358 void print_global_basis_set(Log &out, std::string dof_key,
359 BasisSet
const &basis_set) {
360 Index dim = basis_set.size();
362 Index n_functions = 0;
363 for (
Index f = 0; f < dim; f++) {
364 if (basis_set[f]->
type_name() !=
"Variable") {
370 out <<
"\\begin{align}\n";
372 for (
Index f = 0; f < dim; f++) {
374 if (basis_set[f]->
type_name() !=
"Variable") {
375 out <<
"\\phi^{" << dof_key <<
"}_{" << f <<
"} = ";
377 out << basis_set[f]->tex_formula() <<
"\n";
383 out <<
"\\end{align}\n\n";
393 std::string indent(indent_space,
' ');
395 std::ostream nullstream(0);
397 std::vector<Orbit<PrimPeriodicSymCompare<IntegralCluster>>> asym_unit;
398 make_prim_periodic_asymmetric_unit(prim_ptr,
400 std::back_inserter(asym_unit), nullstream);
403 for (
auto const &dofset : clex_basis.
site_bases()) {
404 out <<
"\\pagebreak\n";
405 if (dofset.first ==
"occ") {
406 out <<
"Site basis functions for DoF ``" << dofset.first <<
"\":\n\n";
408 out <<
"Site bases for DoF ``" << dofset.first <<
"\":\n\n";
410 out <<
"\\begin{itemize}\n";
412 for (
Index no = 0; no < asym_unit.size(); no++) {
413 out <<
"\\item Asymmetric unit " << no + 1 <<
":\n"
415 print_tex_tabular_asym_unit(out, asym_unit[no], prim, mode);
418 for (
Index ne = 0; ne < asym_unit[no].size(); ne++) {
419 Index b = asym_unit[no][ne][0].sublattice();
420 Site const &site = asym_unit[no][ne][0].site(prim);
422 if (dofset.second[b].size() == 0) {
423 out <<
"Basis site " << b <<
": [No site basis functions]\n\n";
425 if (dofset.first ==
"occ") {
427 out <<
"Basis site " << b <<
":\n\n";
428 print_tex_tabular_occ_basis_funcs(out, site, dofset.second[b], b);
433 site.
dofs().find(dofset.first)->second;
435 out <<
"Basis site " << b <<
":\n\n";
436 print_tex_tabular_basis(out, current_dofset, dofset.second[b]);
443 out <<
"\\end{itemize}\n\n";
447 out <<
"\\pagebreak\n";
448 out <<
"Global basis for DoF ``" << dofset.first <<
"\":\n\n";
451 for (
Index i = 0; i < dofset.second.size(); ++i) {
452 if (dofset.second.size() > 1) {
453 out <<
"Basis " << i <<
":\n\n";
459 print_tex_tabular_basis(out, current_dofset, dofset.second[i]);
482 std::ostream nullstream(0);
483 std::vector<Orbit<PrimPeriodicSymCompare<IntegralCluster>>> asym_unit;
484 make_prim_periodic_asymmetric_unit(prim_ptr,
486 std::back_inserter(asym_unit), nullstream);
489 for (
auto const &dofset : clex_basis.
site_bases()) {
490 for (
Index no = 0; no < asym_unit.size(); no++) {
491 for (
Index ne = 0; ne < asym_unit[no].size(); ne++) {
492 Index b = asym_unit[no][ne][0].sublattice();
493 sitef[b][
"sublat"] = b;
494 sitef[b][
"asym_unit"] = no;
496 if (dofset.second[b].size() == 0) {
497 sitef[b][dofset.first][
"basis"].
put_null();
501 for (
Index f = 0; f < dofset.second[b].size(); f++) {
502 std::stringstream fname;
504 if (dofset.first ==
"occ") {
505 fname <<
"\\phi_{" << b <<
"," << f <<
"}";
510 std::vector<DoF::RemoteHandle> remote(
515 for (
s = 0;
s < prim.
basis()[b].occupant_dof().size();
s++) {
516 sitef[b][dofset.first][
"basis"][fname.str()]
517 [prim.
basis()[b].occupant_dof()[
s].name()] =
518 pretty(tbasis[f]->remote_eval(), 1e-10);
521 if (dofset.second[b][f]) {
522 if (dofset.second[b][f]->type_name() !=
"Variable") {
523 fname <<
"\\phi^{" << (dofset.first) <<
"}_{" << b <<
"," << f
526 fname <<
"var_{" << b <<
"}_{" << f <<
"}";
528 sitef[b][dofset.first][
"basis"][fname.str()] =
529 dofset.second[b][f]->tex_formula();
std::set< std::string > & s
int register_remotes(const std::vector< DoF::RemoteHandle > &remote_handles)
std::map< DoFKey, std::vector< BasisSet > > const & site_bases() const
Const access to dictionary of all site BasisSets.
std::map< DoFKey, std::vector< BasisSet > > const & global_bases() const
Const access to dictionary of all global BasisSets.
size_type size() const
Number of elements in the cluster.
Structure specifies the lattice and atomic basis of a crystal.
const xtal::BasicStructure & structure() const
const std::vector< xtal::Site > & basis() const
static jsonParser object()
Returns an empty json object.
static jsonParser array()
Returns an empty json array.
jsonParser & put_null()
Puts 'null' JSON value.
BasicStructure specifies the lattice and atomic basis of a crystal.
std::map< DoFKey, DoFSet > const & global_dofs() const
COORD_MODE specifies the current coordinate mode (Fractional or Cartesian)
Coordinate_impl::CartCoordinate cart()
Set Cartesian coordinate vector and update fractional coordinate vector.
Coordinate_impl::FracCoordinate frac()
Set the fractional coordinate vector.
std::map< std::string, SiteDoFSet > const & dofs() const
const std::vector< Molecule > & occupant_dof() const
static void print_occupant_dof(const std::vector< Molecule > &allowed_occupants, std::ostream &out_stream)
Eigen::MatrixXd pretty(const Eigen::MatrixXd &M, double tol)
Round entries that are within tol of being integer to that integer value.
Eigen::CwiseUnaryOp< decltype(Local::round_l< typename Derived::Scalar >), const Derived > round(const Eigen::MatrixBase< Derived > &val)
Round Eigen::MatrixXd.
void write_site_basis_funcs(std::shared_ptr< const Structure > prim_ptr, ClexBasis const &clex_basis, jsonParser &json)
void print_tex_tabular_cluster_sites(Log &out, IntegralCluster const &cluster, xtal::BasicStructure const &prim, COORD_TYPE mode)
Print prototype cluster sites as a tex tabular.
const COORD_TYPE INTEGRAL
void print_site_basis_funcs(std::shared_ptr< const Structure > prim_ptr, ClexBasis const &clex_basis, Log &out, Index indent_space=6, COORD_TYPE mode=FRAC)
Print site basis functions, as for 'casm bset –functions'.
INDEX_TYPE Index
For long integer indexing:
void print_aligned_site_basis_funcs(std::shared_ptr< const Structure > prim_ptr, ClexBasis const &clex_basis, Log &out, Index indent_space=6, COORD_TYPE mode=FRAC)
Print aligned site basis functions, as for 'casm bset –functions –align'.
N-nary function that behaves as a constant (i.e. transform(arg1,arg2,...) == constant is true)
std::shared_ptr< const PrimType > PrimType_ptr
ClexBasis const & clex_basis
std::vector< SubExpressionLabeler > labelers
ProtoFuncsPrinter(ClexBasis const &_clex_basis, PrimType_ptr prim_ptr, bool align, OrbitPrinterOptions const &_opt=OrbitPrinterOptions())