19 namespace DoFSpace_impl {
24 std::optional<std::set<Index>>
const &sites) {
26 std::stringstream msg;
27 msg <<
"Error: local DoF '" << dof_key
28 <<
"' require transformation_matrix_to_super and sites" << std::endl;
29 throw std::runtime_error(msg.str());
35 std::vector<PermuteIterator>
const &group,
bool calc_wedges,
36 std::optional<VectorSpaceSymReport> &symmetry_report) {
39 bool include_va =
false;
44 CASM::err_log() <<
"transformation_matrix_to_super:" << std::endl;
53 std::optional<std::string> identifier;
54 std::optional<ConfigEnumInput> input_state;
55 to_json(dof_space, dof_space_json, identifier, input_state, symmetry_report);
61 << dof_space.
basis() << std::endl;
62 if (symmetry_report.has_value()) {
64 << symmetry_report->symmetry_adapted_dof_subspace.cols()
66 CASM::err_log() <<
"symmetry_adapted_dof_subspace: " << std::endl
67 << symmetry_report->symmetry_adapted_dof_subspace
70 for (
auto const &irrep : symmetry_report->irreps) {
71 CASM::err_log() <<
"irrep[" << i <<
"].trans_mat: " << std::endl;
81 std::vector<PermuteIterator>
const &group,
bool calc_wedges,
82 std::optional<SymRepTools_v2::VectorSpaceSymReport> &symmetry_report) {
85 bool include_va =
false;
90 CASM::err_log() <<
"transformation_matrix_to_super:" << std::endl;
99 std::optional<std::string> identifier;
100 std::optional<ConfigEnumInput> input_state;
101 to_json(dof_space, dof_space_json, identifier, input_state, symmetry_report);
107 << dof_space.
basis() << std::endl;
108 if (symmetry_report.has_value()) {
110 << symmetry_report->symmetry_adapted_subspace.cols()
112 CASM::err_log() <<
"symmetry_adapted_dof_subspace: " << std::endl
113 << symmetry_report->symmetry_adapted_subspace << std::endl;
115 for (
auto const &irrep : symmetry_report->irreps) {
116 CASM::err_log() <<
"irrep[" << i <<
"].trans_mat: " << std::endl;
142 std::shared_ptr<Structure const>
const &_shared_prim,
144 std::optional<Eigen::Matrix3l>
const &_transformation_matrix_to_super,
145 std::optional<std::set<Index>>
const &_sites,
146 std::optional<Eigen::MatrixXd>
const &_basis)
147 : m_shared_prim(_shared_prim),
149 m_transformation_matrix_to_super(_transformation_matrix_to_super),
156 std::stringstream msg;
157 msg <<
"Error constructing DoFSpace: Local DoF '" <<
m_dof_key
158 <<
"' requires transformation_matrix_to_super." << std::endl;
159 throw std::runtime_error(msg.str());
174 if (!_basis.has_value()) {
180 if (
m_basis.rows() != dof_space_dimension) {
181 std::stringstream msg;
182 msg <<
"Error constructing DoFSpace: # basis rows (" <<
m_basis.rows()
183 <<
") != expected dimension (" << dof_space_dimension <<
").";
184 throw std::runtime_error(msg.str());
187 std::stringstream msg;
188 msg <<
"Error constructing DoFSpace: # basis columns (" <<
m_basis.cols()
189 <<
") > expected dimension (" <<
m_basis.rows() <<
").";
190 throw std::runtime_error(msg.str());
263 if (
config.supercell().sym_info().transformation_matrix_to_super() !=
275 std::stringstream msg;
276 msg <<
"Error: DoFSpace is not valid for given configuration." << std::endl;
277 throw std::runtime_error(msg.str());
286 using namespace DoFSpace_impl;
289 auto const &dof_key = dof_space.
dof_key();
290 auto const &basis = dof_space.
basis();
293 auto const &dof_values =
config.configdof().global_dof(dof_key).values();
294 return basis.colPivHouseholderQr().solve(dof_values);
296 if (dof_key ==
"occ") {
297 auto const &dof_values =
config.configdof().occupation().cast<
double>();
298 return basis.colPivHouseholderQr().solve(dof_values);
302 config.configdof().local_dof(dof_key).values();
307 for (
Index i = 0; i < dof_space.
dim(); ++i) {
309 matrix_values(axis_dof_component[i], axis_site_index[i]);
311 return basis.colPivHouseholderQr().solve(vector_values);
319 using namespace DoFSpace_impl;
323 std::stringstream msg;
324 msg <<
"Error in set_dof_value: normal coordinate size ("
327 throw std::runtime_error(msg.str());
330 auto const &dof_key = dof_space.
dof_key();
331 auto const &basis = dof_space.
basis();
336 if (dof_key ==
"occ") {
337 std::stringstream msg;
338 msg <<
"Error: set_dof_value is not supported for occupation."
340 throw std::runtime_error(msg.str());
343 auto &local_dof =
config.configdof().local_dof(dof_key);
350 for (
Index i = 0; i < dof_space.
dim(); ++i) {
351 matrix_values(axis_dof_component[i], axis_site_index[i]) =
355 local_dof.set_values(matrix_values);
362 std::optional<std::set<Index>>
const &sites) {
366 using namespace DoFSpace_impl;
372 Index dof_space_dimension = 0;
373 for (
Index site_index : *sites) {
374 Index sublattice_index =
375 unitcellcoord_index_converter(site_index).sublattice();
377 if (dof_key ==
"occ") {
379 }
else if (site.
has_dof(dof_key)) {
380 dof_space_dimension += site.
dof(dof_key).
dim();
383 return dof_space_dimension;
391 std::optional<std::set<Index>>
const &sites) {
392 std::vector<std::string> axis_glossary;
398 using namespace DoFSpace_impl;
405 for (
Index site_index : *sites) {
406 Index sublattice_index =
407 unitcellcoord_index_converter(site_index).sublattice();
409 if (dof_key ==
"occ") {
412 "][" + molecule.name() +
"]");
414 }
else if (site.
has_dof(dof_key)) {
415 std::vector<std::string> tdescs =
417 for (std::string
const &
desc : tdescs) {
422 if (!site.
has_dof(dof_key))
continue;
425 return axis_glossary;
432 std::optional<std::set<Index>>
const &sites,
433 std::vector<std::string> &axis_glossary,
434 std::optional<std::vector<Index>> &axis_site_index,
435 std::optional<std::vector<Index>> &axis_dof_component) {
437 axis_glossary.clear();
438 axis_site_index = std::nullopt;
439 axis_dof_component = std::nullopt;
444 using namespace DoFSpace_impl;
448 axis_glossary.clear();
449 axis_site_index = std::vector<Index>();
450 axis_dof_component = std::vector<Index>();
455 for (
Index site_index : *sites) {
456 Index sublattice_index =
457 unitcellcoord_index_converter(site_index).sublattice();
459 if (dof_key ==
"occ") {
463 "][" + molecule.name() +
"]");
464 axis_dof_component->push_back(i);
465 axis_site_index->push_back(site_index);
468 }
else if (site.
has_dof(dof_key)) {
469 std::vector<std::string> tdescs =
472 for (std::string
const &
desc : tdescs) {
475 axis_dof_component->push_back(i);
476 axis_site_index->push_back(site_index);
480 if (!site.
has_dof(dof_key))
continue;
488 std::optional<Eigen::MatrixXd>
const &basis) {
491 return DoFSpace(supercell.shared_prim(), dof_key,
492 supercell.sym_info().transformation_matrix_to_super(),
493 input_state.
sites(), basis);
515 std::vector<PermuteIterator>
const &group,
531 for (
Index i = 0; i < pointgroup.size(); ++i) {
532 Index fg_ix = pointgroup[i].index();
539 if (!dof_space.
sites().has_value()) {
540 throw std::runtime_error(
541 "Error in make_dof_space_symrep: Local DoF, but no sites");
544 sym_info, dof_key, group);
545 g = group_and_ID.first;
547 id = group_and_ID.second;
562 std::vector<PermuteIterator>
const &group,
bool calc_wedges) {
587 std::vector<PermuteIterator>
const &group,
bool calc_wedges) {
606 std::vector<PermuteIterator>
const &group,
bool calc_wedges,
607 std::optional<VectorSpaceSymReport> &symmetry_report) {
608 using namespace DoFSpace_impl;
613 }
catch (std::exception &e) {
614 error_report(dof_space, sym_info, group, calc_wedges, symmetry_report);
615 CASM::err_log() <<
"Error constructing vector space symmetry report: "
616 << e.what() << std::endl;
620 if (symmetry_report->symmetry_adapted_dof_subspace.cols() <
621 dof_space.
basis().cols()) {
622 error_report(dof_space, sym_info, group, calc_wedges, symmetry_report);
623 std::stringstream msg;
624 msg <<
"Error in make_symmetry_adapted_dof_space: "
625 <<
"symmetry_adapted_dof_subspace.cols() < dof_space.basis().cols()";
631 symmetry_report->symmetry_adapted_dof_subspace);
637 std::vector<PermuteIterator>
const &group,
bool calc_wedges,
638 std::optional<SymRepTools_v2::VectorSpaceSymReport> &symmetry_report) {
639 using namespace DoFSpace_impl;
644 }
catch (std::exception &e) {
645 error_report_v2(dof_space, sym_info, group, calc_wedges, symmetry_report);
646 CASM::err_log() <<
"Error constructing vector space symmetry report: "
647 << e.what() << std::endl;
651 if (symmetry_report->symmetry_adapted_subspace.cols() <
652 dof_space.
basis().cols()) {
653 error_report_v2(dof_space, sym_info, group, calc_wedges, symmetry_report);
654 std::stringstream msg;
655 msg <<
"Error in make_symmetry_adapted_dof_space_v2: "
656 <<
"symmetry_adapted_subspace.cols() < dof_space.basis().cols()";
662 symmetry_report->symmetry_adapted_subspace);
676 std::stringstream msg;
677 msg <<
"Error in exclude_homogeneous_mode_space: Must be a DoF space for a "
678 "local continuous degrees of freedom that includes all sites in the "
680 throw std::runtime_error(msg.str());
743 std::stringstream msg;
744 msg <<
"Error in make_homogeneous_mode_space: Must be a DoF space for a "
745 "local continuous degrees of freedom that includes all sites in the "
747 throw std::runtime_error(msg.str());
750 auto const &dof_key = dof_space.
dof_key();
753 auto const &sites = *dof_space.
sites();
756 std::vector<DoFSetInfo> prim_dof_info =
local_dof_info(prim)[dof_key];
759 std::vector<DoFSetInfo> sites_dof_info;
764 for (
Index l : sites) {
765 Index b = l_to_bijk(l).sublattice();
768 sites_dof_info.push_back(prim_dof_info[b]);
776 int standard_basis_dim = prim_dof_info[0].basis().rows();
780 for (
auto const &sublat_dof : prim_dof_info) {
781 prod = sublat_dof.basis() * sublat_dof.inv_basis() * prod;
785 (prod - I).transpose().fullPivLu().kernel();
787 if (common_standard_basis.isZero(
TOL)) {
788 return Eigen::MatrixXd::Zero(dof_space.
basis().rows(), 0);
794 common_standard_basis.cols()};
798 for (
auto const &site_dof : sites_dof_info) {
799 auto const &values = site_dof.inv_basis() * common_standard_basis;
800 int n_rows = values.rows();
801 int n_cols = values.cols();
802 homogeneous_mode_space.block(row, col, n_rows, n_cols) = values;
803 row += site_dof.dim();
806 return homogeneous_mode_space;
816 for (
Index i = 0; i < column_vector_space.cols(); ++i) {
817 Eigen::VectorXd col_projection = proj_operator * column_vector_space.col(i);
818 if (col_projection.isZero(tol)) {
821 column_vector_space.col(i).normalized(),
Specifies traits of (possibly) anisotropic crystal properties.
bool global() const
Returns true if type is global.
const Supercell & supercell() const
Get the Supercell for this Configuration.
Index dim() const
Dimension of the DoFSet, equivalent to basis().cols()
std::vector< std::string > m_axis_glossary
Names the DoF corresponding to each dimension (row) of the basis.
Eigen::MatrixXd const & basis() const
std::optional< std::vector< Index > > const & axis_site_index() const
Index subspace_dim() const
The DoF subspace dimension (equal to number of columns in basis).
bool includes_all_sites() const
True, if local DoF space with all sites in the supercell included.
std::optional< Eigen::Matrix3l > const & transformation_matrix_to_super() const
Specifies the supercell for a local DoF space. Has value for local DoF.
std::optional< std::vector< Index > > const & axis_dof_component() const
DoFSpace(std::shared_ptr< Structure const > const &_shared_prim, DoFKey const &_dof_key, std::optional< Eigen::Matrix3l > const &_transformation_matrix_to_super=std::nullopt, std::optional< std::set< Index >> const &_sites=std::nullopt, std::optional< Eigen::MatrixXd > const &_basis=std::nullopt)
std::optional< std::set< Index > > const & sites() const
The sites included in a local DoF space. Has value for local DoF.
std::shared_ptr< Structure const > const & shared_prim() const
Shared prim structure.
std::vector< std::string > const & axis_glossary() const
Names the DoF corresponding to each dimension (row) of the basis.
std::shared_ptr< Structure const > m_shared_prim
Shared prim structure.
std::optional< std::vector< Index > > m_axis_dof_component
std::optional< Eigen::Matrix3l > m_transformation_matrix_to_super
Specifies the supercell for a local DoF space. Required for local DoF.
std::optional< std::set< Index > > m_sites
The sites included in a local DoF space. Required for local DoF.
Index dim() const
The DoF space dimension (equal to number of rows in basis).
DoFKey const & dof_key() const
std::optional< std::vector< Index > > m_axis_site_index
SymGroupRepID allocate_representation() const
Add a new empty representation.
void set_rep(SymGroupRepID _rep_ID, SymOpRepresentation const &_op_rep, Index op_index) const
void is_temporary_of(MasterSymGroup const &RHS)
SymGroupRep const & representation(SymGroupRepID i) const
Const access of alternate Representations of a SymGroup.
A class that collects all symmetry information for for performing symmetry transformations on the sit...
SymGroup const & factor_group() const
Subgroup of primitive-cell factor group operations that leave supercell lattice invariant.
const xtal::Lattice & supercell_lattice() const
const reference to supercell lattice
Eigen::Matrix3l transformation_matrix_to_super() const
long-int transformation from primitive lattice vectors to supercell lattice vectors supercell_lattice...
SymGroupRep::RemoteHandle const & global_dof_symrep(DoFKey const &_key) const
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
SymGroupRep const * rep_ptr() const
SymGroupRep is an alternative representation of a SymGroup for something other than real space....
Type-safe ID object for communicating and accessing Symmetry representation info.
BasicStructure specifies the lattice and atomic basis of a crystal.
std::map< DoFKey, DoFSet > const & global_dofs() const
DoFSet const & global_dof(std::string const &dof_type) const
const std::vector< Site > & basis() const
bool has_dof(std::string const &_dof_type) const
const std::vector< Molecule > & occupant_dof() const
SiteDoFSet const & dof(std::string const &_dof_type) const
Index total_sites() const
Returns the total number of sites within the superlattice.
std::string to_string(ENUM val)
Return string representation of enum class.
std::set< Index > const & sites() const
Configuration const & configuration() const
MasterSymGroup make_master_sym_group(SymGroup const &_group, Lattice const &_lattice)
Generic1DDatumFormatter< Eigen::VectorXd, ConfigEnumDataType > normal_coordinate()
ConfigIO::GenericConfigFormatter< jsonParser > config()
void throw_if_missing_local_dof_requirements(DoFKey const &dof_key, std::optional< Eigen::Matrix3l > const &transformation_matrix_to_super, std::optional< std::set< Index >> const &sites)
void error_report_v2(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges, std::optional< SymRepTools_v2::VectorSpaceSymReport > &symmetry_report)
Print information in case constructing VectorSpaceSymReport fails.
void error_report(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges, std::optional< VectorSpaceSymReport > &symmetry_report)
Print information in case constructing VectorSpaceSymReport fails.
IdentitySymRepBuilder Identity()
std::vector< std::string > component_descriptions(DoFSet const &dofset)
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
void set_dof_value(Configuration &config, DoFSpace const &dof_space, Eigen::VectorXd const &normal_coordinate)
Set config DoF value from a coordinate in the DoFSpace basis.
VectorSpaceSymReport vector_space_sym_report(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges=false)
Make VectorSpaceSymReport.
Eigen::VectorXd get_normal_coordinate(Configuration const &config, DoFSpace const &dof_space)
Return config DoF value as a coordinate in the DoFSpace basis.
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
std::pair< MasterSymGroup, SymGroupRepID > make_collective_dof_symrep(std::set< Index > const &site_indices, SupercellSymInfo const &_syminfo, DoFKey const &_key, std::vector< PermuteIterator > const &_group)
Make the matrix representation for group '_group' describing the transformation of DoF '_key' among a...
DoFSpace exclude_homogeneous_mode_space(DoFSpace const &dof_space)
Removes the homogeneous mode space from the DoFSpace basis.
DoFSpace make_dof_space(DoFKey dof_key, ConfigEnumInput const &input_state, std::optional< Eigen::MatrixXd > const &basis=std::nullopt)
void write_prim(const xtal::BasicStructure &prim, fs::path filename, COORD_TYPE mode, bool include_va=false)
Write prim.json to file.
std::string brief_description(const SymOp &op, const xtal::Lattice &lat, SymInfoOptions opt=SymInfoOptions())
Print SymInfo to brief string.
Index get_dof_space_dimension(DoFKey dof_key, xtal::BasicStructure const &prim, std::optional< Eigen::Matrix3l > const &transformation_matrix_to_super=std::nullopt, std::optional< std::set< Index >> const &sites=std::nullopt)
Return dimension of DoFSpace.
std::vector< std::string > make_axis_glossary(DoFKey dof_key, xtal::BasicStructure const &prim, std::optional< Eigen::Matrix3l > const &transformation_matrix_to_super, std::optional< std::set< Index >> const &sites)
The axis_glossary gives names to an un-symmetrized coordinate system.
void make_dof_space_axis_info(DoFKey dof_key, xtal::BasicStructure const &prim, std::optional< Eigen::Matrix3l > const &transformation_matrix_to_super, std::optional< std::set< Index >> const &sites, std::vector< std::string > &axis_glossary, std::optional< std::vector< Index >> &axis_site_index, std::optional< std::vector< Index >> &axis_dof_component)
Make DoFSpace axis glossary, axis site index, and axis dof component.
SymGroupRep const & make_dof_space_symrep(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, MasterSymGroup &symrep_master_group, SymGroupRepID &id)
Make a SymGroupRep for a DoFSpace.
SymRepTools_v2::VectorSpaceSymReport vector_space_sym_report_v2(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges=false)
Make VectorSpaceSymReport.
void throw_if_invalid_dof_space(Configuration const &config, DoFSpace const &dof_space)
Throw if !is_valid_dof_space(config, dof_space)
bool is_valid_dof_space(Configuration const &config, DoFSpace const &dof_space)
Eigen::MatrixXd make_homogeneous_mode_space(DoFSpace const &dof_space)
Make the homogeneous mode space of a local DoFSpace.
DoFSpace make_symmetry_adapted_dof_space(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges, std::optional< VectorSpaceSymReport > &symmetry_report)
Make DoFSpace with symmetry adapated basis.
std::map< DoFKey, std::vector< CASM::DoFSetInfo > > local_dof_info(Structure const &_struc)
INDEX_TYPE Index
For long integer indexing:
DoFSpace make_symmetry_adapted_dof_space_v2(DoFSpace const &dof_space, SupercellSymInfo const &sym_info, std::vector< PermuteIterator > const &group, bool calc_wedges, std::optional< SymRepTools_v2::VectorSpaceSymReport > &symmetry_report)
Make DoFSpace with symmetry adapated basis.
SymGroup make_point_group(const PermuteIteratorContainer &container, const Lattice &supercell_lattice)
Returns a SymGroup generated from a container of PermuteIterator.
Options for printing SymInfo.
std::vector< Index > axes_not_in_subspace
bool are_axes_mixed_with_subspace
std::vector< Index > axes_in_subspace
VectorSpaceMixingInfo(Eigen::MatrixXd const &column_vector_space, Eigen::MatrixXd const &subspace, double tol)
std::vector< Index > axes_mixed_with_subspace
Summary of data associated with the action of a symmetry group on a vector space.
std::vector< std::string > axis_glossary
Names given to individual axes in initial (un-adapted) vector space, corresponding to rows of symmetr...