25 struct NeighborListInfoData {
26 NeighborListInfoData(std::shared_ptr<Structure const> _shared_prim,
27 SupercellSymInfo
const &_supercell_sym_info,
28 PrimNeighborList
const &_prim_neighbor_list,
29 SuperNeighborList
const &_supercell_neighbor_list)
42 template <
typename ValueType>
43 using NeighborListInfoFormatter =
44 GenericDatumFormatter<ValueType, NeighborListInfoData>;
47 return NeighborListInfoFormatter<jsonParser>(
49 "Contains an array of unitcells, the ordered set of unitcells the make "
50 "up the neighborhood of the origin unit cell, along with the "
51 "nlist_weight_matrix and nlist_sublat_indices.",
52 [](NeighborListInfoData
const &data) -> jsonParser {
54 std::vector<UnitCell>
unitcells{data.prim_neighbor_list.begin(),
55 data.prim_neighbor_list.end()};
57 json[
"weight_matrix"] = data.prim_neighbor_list.weight_matrix();
58 json[
"sublat_indices"] = data.prim_neighbor_list.sublat_indices();
64 return NeighborListInfoFormatter<jsonParser>(
65 "supercell_neighbor_list",
66 "Contains, for each unitcell in the supercell, "
67 "`linear_unitcell_indices`, the neighborhood of unitcells, and "
68 "`linear_site_indices` the neighborhood of sites. The linear indices can "
69 "be used to lookup coordinates with the `unitcells` and "
70 "`integral_site_coordinates` properties of the supercell.",
71 [](NeighborListInfoData
const &data) -> jsonParser {
72 auto const &sym_info = data.supercell_sym_info;
73 auto const &T = sym_info.transformation_matrix_to_super();
77 auto const &scel_nlist = data.supercell_neighbor_list;
80 json[
"transformation_matrix_to_super"] = T;
81 json[
"supercell_lattice_column_matrix"] = L;
82 json[
"supercell_lattice_vectors"] = L.transpose();
84 data.shared_prim->point_group(), sym_info.prim_lattice(),
85 sym_info.supercell_lattice());
86 json[
"supercell_volume"] =
volume;
88 json[
"n_neighbor_sites"] = scel_nlist.sites(0).size();
89 json[
"n_neighbor_unitcells"] = scel_nlist.unitcells(0).size();
90 json[
"periodic_images_of_neighborhood_overlap"] = scel_nlist.overlaps();
95 json[
"linear_site_indices"].push_back(scel_nlist.sites(l));
96 json[
"linear_unitcell_indices"].push_back(scel_nlist.unitcells(l));
102 DataFormatterDictionary<NeighborListInfoData> make_neighbor_list_info_dict() {
103 DataFormatterDictionary<NeighborListInfoData> neighbor_list_info_dict;
108 return neighbor_list_info_dict;
113 struct ExpandPrimNeighborList {
114 ExpandPrimNeighborList(PrimNeighborList &_prim_neighbor_list)
117 template <
typename OrbitVecType>
118 void operator()(OrbitVecType
const &orbits)
const {
119 for (
const auto &orbit : orbits) {
120 for (
const auto &equiv : orbit) {
121 for (
const auto &site : equiv) {
135 "Get prim and supercell neighbor list information. The supercell is \n"
136 "specified by the prim and one of the following (else the primitive \n"
138 "- transformation_matrix_to_super \n"
139 "- supercell_lattice_vectors \n"
140 "- supercell_lattice_column_matrix \n"
141 "- supercell_name \n\n";
143 std::string custom_options =
144 " prim: JSON object (optional, default=prim of current project) \n"
145 " See `casm format --prim` for details on the prim format. \n\n"
147 " nlist_weight_matrix: 3x3 array of integer (optional) \n"
148 " The neighbor list weight matrix, W, defines the canonical order\n"
149 " of neighboring UnitCell through lexicographically sorting \n"
150 " [r, i, j, k], where r = (i,j,k).transpose() * W * (i,j,k). If \n"
151 " not provided, it is obtained from 1) the settings of the \n"
152 " current project, or 2) an appropriate default for the prim \n"
153 " lattice so that unit cells are added to the neighborhood in an \n"
154 " approximate sphere around the origin. \n\n"
156 " nlist_sublat_indices: 3x3 array of integer (optional) \n"
157 " The indices of sublattices that should be included in the \n"
158 " supercell neighbor list. If not provided, it is obtained from \n"
159 " 1) the settings of the current project, or 2) indices of the \n"
160 " sites that have >= 2 occupant DoF, or continuous DoF. \n\n"
162 " cluster_specs: array of JSON objects (optional) \n"
163 " The `cluster_specs` array holds one or more JSON descriptions \n"
164 " of cluster orbits, as used in `bspecs.json`. The prim neighbor \n"
165 " is expanded to include the sites in all cluster orbits. \n\n"
167 " basis_set_names: array of string (optional) \n"
168 " Names of basis sets in the current project whose orbits are \n"
169 " all added to the prim neighbor list. \n\n"
171 " unitcells: array of [i,j,k] (optional) \n"
172 " Array of unit cells (specified by [i, j, k] multiples of the \n"
173 " prim lattice vectors) that should be added to the prim neighbor\n"
176 " transformation_matrix_to_super: 3x3 array of integer (optional) \n"
177 " Transformation matrix T, defining the supercell lattice vectors\n"
178 " S, in terms of the prim lattice vectors, P: `S = P * T`, where \n"
179 " S and P are column vector matrices. \n\n"
181 " supercell_lattice_vectors: 3x3 array of integer (optional) \n"
182 " Supercell lattice vectors, as a row vector matrix. \n\n"
184 " supercell_lattice_column_matrix: 3x3 array of integer (optional) \n"
185 " Supercell lattice vectors, as a column vector matrix. \n\n"
187 " supercell_name: string (optional) \n"
188 " Unique name given to a supercell, based on the hermite normal \n"
189 " form, of the transformation_matrix_to_super and, if not \n"
190 " canonical, the index of the prim factor group operation that \n"
191 " transforms the canonical supercell into this supercell. \n\n"
193 " properties: array of string (optional, default=[]) \n"
194 " An array of strings specifying which neighbor list properties \n"
195 " to output. The default value of an empty array will print all \n"
196 " properties. The allowed options are: \n\n";
198 std::stringstream ss;
199 auto dict = make_neighbor_list_info_dict();
206 return "NeighborListInfo";
215 std::runtime_error error_if_invalid{
"Error reading NeighborListInfo input"};
217 std::unique_ptr<PrimClex> primclex_ptr;
221 primclex_ptr = notstd::make_unique<PrimClex>(root);
228 if (parser.self.contains(
"prim")) {
232 if (parser.valid()) {
233 shared_prim = std::make_shared<Structure const>(basic_structure);
239 std::stringstream msg;
240 msg <<
"Error in NeighborListInfo: No \"prim\" in input and no project "
241 "provided or found.";
242 parser.insert_error(
"prim", msg.str());
248 std::set<int> nlist_sublat_indices;
249 if (parser.self.contains(
"nlist_weight_matrix") ||
250 parser.self.contains(
"nlist_sublat_indices")) {
251 parser.optional(nlist_weight_matrix,
"nlist_weight_matrix");
252 parser.optional(nlist_sublat_indices,
"nlist_sublat_indices");
257 nlist_weight_matrix =
primclex->settings().nlist_weight_matrix();
258 nlist_sublat_indices =
primclex->settings().nlist_sublat_indices();
259 }
catch (std::exception &e) {
260 parser.error.insert(e.what());
263 nlist_weight_matrix =
270 nlist_sublat_indices.begin(),
271 nlist_sublat_indices.end()};
275 if (parser.self.contains(
"cluster_specs")) {
276 std::vector<jsonParser> cluster_specs_json_vec;
277 parser.optional(cluster_specs_json_vec,
"cluster_specs");
279 for (
jsonParser const &cluster_specs_json : cluster_specs_json_vec) {
281 if (!parser.valid()) {
289 if (
primclex !=
nullptr && parser.self.contains(
"basis_set_names")) {
290 std::vector<std::string> basis_set_names;
291 parser.optional(basis_set_names,
"basis_set_names");
292 for (
auto basis_set_name : basis_set_names) {
293 if (!
primclex->has_basis_set_specs(basis_set_name)) {
294 std::stringstream msg;
295 msg <<
"No basis set named: " << basis_set_name;
296 parser.insert_error(
"basis_set_names", msg.str());
300 primclex->basis_set_specs(basis_set_name);
302 neighbor_list_expander);
307 if (parser.self.contains(
"unitcells")) {
315 if (parser.self.contains(
"transformation_matrix_to_super")) {
316 parser.optional(T,
"transformation_matrix_to_super");
319 }
else if (parser.self.contains(
"supercell_lattice_vectors")) {
321 parser.optional(L_transpose,
"supercell_lattice_vectors");
322 Lattice super_lattice{L_transpose.transpose()};
327 }
else if (parser.self.contains(
"supercell_lattice_column_matrix")) {
329 parser.optional(L,
"supercell_lattice_column_matrix");
335 }
else if (parser.self.contains(
"supercell_name")) {
336 std::string supercell_name;
337 parser.optional(supercell_name,
"supercell_name");
357 auto dict = make_neighbor_list_info_dict();
360 for (
auto it = dict.begin(); it != dict.end(); ++it) {
372 formatter.to_json(data, json);
373 log << json << std::endl;
SupercellSymInfo const & supercell_sym_info
SuperNeighborList const & supercell_neighbor_list
std::shared_ptr< Structure const > shared_prim
PrimNeighborList const & prim_neighbor_list
std::string desc() const override
std::string name() const override
Enumeration method name (i.e. "prim", "supercell", "dof_space", etc.)
void run(jsonParser const &json_options, PrimClex const *primclex=nullptr) const override
Run NeighborListInfo info method.
PrimClex is the top-level data structure for a CASM project.
The PrimNeighborList gives the coordinates of UnitCell that are neighbors of the origin UnitCell.
A class that collects all symmetry information for for performing symmetry transformations on the sit...
static jsonParser array()
Returns an empty json array.
BasicStructure specifies the lattice and atomic basis of a crystal.
const Eigen::Matrix3l & transformation_matrix_to_super() const
Lattice make_superlattice(const Lattice &lat, const Eigen::Matrix< IntegralType, 3, 3, Options > &transf_mat)
Returns a super Lattice. Transformation matrix must be integer.
xtal::Superlattice make_superlattice_from_supercell_name(Structure const &prim, std::string supercell_name)
Construct a Superlattice from the supercell name.
std::string make_supercell_name(Structure const &prim, xtal::Superlattice const &superlattice)
Make the supercell name from a Superlattice.
ConfigIO::GenericConfigFormatter< jsonParser > properties()
GenericScelFormatter< double > volume()
IdentitySymRepBuilder Identity()
Eigen::Matrix3l make_transformation_matrix_to_super(const Lattice &tiling_unit, const Lattice &superlattice, double tol)
void for_all_orbits(ClusterSpecs const &cluster_specs, std::vector< IntegralCluster > const &generating_elements, FunctorType const &f)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
std::set< int > default_nlist_sublat_indices(xtal::BasicStructure const &prim)
std::string description(const SymOp &op, const xtal::Lattice &lat, SymInfoOptions opt=SymInfoOptions())
Print SymInfo to string.
Eigen::Matrix3l default_nlist_weight_matrix(xtal::BasicStructure const &prim, double tol)
fs::path find_casmroot(const fs::path &cwd)
void report_and_throw_if_invalid(KwargsParser const &parser, Log &log, ErrorType error)
SupercellSymInfo make_supercell_sym_info(Structure const &prim, Lattice const &super_lattice)
INDEX_TYPE Index
For long integer indexing:
Matrix< long int, 3, 3 > Matrix3l
Provides parameters for constructing a cluster expansion basis (ClexBasis)
notstd::cloneable_ptr< ClusterSpecs > cluster_specs