From bedc4547ca56f04fdb5c28f02ec957957d251768 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 17 Nov 2017 22:04:04 +0900 Subject: [PATCH 01/33] Simplify the symmetry code with the SymmetryOperation class Merged several variables in symmetry.h into the SymmetryOperation class. The new SymmetryOperation class contains the rotation matrix in both lattice (fractional) and Cartesian coordinates and translation vector in Cartesian coordinate. Also, the information about the compatibility for the force constant reduction is stored. We also changed the variable name as namin-->nat_prim. --- alm/constraint.cpp | 8 +- alm/fcs.cpp | 21 +-- alm/fitting.cpp | 8 +- alm/interaction.cpp | 22 +-- alm/patterndisp.cpp | 31 ++--- alm/symmetry.cpp | 289 +++++++++++++++++++--------------------- alm/symmetry.h | 50 ++++--- alm/system.cpp | 4 +- alm/writes.cpp | 2 +- anphon/dynamical.cpp | 3 +- include/mathfunctions.h | 2 +- 11 files changed, 218 insertions(+), 222 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index d153f1b4..efadccf4 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -562,7 +562,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou std::vector > const_mat; for (isym = 0; isym < symmetry->nsym; ++isym) { - if (symmetry->sym_available[isym]) continue; + if (symmetry->SymmList[isym].compatible_with_cartesian) continue; has_constraint_from_symm = true; } @@ -639,7 +639,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou for (isym = 0; isym < symmetry->nsym; ++isym) { - if (symmetry->sym_available[isym]) continue; + if (symmetry->SymmList[isym].compatible_with_cartesian) continue; for (i = 0; i < order + 2; ++i) atm_index_symm[i] = symmetry->map_sym[atm_index[i]][isym]; @@ -742,7 +742,7 @@ void Constraint::translational_invariance() int **xyzcomponent; int ixyz, nxyz; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int nat = system->nat; int nparams; @@ -1019,7 +1019,7 @@ void Constraint::rotational_invariance() int icrd, jcrd; int order; int maxorder = interaction->maxorder; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int mu, nu; int ixyz, nxyz, nxyz2; int mu_lambda, lambda; diff --git a/alm/fcs.cpp b/alm/fcs.cpp index a1713dbe..2aae731e 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -26,9 +26,13 @@ using namespace ALM_NS; -Fcs::Fcs(ALM *alm) : Pointers(alm) {}; +Fcs::Fcs(ALM *alm) : Pointers(alm) +{ +}; -Fcs::~Fcs() {}; +Fcs::~Fcs() +{ +}; void Fcs::init() { @@ -127,8 +131,7 @@ void Fcs::generate_fclists(int maxorder) std::set list_found; - for (std::set::iterator iter = interaction->pairs[order].begin(); - iter != interaction->pairs[order].end(); ++iter) { + for (auto iter = interaction->pairs[order].begin(); iter != interaction->pairs[order].end(); ++iter) { for (i = 0; i < order + 2; ++i) atmn[i] = (*iter).iarray[i]; @@ -152,7 +155,7 @@ void Fcs::generate_fclists(int maxorder) for (isym = 0; isym < symmetry->nsym; ++isym) { - if (!symmetry->sym_available[isym]) continue; + if (!symmetry->SymmList[isym].compatible_with_cartesian) continue; for (i = 0; i < order + 2; ++i) atmn_mapped[i] = symmetry->map_sym[atmn[i]][isym]; @@ -250,7 +253,7 @@ double Fcs::coef_sym(const int n, int i; for (i = 0; i < n; ++i) { - tmp *= symmetry->symrel[symnum][arr2[i]][arr1[i]]; + tmp *= symmetry->SymmList[symnum].rotation_cart[arr2[i]][arr1[i]]; } return tmp; } @@ -267,7 +270,7 @@ bool Fcs::is_ascending(const int n, const int *arr) int Fcs::min_inprim(const int n, const int *arr) { int i, j, atmnum; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int minloc; int *ind; @@ -303,7 +306,7 @@ int Fcs::min_inprim(const int n, const int *arr) bool Fcs::is_inprim(const int n, const int *arr) { int i, j; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; for (i = 0; i < n; ++i) { for (j = 0; j < natmin; ++j) { @@ -316,7 +319,7 @@ bool Fcs::is_inprim(const int n, const int *arr) bool Fcs::is_inprim(const int n) { int i, atmn; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; atmn = n / 3; diff --git a/alm/fitting.cpp b/alm/fitting.cpp index ebbce9a7..0fa431f7 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -67,7 +67,7 @@ void Fitting::fitmain() { int i; int nat = system->nat; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int ntran = symmetry->ntran; int ndata = system->ndata; @@ -379,8 +379,8 @@ void Fitting::data_multiplier(const int nat, f_rot[k] = f_tmp[3 * nat * i + 3 * j + k]; } - rotvec(u_rot, u_rot, symmetry->symrel[isym]); - rotvec(f_rot, f_rot, symmetry->symrel[isym]); + rotvec(u_rot, u_rot, symmetry->SymmList[isym].rotation_cart); + rotvec(f_rot, f_rot, symmetry->SymmList[isym].rotation_cart); for (k = 0; k < 3; ++k) { u[nmulti * idata + isym][3 * n_mapped + k] = u_rot[k]; @@ -1249,7 +1249,7 @@ int Fitting::inprim_index(const int n) int atmn = n / 3; int crdn = n % 3; - for (int i = 0; i < symmetry->natmin; ++i) { + for (int i = 0; i < symmetry->nat_prim; ++i) { if (symmetry->map_p2s[i][0] == atmn) { in = 3 * i + crdn; break; diff --git a/alm/interaction.cpp b/alm/interaction.cpp index 2c78f0f9..69813bb9 100644 --- a/alm/interaction.cpp +++ b/alm/interaction.cpp @@ -77,8 +77,8 @@ void Interaction::init() memory->allocate(exist_image, nneib); memory->allocate(distall, nat, nat); memory->allocate(mindist_pairs, nat, nat); - memory->allocate(interaction_pair, maxorder, symmetry->natmin); - memory->allocate(mindist_cluster, maxorder, symmetry->natmin); + memory->allocate(interaction_pair, maxorder, symmetry->nat_prim); + memory->allocate(mindist_cluster, maxorder, symmetry->nat_prim); memory->allocate(pairs, maxorder); generate_coordinate_of_periodic_images(nat, system->xcoord, @@ -103,7 +103,7 @@ void Interaction::generate_pairs(std::set *pair_out, int i, j; int iat; int order; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int nat = system->nat; int *pair_tmp; @@ -289,9 +289,9 @@ void Interaction::print_neighborlist(std::vector **mindist) double dist_tmp; std::vector *neighborlist; - memory->allocate(neighborlist, symmetry->natmin); + memory->allocate(neighborlist, symmetry->nat_prim); - for (i = 0; i < symmetry->natmin; ++i) { + for (i = 0; i < symmetry->nat_prim; ++i) { neighborlist[i].clear(); iat = symmetry->map_p2s[i][0]; @@ -310,7 +310,7 @@ void Interaction::print_neighborlist(std::vector **mindist) int nthnearest; std::vector atomlist; - for (i = 0; i < symmetry->natmin; ++i) { + for (i = 0; i < symmetry->nat_prim; ++i) { nthnearest = 0; atomlist.clear(); @@ -398,7 +398,7 @@ void Interaction::search_interactions(std::vector **interaction_list_out, // int i; int order; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int iat, jat; int nat = system->nat; int ikd, jkd; @@ -704,7 +704,7 @@ void Interaction::calc_mindist_clusters(std::vector **interaction_pair_in, // Calculate the complete set of interaction clusters for each order. // - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int i, j, k; int iat, jat; int order; @@ -735,7 +735,7 @@ void Interaction::calc_mindist_clusters(std::vector **interaction_pair_in, std::vector > data_vec; for (order = 0; order < maxorder; ++order) { - for (i = 0; i < symmetry->natmin; ++i) { + for (i = 0; i < symmetry->nat_prim; ++i) { mindist_cluster_out[order][i].clear(); @@ -971,7 +971,7 @@ void Interaction::calc_mindist_clusters2(std::vector **interaction_pair_in, { std::vector distance_list; - int natmin = symmetry->natmin; + int natmin = symmetry->nat_prim; int i, j, k; int iat, jat; int ikd, jkd; @@ -996,7 +996,7 @@ void Interaction::calc_mindist_clusters2(std::vector **interaction_pair_in, bool isok; for (order = 0; order < maxorder; ++order) { - for (i = 0; i < symmetry->natmin; ++i) { + for (i = 0; i < symmetry->nat_prim; ++i) { mindist_cluster_out[order][i].clear(); iat = symmetry->map_p2s[i][0]; diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index ec5552f7..a251f61c 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -25,7 +25,9 @@ or http://opensource.org/licenses/mit-license.php for information. using namespace ALM_NS; -Displace::Displace(ALM *alm) : Pointers(alm) {} +Displace::Displace(ALM *alm) : Pointers(alm) +{ +} Displace::~Displace() { @@ -142,7 +144,7 @@ void Displace::generate_pattern_all(const int N, std::vector atoms, vec_tmp, nums; std::vector directions, directions_copy; - std::vector > *sign_prod, sign_reduced; + std::vector> *sign_prod, sign_reduced; memory->allocate(sign_prod, N); @@ -156,8 +158,8 @@ void Displace::generate_pattern_all(const int N, pattern[order].clear(); - for (std::set::iterator it = dispset_in[order].begin(); - it != dispset_in[order].end(); ++it) { + for (std::set::iterator it = dispset_in[order].begin(); + it != dispset_in[order].end(); ++it) { atoms.clear(); directions.clear(); @@ -194,7 +196,7 @@ void Displace::generate_pattern_all(const int N, std::copy(directions.begin(), directions.end(), std::back_inserter(directions_copy)); - for (std::vector >::const_iterator it2 = sign_reduced.begin(); + for (std::vector>::const_iterator it2 = sign_reduced.begin(); it2 != sign_reduced.end(); ++it2) { directions.clear(); @@ -225,7 +227,7 @@ void Displace::generate_pattern_all(const int N, } void Displace::generate_signvecs(const int N, - std::vector > &sign, + std::vector> &sign, std::vector vec) { // returns the product of signs ('+','-') @@ -250,9 +252,9 @@ void Displace::generate_signvecs(const int N, } void Displace::find_unique_sign_pairs(const int N, - std::vector > sign_in, + std::vector> sign_in, std::vector pair_in, - std::vector > &sign_out) + std::vector> &sign_out) { int isym, i, j, k; int mapped_atom; @@ -267,7 +269,7 @@ void Displace::find_unique_sign_pairs(const int N, std::vector symnum_vec; std::vector::iterator loc; std::vector atom_tmp, pair_tmp; - std::vector > sign_found; + std::vector> sign_found; std::vector sign_tmp; std::vector list_disp_atom; std::vector index_for_sort; @@ -333,8 +335,8 @@ void Displace::find_unique_sign_pairs(const int N, for (j = 0; j < 3; ++j) { disp_sym[mapped_atom][j] = 0.0; for (k = 0; k < 3; ++k) { - disp_sym[mapped_atom][j] - += symmetry->symrel[isym][j][k] * disp[list_disp_atom[i]][k]; + disp_sym[mapped_atom][j] + += symmetry->SymmList[isym].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; } disp_tmp = disp_sym[mapped_atom][j]; @@ -356,8 +358,8 @@ void Displace::find_unique_sign_pairs(const int N, sign_found.clear(); - for (std::vector >::const_iterator it = sign_in.begin(); - it != sign_in.end(); ++it) { + for (std::vector>::const_iterator it = sign_in.begin(); + it != sign_in.end(); ++it) { // if the sign has already been found before, cycle the loop. // else, add the current sign pairs to the return variable. @@ -387,7 +389,7 @@ void Displace::find_unique_sign_pairs(const int N, for (j = 0; j < 3; ++j) { disp_sym[mapped_atom][j] = 0.0; for (k = 0; k < 3; ++k) { - disp_sym[mapped_atom][j] += symmetry->symrel[symnum_vec[isym]][j][k] + disp_sym[mapped_atom][j] += symmetry->SymmList[symnum_vec[isym]].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; } disp_tmp = disp_sym[mapped_atom][j]; @@ -422,4 +424,3 @@ void Displace::find_unique_sign_pairs(const int N, memory->deallocate(disp); memory->deallocate(disp_sym); } - diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index c37e2f3b..fd44e254 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -31,19 +31,15 @@ using namespace ALM_NS; Symmetry::Symmetry(ALM *alm) : Pointers(alm) { - file_sym = "SYMM_INFO"; } Symmetry::~Symmetry() { - memory->deallocate(symrel); - memory->deallocate(symrel_int); - memory->deallocate(tnons); memory->deallocate(map_sym); memory->deallocate(map_p2s); memory->deallocate(map_s2p); memory->deallocate(symnum_tran); - memory->deallocate(sym_available); + SymmList.clear(); } void Symmetry::init() @@ -54,49 +50,29 @@ void Symmetry::init() std::cout << " SYMMETRY" << std::endl; std::cout << " ========" << std::endl << std::endl; - setup_symmetry_operation(nat, nsym, system->lavec, system->rlavec, + setup_symmetry_operation(nat, nsym, + system->lavec, system->rlavec, system->xcoord, system->kd); - memory->allocate(tnons, nsym, 3); - memory->allocate(symrel_int, nsym, 3, 3); - - int isym = 0; - for (std::vector::iterator iter = SymmList.begin(); - iter != SymmList.end(); ++iter) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - symrel_int[isym][i][j] = (*iter).rot[i][j]; - } - } - for (i = 0; i < 3; ++i) { - tnons[isym][i] = (*iter).tran[i]; - } - ++isym; - } - - std::cout << " Number of symmetry operations = " << nsym << std::endl; - memory->allocate(symrel, nsym, 3, 3); - symop_in_cart(system->lavec, system->rlavec); + std::cout << " Number of symmetry operations = " << SymmList.size() << std::endl; - memory->allocate(sym_available, nsym); - int nsym_fc; - symop_availability_check(symrel, sym_available, nsym, nsym_fc); + // int nsym_fc; - if (nsym_fc == nsym) { - std::cout << " All symmetry operations will be used to" << std::endl; - std::cout << " reduce the number of force constants." << std::endl; - } else { - std::cout << " " << nsym_fc << " symmetry operations out of " - << nsym << " will be used to reduce the number of parameters." << std::endl; - std::cout << " Other " << nsym - nsym_fc - << " symmetry operations will be imposed as constraints." << std::endl; - } - std::cout << std::endl; + // if (nsym_fc == nsym) { + // std::cout << " All symmetry operations will be used to" << std::endl; + // std::cout << " reduce the number of force constants." << std::endl; + // } else { + // std::cout << " " << nsym_fc << " symmetry operations out of " + // << nsym << " will be used to reduce the number of parameters." << std::endl; + // std::cout << " Other " << nsym - nsym_fc + // << " symmetry operations will be imposed as constraints." << std::endl; + // } + // std::cout << std::endl; pure_translations(); memory->allocate(map_sym, nat, nsym); - memory->allocate(map_p2s, natmin, ntran); + memory->allocate(map_p2s, nat_prim, ntran); memory->allocate(map_s2p, nat); genmaps(nat, system->xcoord, map_sym, map_p2s, map_s2p); @@ -107,7 +83,7 @@ void Symmetry::init() for (int i = 0; i < ntran; ++i) { std::cout << std::setw(6) << i + 1 << " | "; - for (int j = 0; j < natmin; ++j) { + for (int j = 0; j < nat_prim; ++j) { std::cout << std::setw(5) << map_p2s[j][i] + 1; if ((j + 1) % 5 == 0) { std::cout << std::endl << " | "; @@ -154,11 +130,10 @@ void Symmetry::setup_symmetry_operation(int nat, ofs_sym.open(file_sym.c_str(), std::ios::out); ofs_sym << nsym << std::endl; - for (std::vector::iterator p = SymmList.begin(); - p != SymmList.end(); ++p) { + for (auto p = SymmList.begin(); p != SymmList.end(); ++p) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - ofs_sym << std::setw(4) << (*p).rot[i][j]; + ofs_sym << std::setw(4) << (*p).rotation[i][j]; } } ofs_sym << " "; @@ -175,30 +150,41 @@ void Symmetry::setup_symmetry_operation(int nat, // Identity operation only ! - std::cout << " NSYM = 1 : Only the identity matrix will be considered." << std::endl << std::endl; + std::cout << " NSYM = 1 : Only the identity matrix will be considered." + << std::endl << std::endl; int rot_tmp[3][3]; + double rot_cart_tmp[3][3]; double tran_tmp[3]; for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { if (i == j) { rot_tmp[i][j] = 1; + rot_cart_tmp[i][j] = 1.0; } else { rot_tmp[i][j] = 0; + rot_cart_tmp[i][j] = 0.0; } } tran_tmp[i] = 0.0; } - SymmList.push_back(SymmetryOperation(rot_tmp, tran_tmp)); + SymmList.push_back(SymmetryOperation(rot_tmp, + tran_tmp, + rot_cart_tmp, + true, + true, + true)); } else { - std::cout << " NSYM > 1 : Symmetry operations will be read from SYMM_INFO file" << std::endl << std::endl; + std::cout << " NSYM > 1 : Symmetry operations will be read from SYMM_INFO file" + << std::endl << std::endl; int nsym2; int rot_tmp[3][3]; + double rot_cart_tmp[3][3]; double tran_tmp[3]; std::ifstream ifs_sym; @@ -216,7 +202,13 @@ void Symmetry::setup_symmetry_operation(int nat, >> rot_tmp[2][0] >> rot_tmp[2][1] >> rot_tmp[2][2] >> tran_tmp[0] >> tran_tmp[1] >> tran_tmp[2]; - SymmList.push_back(SymmetryOperation(rot_tmp, tran_tmp)); + symop_in_cart(rot_cart_tmp, rot_tmp, system->lavec, system->rlavec); + SymmList.push_back(SymmetryOperation(rot_tmp, + tran_tmp, + rot_cart_tmp, + is_compatible(rot_tmp), + is_compatible(rot_cart_tmp), + is_translation(rot_tmp))); } ifs_sym.close(); } @@ -402,18 +394,24 @@ void Symmetry::find_crystal_symmetry(int nat, for (j = 0; j < 3; ++j) { if (i == j) { rot_int[i][j] = 1; + rot_cart[i][j] = 1.0; } else { rot_int[i][j] = 0; + rot_cart[i][j] = 0.0; } } tran[i] = 0.0; } - CrystalSymmList.push_back(SymmetryOperation(rot_int, tran)); + CrystalSymmList.push_back(SymmetryOperation(rot_int, + tran, + rot_cart, + is_compatible(rot_int), + is_compatible(rot_cart), + is_translation(rot_int))); - for (std::vector::iterator it_latsym = LatticeSymmList.begin(); - it_latsym != LatticeSymmList.end(); ++it_latsym) { + for (auto it_latsym = LatticeSymmList.begin(); it_latsym != LatticeSymmList.end(); ++it_latsym) { iat = atomclass[0][0]; @@ -443,10 +441,10 @@ void Symmetry::find_crystal_symmetry(int nat, continue; is_identity_matrix = - (std::pow(rot[0][0] - 1.0, 2) + std::pow(rot[0][1], 2) + std::pow(rot[0][2], 2) - + std::pow(rot[1][0], 2) + std::pow(rot[1][1] - 1.0, 2) + std::pow(rot[1][2], 2) - + std::pow(rot[2][0], 2) + std::pow(rot[2][1], 2) + std::pow(rot[2][2] - 1.0, 2) - + std::pow(tran[0], 2) + std::pow(tran[1], 2) + std::pow(tran[2], 2)) < eps12; + (std::pow(rot[0][0] - 1.0, 2) + std::pow(rot[0][1], 2) + std::pow(rot[0][2], 2) + + std::pow(rot[1][0], 2) + std::pow(rot[1][1] - 1.0, 2) + std::pow(rot[1][2], 2) + + std::pow(rot[2][0], 2) + std::pow(rot[2][1], 2) + std::pow(rot[2][2] - 1.0, 2) + + std::pow(tran[0], 2) + std::pow(tran[1], 2) + std::pow(tran[2], 2)) < eps12; if (is_identity_matrix) continue; isok = true; @@ -484,12 +482,7 @@ void Symmetry::find_crystal_symmetry(int nat, } } - if (isok && system->lspin && system->noncollinear) { - for (i = 0; i < 3; ++i) { - mag[i] = system->magmom[jat][i]; - mag_rot[i] = system->magmom[iat][i]; - } - + if (isok) { matmul3(rot_tmp, rot, system->rlavec); matmul3(rot_cart, system->lavec, rot_tmp); @@ -498,36 +491,51 @@ void Symmetry::find_crystal_symmetry(int nat, rot_cart[i][j] /= (2.0 * pi); } } - rotvec(mag_rot, mag_rot, rot_cart); - // In the case of improper rotation, the factor -1 should be multiplied - // because the inversion operation doesn't flip the spin. - if (!is_proper(rot_cart)) { + if (system->lspin && system->noncollinear) { for (i = 0; i < 3; ++i) { - mag_rot[i] = -mag_rot[i]; + mag[i] = system->magmom[jat][i]; + mag_rot[i] = system->magmom[iat][i]; } - } - mag_sym1 = (std::pow(mag[0] - mag_rot[0], 2.0) - + std::pow(mag[1] - mag_rot[1], 2.0) - + std::pow(mag[2] - mag_rot[2], 2.0)) < eps6; - mag_sym2 = (std::pow(mag[0] + mag_rot[0], 2.0) - + std::pow(mag[1] + mag_rot[1], 2.0) - + std::pow(mag[2] + mag_rot[2], 2.0)) < eps6; + rotvec(mag_rot, mag_rot, rot_cart); - if (!mag_sym1 && !mag_sym2) { - isok = false; - } else if (!mag_sym1 && mag_sym2 && !trev_sym_mag) { - isok = false; + // In the case of improper rotation, the factor -1 should be multiplied + // because the inversion operation doesn't flip the spin. + if (!is_proper(rot_cart)) { + for (i = 0; i < 3; ++i) { + mag_rot[i] = -mag_rot[i]; + } + } + + mag_sym1 = (std::pow(mag[0] - mag_rot[0], 2.0) + + std::pow(mag[1] - mag_rot[1], 2.0) + + std::pow(mag[2] - mag_rot[2], 2.0)) < eps6; + + mag_sym2 = (std::pow(mag[0] + mag_rot[0], 2.0) + + std::pow(mag[1] + mag_rot[1], 2.0) + + std::pow(mag[2] + mag_rot[2], 2.0)) < eps6; + + if (!mag_sym1 && !mag_sym2) { + isok = false; + } else if (!mag_sym1 && mag_sym2 && !trev_sym_mag) { + isok = false; + } } } + if (isok) { #ifdef _OPENMP #pragma omp critical #endif - CrystalSymmList.push_back(SymmetryOperation((*it_latsym).mat, tran)); + CrystalSymmList.push_back(SymmetryOperation((*it_latsym).mat, + tran, + rot_cart, + is_compatible((*it_latsym).mat), + is_compatible(rot_cart), + is_translation((*it_latsym).mat))); } } @@ -535,54 +543,42 @@ void Symmetry::find_crystal_symmetry(int nat, } -void Symmetry::symop_in_cart(double lavec[3][3], double rlavec[3][3]) +void Symmetry::symop_in_cart(double rot_cart[3][3], + const int rot_lattice[3][3], + const double lavec[3][3], + const double rlavec[3][3]) { int i, j; - double sym_tmp[3][3], sym_crt[3][3]; + double sym_tmp[3][3]; double tmp[3][3]; - for (int isym = 0; isym < nsym; ++isym) { - - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - sym_tmp[i][j] = static_cast(symrel_int[isym][i][j]); - } - } - - matmul3(tmp, sym_tmp, rlavec); - matmul3(sym_crt, lavec, tmp); - - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - symrel[isym][i][j] = sym_crt[i][j] / (2.0 * pi); - } + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + sym_tmp[i][j] = static_cast(rot_lattice[i][j]); } } -#ifdef _DEBUG + matmul3(tmp, sym_tmp, rlavec); + matmul3(rot_cart, lavec, tmp); - std::cout << "Symmetry Operations in Cartesian Coordinate" << std::endl; - for (int isym = 0; isym < nsym; ++isym) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - std::cout << std::setw(8) << symrel[isym][i][j]; - } + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + rot_cart[i][j] = rot_cart[i][j] / (2.0 * pi); } - std::cout << std::endl; } -#endif } + void Symmetry::pure_translations() { int i; ntran = 0; for (i = 0; i < nsym; ++i) { - if (is_translation(symrel_int[i])) ++ntran; + if (SymmList[i].is_translation) ++ntran; } - natmin = system->nat / ntran; + nat_prim = system->nat / ntran; if (ntran > 1) { std::cout << " Given system is not primitive cell." << std::endl; @@ -591,11 +587,11 @@ void Symmetry::pure_translations() } else { std::cout << " Given system is a primitive cell." << std::endl; } - std::cout << " Primitive cell contains " << natmin << " atoms" << std::endl; + std::cout << " Primitive cell contains " << nat_prim << " atoms" << std::endl; if (system->nat % ntran) { error->exit("pure_translations", - "nat != natmin * ntran. Something is wrong in the structure."); + "nat != nat_prim * ntran. Something is wrong in the structure."); } memory->allocate(symnum_tran, ntran); @@ -603,7 +599,7 @@ void Symmetry::pure_translations() int isym = 0; for (i = 0; i < nsym; ++i) { - if (is_translation(symrel_int[i])) symnum_tran[isym++] = i; + if (SymmList[i].is_translation) symnum_tran[isym++] = i; } } @@ -634,7 +630,7 @@ void Symmetry::genmaps(int nat, for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - rot_double[i][j] = static_cast(symrel_int[isym][i][j]); + rot_double[i][j] = static_cast(SymmList[isym].rotation[i][j]); } } @@ -646,7 +642,7 @@ void Symmetry::genmaps(int nat, rotvec(xnew, x[iat], rot_double); - for (i = 0; i < 3; ++i) xnew[i] += tnons[isym][i]; + for (i = 0; i < 3; ++i) xnew[i] += SymmList[isym].tran[i]; for (jj = 0; jj < system->atomlist_class[itype].size(); ++jj) { @@ -691,7 +687,7 @@ void Symmetry::genmaps(int nat, memory->deallocate(is_checked); - for (iat = 0; iat < natmin; ++iat) { + for (iat = 0; iat < nat_prim; ++iat) { for (i = 0; i < ntran; ++i) { atomnum_translated = map_p2s[iat][i]; map_s2p[atomnum_translated].atom_num = iat; @@ -700,7 +696,7 @@ void Symmetry::genmaps(int nat, } } -bool Symmetry::is_translation(int **rot) +bool Symmetry::is_translation(const int rot[3][3]) { bool ret; @@ -712,40 +708,26 @@ bool Symmetry::is_translation(int **rot) return ret; } -void Symmetry::symop_availability_check(double ***rot, - bool *flag, - const int n, - int &nsym_fc) + +template +bool Symmetry::is_compatible(const T rot[3][3], + const double tolerance_zero) { - int i, j, k; + int i, j; int nfinite; + double rot_double[3][3]; - nsym_fc = 0; - - for (i = 0; i < nsym; ++i) { - - std::cout << "Sym. No. : " << std::setw(3) << i + 1 << std::endl; - for (j = 0; j < 3; ++j) { - for (k = 0; k < 3; ++k) { - std::cout << std::setw(15) << rot[i][j][k]; - } - std::cout << std::endl; - } - std::cout << std::endl; - nfinite = 0; + nfinite = 0; + for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - for (k = 0; k < 3; ++k) { - if (std::abs(rot[i][j][k]) > 1.0e-5) ++nfinite; - } - } - - if (nfinite == 3) { - ++nsym_fc; - flag[i] = true; - } else { - flag[i] = false; + rot_double[i][j] = static_cast(rot[i][j]); + if (std::abs(rot_double[i][j]) > tolerance_zero) ++nfinite; } } + + if (nfinite == 3) return true; + + return false; } void Symmetry::print_symmetrized_coordinate(double **x) @@ -774,21 +756,21 @@ void Symmetry::print_symmetrized_coordinate(double **x) } } - for (std::vector::iterator it = SymmList.begin(); - it != SymmList.end(); ++it) { + for (std::vector::iterator it = SymmList.begin(); + it != SymmList.end(); ++it) { ++isym; std::cout << "Symmetry No. : " << std::setw(5) << isym << std::endl; - m11 = (*it).rot[0][0]; - m12 = (*it).rot[0][1]; - m13 = (*it).rot[0][2]; - m21 = (*it).rot[1][0]; - m22 = (*it).rot[1][1]; - m23 = (*it).rot[1][2]; - m31 = (*it).rot[2][0]; - m32 = (*it).rot[2][1]; - m33 = (*it).rot[2][2]; + m11 = (*it).rotation[0][0]; + m12 = (*it).rotation[0][1]; + m13 = (*it).rotation[0][2]; + m21 = (*it).rotation[1][0]; + m22 = (*it).rotation[1][1]; + m23 = (*it).rotation[1][2]; + m31 = (*it).rotation[2][0]; + m32 = (*it).rotation[2][1]; + m33 = (*it).rotation[2][2]; for (i = 0; i < 3; ++i) tran[i] = (*it).tran[i]; @@ -921,7 +903,7 @@ void Symmetry::print_symmetrized_coordinate(double **x) memory->deallocate(x_avg); } -bool Symmetry::is_proper(double rot[3][3]) +bool Symmetry::is_proper(const double rot[3][3]) { double det; bool ret; @@ -940,4 +922,3 @@ bool Symmetry::is_proper(double rot[3][3]) return ret; } - diff --git a/alm/symmetry.h b/alm/symmetry.h index 8da44287..074c5cdf 100644 --- a/alm/symmetry.h +++ b/alm/symmetry.h @@ -24,23 +24,34 @@ namespace ALM_NS class SymmetryOperation { public: - int rot[3][3]; - double tran[3]; + int rotation[3][3]; // in lattice basis + double tran[3]; // in Cartesian basis + double rotation_cart[3][3]; // in Cartesian basis + bool compatible_with_lattice; + bool compatible_with_cartesian; + bool is_translation; SymmetryOperation(); - // Declaration construction - - SymmetryOperation(const int rot_in[3][3], const double tran_in[3]) + SymmetryOperation(const int rot_in[3][3], + const double tran_in[3], + const double rot_cart_in[3][3], + const bool compatibility_lat, + const bool compatibility_cart, + const bool is_trans_in) { for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - rot[i][j] = rot_in[i][j]; + rotation[i][j] = rot_in[i][j]; + rotation_cart[i][j] = rot_cart_in[i][j]; } } for (int i = 0; i < 3; ++i) { tran[i] = tran_in[i]; } + compatible_with_lattice = compatibility_lat; + compatible_with_cartesian = compatibility_cart; + is_translation = is_trans_in; } bool operator<(const SymmetryOperation &a) const @@ -48,8 +59,8 @@ namespace ALM_NS std::vector v1, v2; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - v1.push_back(static_cast(rot[i][j])); - v2.push_back(static_cast(a.rot[i][j])); + v1.push_back(static_cast(rotation[i][j])); + v2.push_back(static_cast(a.rotation[i][j])); } } for (int i = 0; i < 3; ++i) { @@ -94,14 +105,12 @@ namespace ALM_NS void init(); - unsigned int nsym, ntran, natmin; + unsigned int nsym, ntran, nat_prim; int is_printsymmetry; int multiply_data; int *symnum_tran; double tolerance; - double ***symrel; - double **tnons; int **map_sym; int **map_p2s; @@ -116,7 +125,8 @@ namespace ALM_NS Maps *map_s2p; int trev_sym_mag; - bool *sym_available; + + std::vector SymmList; private: @@ -130,13 +140,16 @@ namespace ALM_NS void findsym(int, double [3][3], double **, std::vector &); - bool is_translation(int **); - bool is_proper(double [3][3]); + bool is_translation(const int [3][3]); + bool is_proper(const double [3][3]); - void symop_in_cart(double [3][3], double [3][3]); + void symop_in_cart(double [3][3], const int [3][3], + const double [3][3], const double [3][3]); void pure_translations(); void print_symmetrized_coordinate(double **); - void symop_availability_check(double ***, bool *, const int, int &); + + template + bool is_compatible(const T [3][3], const double tolerance_zero = 1.0e-5); void find_lattice_symmetry(double [3][3], std::vector &); @@ -145,9 +158,6 @@ namespace ALM_NS std::vector, std::vector &); - std::string file_sym; - int ***symrel_int; - std::vector SymmList; + std::string file_sym = "SYMM_INFO"; }; } - diff --git a/alm/system.cpp b/alm/system.cpp index 18d39dca..b034ffd9 100644 --- a/alm/system.cpp +++ b/alm/system.cpp @@ -249,7 +249,7 @@ void System::load_reference_system_xml(std::string file_reference_fcs, get_value_from_xml(pt, "Data.Symmetry.NumberOfTranslations")); natmin_ref = nat_ref / ntran_ref; - if (natmin_ref != symmetry->natmin) { + if (natmin_ref != symmetry->nat_prim) { error->exit("load_reference_system_xml", "The number of atoms in the primitive cell is not consistent."); } @@ -389,7 +389,7 @@ void System::load_reference_system() ifs_fc2 >> nat_s >> natmin_ref >> ntran_ref; - if (natmin_ref != symmetry->natmin) { + if (natmin_ref != symmetry->nat_prim) { error->exit("load_reference_system", "The number of atoms in the primitive cell is not consistent"); } diff --git a/alm/writes.cpp b/alm/writes.cpp index 3259179d..809637ae 100644 --- a/alm/writes.cpp +++ b/alm/writes.cpp @@ -327,7 +327,7 @@ void Writes::write_misc_xml() } system_structure.nat = system->nat; - system_structure.natmin = symmetry->natmin; + system_structure.natmin = symmetry->nat_prim; system_structure.ntran = symmetry->ntran; system_structure.nspecies = system->nkd; diff --git a/anphon/dynamical.cpp b/anphon/dynamical.cpp index da9570df..294fa78c 100644 --- a/anphon/dynamical.cpp +++ b/anphon/dynamical.cpp @@ -29,6 +29,7 @@ #include "gruneisen.h" #include "ewald.h" + using namespace PHON_NS; Dynamical::Dynamical(PHON *phon): Pointers(phon) @@ -944,7 +945,7 @@ void Dynamical::load_born() for (iat = 0; iat < system->natmin; ++iat) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - diff_sym = std::max(res, std::abs(borncharge[iat][i][j]-born_sym[iat][i][j])); + diff_sym = std::max(res, std::abs(borncharge[iat][i][j]-born_sym[iat][i][j])); } } } diff --git a/include/mathfunctions.h b/include/mathfunctions.h index 786f410f..26c0ad6e 100644 --- a/include/mathfunctions.h +++ b/include/mathfunctions.h @@ -14,7 +14,7 @@ #include template -inline void matmul3(T ret[3][3], T amat[3][3], T bmat[3][3]) { +inline void matmul3(T ret[3][3], const T amat[3][3], const T bmat[3][3]) { int i, j, k; T ret_tmp[3][3]; From 5baf92d997303494507a29eb3c7ad4b041f3ed8a Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 17 Nov 2017 22:15:33 +0900 Subject: [PATCH 02/33] Change var name: SymmList --> SymmData --- alm/constraint.cpp | 4 ++-- alm/fcs.cpp | 4 ++-- alm/fitting.cpp | 4 ++-- alm/patterndisp.cpp | 4 ++-- alm/patterndisp.h | 4 ++-- alm/symmetry.cpp | 34 +++++++++++++++++----------------- alm/symmetry.h | 5 +++-- 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index efadccf4..933b9add 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -562,7 +562,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou std::vector > const_mat; for (isym = 0; isym < symmetry->nsym; ++isym) { - if (symmetry->SymmList[isym].compatible_with_cartesian) continue; + if (symmetry->SymmData[isym].compatible_with_cartesian) continue; has_constraint_from_symm = true; } @@ -639,7 +639,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou for (isym = 0; isym < symmetry->nsym; ++isym) { - if (symmetry->SymmList[isym].compatible_with_cartesian) continue; + if (symmetry->SymmData[isym].compatible_with_cartesian) continue; for (i = 0; i < order + 2; ++i) atm_index_symm[i] = symmetry->map_sym[atm_index[i]][isym]; diff --git a/alm/fcs.cpp b/alm/fcs.cpp index 2aae731e..0e21d616 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -155,7 +155,7 @@ void Fcs::generate_fclists(int maxorder) for (isym = 0; isym < symmetry->nsym; ++isym) { - if (!symmetry->SymmList[isym].compatible_with_cartesian) continue; + if (!symmetry->SymmData[isym].compatible_with_cartesian) continue; for (i = 0; i < order + 2; ++i) atmn_mapped[i] = symmetry->map_sym[atmn[i]][isym]; @@ -253,7 +253,7 @@ double Fcs::coef_sym(const int n, int i; for (i = 0; i < n; ++i) { - tmp *= symmetry->SymmList[symnum].rotation_cart[arr2[i]][arr1[i]]; + tmp *= symmetry->SymmData[symnum].rotation_cart[arr2[i]][arr1[i]]; } return tmp; } diff --git a/alm/fitting.cpp b/alm/fitting.cpp index 0fa431f7..bb4775e4 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -379,8 +379,8 @@ void Fitting::data_multiplier(const int nat, f_rot[k] = f_tmp[3 * nat * i + 3 * j + k]; } - rotvec(u_rot, u_rot, symmetry->SymmList[isym].rotation_cart); - rotvec(f_rot, f_rot, symmetry->SymmList[isym].rotation_cart); + rotvec(u_rot, u_rot, symmetry->SymmData[isym].rotation_cart); + rotvec(f_rot, f_rot, symmetry->SymmData[isym].rotation_cart); for (k = 0; k < 3; ++k) { u[nmulti * idata + isym][3 * n_mapped + k] = u_rot[k]; diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index a251f61c..e91e2720 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -336,7 +336,7 @@ void Displace::find_unique_sign_pairs(const int N, disp_sym[mapped_atom][j] = 0.0; for (k = 0; k < 3; ++k) { disp_sym[mapped_atom][j] - += symmetry->SymmList[isym].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; + += symmetry->SymmData[isym].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; } disp_tmp = disp_sym[mapped_atom][j]; @@ -389,7 +389,7 @@ void Displace::find_unique_sign_pairs(const int N, for (j = 0; j < 3; ++j) { disp_sym[mapped_atom][j] = 0.0; for (k = 0; k < 3; ++k) { - disp_sym[mapped_atom][j] += symmetry->SymmList[symnum_vec[isym]].rotation_cart[j][k] + disp_sym[mapped_atom][j] += symmetry->SymmData[symnum_vec[isym]].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; } disp_tmp = disp_sym[mapped_atom][j]; diff --git a/alm/patterndisp.h b/alm/patterndisp.h index 768dd3e8..1bb23cb4 100644 --- a/alm/patterndisp.h +++ b/alm/patterndisp.h @@ -26,7 +26,7 @@ namespace ALM_NS DispAtomSet(std::vector vec) { - for (std::vector::iterator it = vec.begin(); it != vec.end(); ++it) { + for (auto it = vec.begin(); it != vec.end(); ++it) { atomset.push_back((*it)); } } @@ -56,7 +56,7 @@ namespace ALM_NS DispDirectionHarmonic(int n, std::vector list_in) { atom = n; - for (std::vector::iterator it = list_in.begin(); it != list_in.end(); ++it) { + for (auto it = list_in.begin(); it != list_in.end(); ++it) { directionlist.push_back(*it); } } diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index fd44e254..6bad92b4 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -39,7 +39,7 @@ Symmetry::~Symmetry() memory->deallocate(map_p2s); memory->deallocate(map_s2p); memory->deallocate(symnum_tran); - SymmList.clear(); + SymmData.clear(); } void Symmetry::init() @@ -54,7 +54,7 @@ void Symmetry::init() system->lavec, system->rlavec, system->xcoord, system->kd); - std::cout << " Number of symmetry operations = " << SymmList.size() << std::endl; + std::cout << " Number of symmetry operations = " << SymmData.size() << std::endl; // int nsym_fc; @@ -107,7 +107,7 @@ void Symmetry::setup_symmetry_operation(int nat, { int i, j; - SymmList.clear(); + SymmData.clear(); if (nsym == 0) { @@ -117,11 +117,11 @@ void Symmetry::setup_symmetry_operation(int nat, std::cout << " Please be patient. " << std::endl; std::cout << " This can take a while for a large supercell." << std::endl << std::endl; - findsym(nat, aa, x, SymmList); - // The order in SymmList changes for each run because it was generated + findsym(nat, aa, x, SymmData); + // The order in SymmData changes for each run because it was generated // with OpenMP. Therefore, we sort the list here to have the same result. - std::sort(SymmList.begin() + 1, SymmList.end()); - nsym = SymmList.size(); + std::sort(SymmData.begin() + 1, SymmData.end()); + nsym = SymmData.size(); if (is_printsymmetry) { std::ofstream ofs_sym; @@ -130,7 +130,7 @@ void Symmetry::setup_symmetry_operation(int nat, ofs_sym.open(file_sym.c_str(), std::ios::out); ofs_sym << nsym << std::endl; - for (auto p = SymmList.begin(); p != SymmList.end(); ++p) { + for (auto p = SymmData.begin(); p != SymmData.end(); ++p) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { ofs_sym << std::setw(4) << (*p).rotation[i][j]; @@ -170,7 +170,7 @@ void Symmetry::setup_symmetry_operation(int nat, tran_tmp[i] = 0.0; } - SymmList.push_back(SymmetryOperation(rot_tmp, + SymmData.push_back(SymmetryOperation(rot_tmp, tran_tmp, rot_cart_tmp, true, @@ -203,7 +203,7 @@ void Symmetry::setup_symmetry_operation(int nat, >> tran_tmp[0] >> tran_tmp[1] >> tran_tmp[2]; symop_in_cart(rot_cart_tmp, rot_tmp, system->lavec, system->rlavec); - SymmList.push_back(SymmetryOperation(rot_tmp, + SymmData.push_back(SymmetryOperation(rot_tmp, tran_tmp, rot_cart_tmp, is_compatible(rot_tmp), @@ -575,7 +575,7 @@ void Symmetry::pure_translations() ntran = 0; for (i = 0; i < nsym; ++i) { - if (SymmList[i].is_translation) ++ntran; + if (SymmData[i].is_translation) ++ntran; } nat_prim = system->nat / ntran; @@ -599,7 +599,7 @@ void Symmetry::pure_translations() int isym = 0; for (i = 0; i < nsym; ++i) { - if (SymmList[i].is_translation) symnum_tran[isym++] = i; + if (SymmData[i].is_translation) symnum_tran[isym++] = i; } } @@ -630,7 +630,7 @@ void Symmetry::genmaps(int nat, for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - rot_double[i][j] = static_cast(SymmList[isym].rotation[i][j]); + rot_double[i][j] = static_cast(SymmData[isym].rotation[i][j]); } } @@ -642,7 +642,7 @@ void Symmetry::genmaps(int nat, rotvec(xnew, x[iat], rot_double); - for (i = 0; i < 3; ++i) xnew[i] += SymmList[isym].tran[i]; + for (i = 0; i < 3; ++i) xnew[i] += SymmData[isym].tran[i]; for (jj = 0; jj < system->atomlist_class[itype].size(); ++jj) { @@ -756,8 +756,8 @@ void Symmetry::print_symmetrized_coordinate(double **x) } } - for (std::vector::iterator it = SymmList.begin(); - it != SymmList.end(); ++it) { + for (std::vector::iterator it = SymmData.begin(); + it != SymmData.end(); ++it) { ++isym; std::cout << "Symmetry No. : " << std::setw(5) << isym << std::endl; @@ -883,7 +883,7 @@ void Symmetry::print_symmetrized_coordinate(double **x) for (i = 0; i < nat; ++i) { for (j = 0; j < 3; ++j) { - x_avg[i][j] /= static_cast(SymmList.size()); + x_avg[i][j] /= static_cast(SymmData.size()); } } diff --git a/alm/symmetry.h b/alm/symmetry.h index 074c5cdf..8836cfa1 100644 --- a/alm/symmetry.h +++ b/alm/symmetry.h @@ -1,7 +1,7 @@ /* symmetry.h - Copyright (c) 2014, 2015, 2016 Terumasa Tadano + Copyright (c) 2014--2017 Terumasa Tadano This file is distributed under the terms of the MIT license. Please see the file 'LICENCE.txt' in the root directory @@ -54,6 +54,7 @@ namespace ALM_NS is_translation = is_trans_in; } + // Operator definition to sort bool operator<(const SymmetryOperation &a) const { std::vector v1, v2; @@ -126,7 +127,7 @@ namespace ALM_NS int trev_sym_mag; - std::vector SymmList; + std::vector SymmData; private: From 9ca5325ddd91efef7c2ae4e10a2e917f627779d3 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 17 Nov 2017 22:40:05 +0900 Subject: [PATCH 03/33] clean up the codes --- alm/constraint.cpp | 24 +++++++++++++----------- alm/fcs.cpp | 6 ------ alm/fcs.h | 7 +------ alm/symmetry.cpp | 2 +- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 933b9add..beb6500f 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -28,7 +28,9 @@ using namespace ALM_NS; -Constraint::Constraint(ALM *alm) : Pointers(alm) {} +Constraint::Constraint(ALM *alm) : Pointers(alm) +{ +} Constraint::~Constraint() { @@ -559,7 +561,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou double *arr_constraint; bool has_constraint_from_symm = false; std::set list_found; - std::vector > const_mat; + std::vector> const_mat; for (isym = 0; isym < symmetry->nsym; ++isym) { if (symmetry->SymmData[isym].compatible_with_cartesian) continue; @@ -616,7 +618,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou std::set::iterator iter_found; std::vector const_now_omp; - std::vector > const_omp; + std::vector> const_omp; memory->allocate(ind, order + 2); memory->allocate(atm_index, order + 2); @@ -682,7 +684,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou // Merge vectors #pragma omp critical { - for (std::vector >::iterator it = const_omp.begin(); + for (std::vector>::iterator it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } @@ -699,7 +701,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou } // close openmp region memory->allocate(arr_constraint, nparams); - for (std::vector >::reverse_iterator it = const_mat.rbegin(); + for (std::vector>::reverse_iterator it = const_mat.rbegin(); it != const_mat.rend(); ++it) { for (i = 0; i < (*it).size(); ++i) { arr_constraint[i] = (*it)[i]; @@ -752,11 +754,11 @@ void Constraint::translational_invariance() std::vector intlist, data; std::set list_found; std::set::iterator iter_found; - std::vector > data_vec; + std::vector> data_vec; std::vector list_vec; std::vector::iterator iter_vec; std::vector const_now; - std::vector > const_mat; + std::vector> const_mat; std::cout << " Generating constraints for translational invariance ..." << std::endl; @@ -888,7 +890,7 @@ void Constraint::translational_invariance() memory->allocate(intarr_omp, order + 2); memory->allocate(intarr_copy_omp, order + 2); - std::vector > const_omp; + std::vector> const_omp; std::vector data_omp; std::vector const_now_omp; @@ -953,7 +955,7 @@ void Constraint::translational_invariance() // Merge vectors #pragma omp critical { - for (std::vector >::iterator it = const_omp.begin(); + for (std::vector>::iterator it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } @@ -983,7 +985,7 @@ void Constraint::translational_invariance() // Copy to constraint class const_translation[order].clear(); - for (std::vector >::reverse_iterator it = const_mat.rbegin(); + for (std::vector>::reverse_iterator it = const_mat.rbegin(); it != const_mat.rend(); ++it) { for (i = 0; i < (*it).size(); ++i) { arr_constraint[i] = static_cast((*it)[i]); @@ -1047,7 +1049,7 @@ void Constraint::rotational_invariance() CombinationWithRepetition g; std::vector atom_tmp; - std::vector > cell_dummy; + std::vector> cell_dummy; std::set::iterator iter_cluster; setup_rotation_axis(valid_rotation_axis); diff --git a/alm/fcs.cpp b/alm/fcs.cpp index 0e21d616..7fd560c9 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -42,12 +42,9 @@ void Fcs::init() std::cout << " FORCE CONSTANT" << std::endl; std::cout << " ==============" << std::endl << std::endl; - memory->allocate(nints, maxorder); - memory->allocate(nzero, maxorder); memory->allocate(fc_set, maxorder); memory->allocate(ndup, maxorder); - for (i = 0; i < maxorder; ++i) nzero[i] = 0; generate_fclists(maxorder); std::cout << std::endl; @@ -76,8 +73,6 @@ void Fcs::init() } } - memory->deallocate(nints); - memory->deallocate(nzero); timer->print_elapsed(); std::cout << " -------------------------------------------------------------------" << std::endl; std::cout << std::endl; @@ -219,7 +214,6 @@ void Fcs::generate_fclists(int maxorder) if (is_zero) { for (i = 0; i < ndeps; ++i) fc_set[order].pop_back(); - ++nzero[order]; } else { ndup[order].push_back(ndeps); ++nmother; diff --git a/alm/fcs.h b/alm/fcs.h index edf22db3..49a75247 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -30,8 +30,7 @@ namespace ALM_NS { coef = obj.coef; mother = obj.mother; - for (std::vector::const_iterator it = obj.elems.begin(); - it != obj.elems.end(); ++it) { + for (auto it = obj.elems.begin(); it != obj.elems.end(); ++it) { elems.push_back(*it); } }; @@ -60,8 +59,6 @@ namespace ALM_NS void init(); - int *nzero; - std::vector *ndup; std::vector *fc_set; @@ -75,9 +72,7 @@ namespace ALM_NS double coef_sym(const int, const int, const int *, const int *); private: - int *nints; void generate_fclists(int); bool is_ascending(const int, const int *); }; } - diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index 6bad92b4..4498da29 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -138,7 +138,7 @@ void Symmetry::setup_symmetry_operation(int nat, } ofs_sym << " "; for (i = 0; i < 3; ++i) { - ofs_sym << std::setprecision(15) << std::setw(20) << (*p).tran[i]; + ofs_sym << std::setprecision(15) << std::setw(21) << (*p).tran[i]; } ofs_sym << std::endl; } From 16038ea06af091ccb143a7d1e1fdbcd08b030ce4 Mon Sep 17 00:00:00 2001 From: "Terumasa TADANO (windows)" Date: Sun, 19 Nov 2017 02:54:38 +0900 Subject: [PATCH 04/33] Changed variable name in FcProperty as coef --> sign --- alm/constraint.cpp | 28 ++++++++++++++-------------- alm/fcs.cpp | 12 ++++++------ alm/fcs.h | 20 +++++++++++++++----- alm/fitting.cpp | 4 ++-- alm/system.cpp | 4 ++-- alm/writes.cpp | 10 +++++----- 6 files changed, 44 insertions(+), 34 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index beb6500f..7e08089d 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -594,7 +594,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou list_found.clear(); for (auto p = fcs->fc_set[order].begin(); p != fcs->fc_set[order].end(); ++p) { for (i = 0; i < order + 2; ++i) index_tmp[i] = (*p).elems[i]; - list_found.insert(FcProperty(order + 2, (*p).coef, + list_found.insert(FcProperty(order + 2, (*p).sign, index_tmp, (*p).mother)); } @@ -649,7 +649,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou for (i = 0; i < nparams; ++i) const_now_omp[i] = 0.0; - const_now_omp[list_tmp.mother] = -list_tmp.coef; + const_now_omp[list_tmp.mother] = -list_tmp.sign; for (ixyz = 0; ixyz < nxyz; ++ixyz) { for (i = 0; i < order + 2; ++i) @@ -662,7 +662,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); if (iter_found != list_found.end()) { c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); - const_now_omp[(*iter_found).mother] += (*iter_found).coef * c_tmp; + const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; } } @@ -786,11 +786,11 @@ void Constraint::translational_invariance() for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } - if (list_found.find(FcProperty(order + 2, (*p).coef, + if (list_found.find(FcProperty(order + 2, (*p).sign, ind, (*p).mother)) != list_found.end()) { error->exit("translational invariance", "Duplicate interaction list found"); } - list_found.insert(FcProperty(order + 2, (*p).coef, + list_found.insert(FcProperty(order + 2, (*p).sign, ind, (*p).mother)); } @@ -831,7 +831,7 @@ void Constraint::translational_invariance() // If found a IFC if (iter_found != list_found.end()) { // Round the coefficient to integer - const_now[(*iter_found).mother] += nint((*iter_found).coef); + const_now[(*iter_found).mother] += nint((*iter_found).sign); } } @@ -932,7 +932,7 @@ void Constraint::translational_invariance() iter_found = list_found.find(FcProperty(order + 2, 1.0, intarr_copy_omp, 1)); if (iter_found != list_found.end()) { - const_now_omp[(*iter_found).mother] += nint((*iter_found).coef); + const_now_omp[(*iter_found).mother] += nint((*iter_found).sign); } } @@ -1093,7 +1093,7 @@ void Constraint::rotational_invariance() for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } - list_found.insert(FcProperty(order + 2, (*p).coef, + list_found.insert(FcProperty(order + 2, (*p).sign, ind, (*p).mother)); } @@ -1164,7 +1164,7 @@ void Constraint::rotational_invariance() if (iter_found != list_found.end()) { arr_constraint[(*iter_found).mother] - += (*iter_found).coef * vec_for_rot[nu]; + += (*iter_found).sign * vec_for_rot[nu]; } // Exchange mu <--> nu and repeat again. @@ -1175,7 +1175,7 @@ void Constraint::rotational_invariance() interaction_index, 1)); if (iter_found != list_found.end()) { arr_constraint[(*iter_found).mother] - -= (*iter_found).coef * vec_for_rot[mu]; + -= (*iter_found).sign * vec_for_rot[mu]; } } @@ -1309,7 +1309,7 @@ void Constraint::rotational_invariance() iter_found = list_found.find(FcProperty(order + 2, 1.0, interaction_tmp, 1)); if (iter_found != list_found.end()) { arr_constraint[nparams[order - 1] + (*iter_found).mother] - += (*iter_found).coef * vec_for_rot[nu]; + += (*iter_found).sign * vec_for_rot[nu]; } // Exchange mu <--> nu and repeat again. @@ -1322,7 +1322,7 @@ void Constraint::rotational_invariance() iter_found = list_found.find(FcProperty(order + 2, 1.0, interaction_tmp, 1)); if (iter_found != list_found.end()) { arr_constraint[nparams[order - 1] + (*iter_found).mother] - -= (*iter_found).coef * vec_for_rot[mu]; + -= (*iter_found).sign * vec_for_rot[mu]; } } @@ -1350,7 +1350,7 @@ void Constraint::rotational_invariance() interaction_tmp, 1)); if (iter_found != list_found_last.end()) { arr_constraint[(*iter_found).mother] - += (*iter_found).coef * static_cast(levi_factor); + += (*iter_found).sign * static_cast(levi_factor); } } } @@ -1442,7 +1442,7 @@ void Constraint::rotational_invariance() interaction_tmp, 1)); if (iter_found != list_found.end()) { arr_constraint_self[(*iter_found).mother] - += (*iter_found).coef * static_cast(levi_factor); + += (*iter_found).sign * static_cast(levi_factor); } } // jcrd } // lambda diff --git a/alm/fcs.cpp b/alm/fcs.cpp index 7fd560c9..b714aa9d 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -26,13 +26,9 @@ using namespace ALM_NS; -Fcs::Fcs(ALM *alm) : Pointers(alm) -{ -}; +Fcs::Fcs(ALM *alm) : Pointers(alm) {}; -Fcs::~Fcs() -{ -}; +Fcs::~Fcs() {}; void Fcs::init() { @@ -56,6 +52,10 @@ void Fcs::init() } std::cout << std::endl; + for (auto it = ndup[0].begin(); it != ndup[0].end(); ++it) { + std::cout << (*it) << std::endl; + } + // sort fc_set for (int order = 0; order < maxorder; ++order) { diff --git a/alm/fcs.h b/alm/fcs.h index 49a75247..567bf986 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -20,15 +20,15 @@ namespace ALM_NS class FcProperty { public: - std::vector elems; - double coef; - int mother; + std::vector elems; // flattened index of (iatom, icoordinate) in the supercell + double sign; // factor (+1 or -1) to convert the mother FC to the child + int mother; FcProperty(); FcProperty(const FcProperty &obj) { - coef = obj.coef; + sign = obj.sign; mother = obj.mother; for (auto it = obj.elems.begin(); it != obj.elems.end(); ++it) { elems.push_back(*it); @@ -37,7 +37,7 @@ namespace ALM_NS FcProperty(const int n, const double c, const int *arr, const int m) { - coef = c; + sign = c; mother = m; for (int i = 0; i < n; ++i) { elems.push_back(arr[i]); @@ -51,6 +51,16 @@ namespace ALM_NS } }; + class ForceConstantTable + { + public: + double fc_value; + int multiplicity; + std::vector fclist; + ForceConstantTable(); + + }; + class Fcs: protected Pointers { public: diff --git a/alm/fitting.cpp b/alm/fitting.cpp index bb4775e4..9569b7ef 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -1063,7 +1063,7 @@ void Fitting::calc_matrix_elements(const int M, ind[j] = fcs->fc_set[order][mm].elems[j]; amat_tmp *= u[irow][fcs->fc_set[order][mm].elems[j]]; } - amat[k][iparam] -= gamma(order + 2, ind) * fcs->fc_set[order][mm].coef * amat_tmp; + amat[k][iparam] -= gamma(order + 2, ind) * fcs->fc_set[order][mm].sign * amat_tmp; ++mm; } ++iparam; @@ -1175,7 +1175,7 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, ind[j] = fcs->fc_set[order][mm].elems[j]; amat_tmp *= u[irow][fcs->fc_set[order][mm].elems[j]]; } - amat_orig[k][iparam] -= gamma(order + 2, ind) * fcs->fc_set[order][mm].coef * amat_tmp; + amat_orig[k][iparam] -= gamma(order + 2, ind) * fcs->fc_set[order][mm].sign * amat_tmp; ++mm; } ++iparam; diff --git a/alm/system.cpp b/alm/system.cpp index b034ffd9..396b4f9a 100644 --- a/alm/system.cpp +++ b/alm/system.cpp @@ -320,7 +320,7 @@ void System::load_reference_system_xml(std::string file_reference_fcs, for (i = 0; i < nterms; ++i) { ind[i] = list_tmp.elems[i]; } - list_found.insert(FcProperty(nterms, list_tmp.coef, + list_found.insert(FcProperty(nterms, list_tmp.sign, ind, list_tmp.mother)); } @@ -507,7 +507,7 @@ void System::load_reference_system() for (std::vector::iterator p = fcs->fc_set[0].begin(); p != fcs->fc_set[0].end(); ++p) { for (i = 0; i < 2; ++i) ind[i] = (*p).elems[i]; - list_found.insert(FcProperty(2, (*p).coef, ind, (*p).mother)); + list_found.insert(FcProperty(2, (*p).sign, ind, (*p).mother)); } for (i = 0; i < nparam_harmonic; ++i) { diff --git a/alm/writes.cpp b/alm/writes.cpp index 809637ae..7844cc3f 100644 --- a/alm/writes.cpp +++ b/alm/writes.cpp @@ -248,7 +248,7 @@ void Writes::write_force_constants() for (j = 0; j < fcs->ndup[order][iuniq]; ++j) { ofs_fcs << std::setw(5) << j + 1 << std::setw(12) - << std::setprecision(5) << std::fixed << fcs->fc_set[order][id].coef; + << std::setprecision(5) << std::fixed << fcs->fc_set[order][id].sign; for (k = 0; k < order + 2; ++k) { ofs_fcs << std::setw(6) << fcs->easyvizint(fcs->fc_set[order][id].elems[k]); @@ -502,7 +502,7 @@ void Writes::write_misc_xml() for (std::vector::iterator it2 = interaction->mindist_pairs[pair_tmp[0]][pair_tmp[1]].begin(); it2 != interaction->mindist_pairs[pair_tmp[0]][pair_tmp[1]].end(); ++it2) { ptree &child = pt.add("Data.ForceConstants.HARMONIC.FC2", - double2string(fitting->params[ip] * fctmp.coef + double2string(fitting->params[ip] * fctmp.sign / static_cast(interaction->mindist_pairs[pair_tmp[0]][pair_tmp[1]].size()))); child.put(".pair1", boost::lexical_cast(j + 1) @@ -557,7 +557,7 @@ void Writes::write_misc_xml() std::vector cell_now = (*iter_cluster).cell[imult]; ptree &child = pt.add(elementname, - double2string(fitting->params[ip] * fctmp.coef + double2string(fitting->params[ip] * fctmp.sign / static_cast(multiplicity))); child.put(".pair1", boost::lexical_cast(j + 1) @@ -624,7 +624,7 @@ void Writes::write_hessian() pair_tran[i] = symmetry->map_sym[pair_tmp[i]][symmetry->symnum_tran[itran]]; } hessian[3 * pair_tran[0] + fctmp.elems[0] % 3][3 * pair_tran[1] + fctmp.elems[1] % 3] - = fitting->params[ip] * fctmp.coef; + = fitting->params[ip] * fctmp.sign; } } @@ -680,7 +680,7 @@ void Writes::write_hessian() ofs_fc2 << std::setw(15) << vec[2]; ofs_fc2 << std::setw(15) - << fitting->params[ip] * fctmp.coef / static_cast(multiplicity); + << fitting->params[ip] * fctmp.sign / static_cast(multiplicity); ofs_fc2 << std::endl; } } From b7497ec7127e24ca6d64865c3a9089e03126e23a Mon Sep 17 00:00:00 2001 From: "Terumasa TADANO (windows)" Date: Mon, 20 Nov 2017 13:50:31 +0900 Subject: [PATCH 05/33] Add a new function to generate independent IFCs --- alm/fcs.cpp | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++ alm/fcs.h | 13 +++- 2 files changed, 228 insertions(+), 3 deletions(-) diff --git a/alm/fcs.cpp b/alm/fcs.cpp index b714aa9d..23aa4937 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -78,6 +78,210 @@ void Fcs::init() std::cout << std::endl; } +void Fcs::generate_force_constant_table(const int order, + std::set *pairs, + std::vector *symmop, + std::string basis) +{ + int i, j; + int i1, i2; + int i_prim; + int *atmn, *atmn_mapped; + int *ind, *ind_mapped; + int *ind_tmp, *ind_mapped_tmp; + int nxyz; + unsigned int isym; + + double c_tmp; + + int **xyzcomponent; + + int nmother; + int nat = system->nat; + int nsym = symmop->size(); + int nsym_in_use; + + bool is_zero; + bool *is_searched; + int counter; + int **map_sym; + double ***rotation; + + if (order < 0) return; + + memory->allocate(rotation, nsym, 3, 3); + memory->allocate(map_sym, nat, nsym); + nsym_in_use = 0; + counter = 0; + if (basis == "Cartesian") { + + for (auto it = symmop->begin(); it != symmop->end(); ++it) { + if ((*it).compatible_with_cartesian) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + rotation[nsym_in_use][i][j] = (*it).rotation_cart[i][j]; + } + } + for (i = 0; i < nat; ++i) { + map_sym[i][nsym_in_use] = symmetry->map_sym[i][counter]; + } + ++nsym_in_use; + } + ++counter; + } + + } else if (basis == "Lattice") { + + for (auto it = symmop->begin(); it != symmop->end(); ++it) { + if ((*it).compatible_with_lattice) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + rotation[nsym_in_use][i][j] + = static_cast((*it).rotation[i][j]); + } + } + for (i = 0; i < nat; ++i) { + map_sym[i][nsym_in_use] = symmetry->map_sym[i][counter]; + } + ++nsym_in_use; + } + ++counter; + } + + + } else { + memory->deallocate(rotation); + memory->deallocate(map_sym); + error->exit("generate_force_constant_table", "Invalid basis inpout"); + } + + memory->allocate(atmn, order + 2); + memory->allocate(atmn_mapped, order + 2); + memory->allocate(ind, order + 2); + memory->allocate(ind_mapped, order + 2); + memory->allocate(ind_tmp, order); + memory->allocate(ind_mapped_tmp, order + 2); + memory->allocate(is_searched, 3 * nat); + + + fc_set[order].clear(); + ndup[order].clear(); + nmother = 0; + + nxyz = static_cast(std::pow(3.0, order + 2)); + + memory->allocate(xyzcomponent, nxyz, order + 2); + get_xyzcomponent(order + 2, xyzcomponent); + + std::set list_found; + + for (auto iter = pairs->begin(); iter != pairs->end(); ++iter) { + + for (i = 0; i < order + 2; ++i) atmn[i] = (*iter).iarray[i]; + + for (i1 = 0; i1 < nxyz; ++i1) { + for (i = 0; i < order + 2; ++i) ind[i] = 3 * atmn[i] + xyzcomponent[i1][i]; + + if (!is_ascending(order + 2, ind)) continue; + + i_prim = min_inprim(order + 2, ind); + std::swap(ind[0], ind[i_prim]); + sort_tail(order + 2, ind); + + is_zero = false; + + if (list_found.find(IntList(order + 2, ind)) != list_found.end()) continue; // Already exits! + + // Search symmetrically-dependent parameter set + + int ndeps = 0; + + for (isym = 0; isym < nsym_in_use; ++isym) { + + for (i = 0; i < order + 2; ++i) + atmn_mapped[i] = map_sym[atmn[i]][isym]; + + if (!is_inprim(order + 2, atmn_mapped)) continue; + + for (i2 = 0; i2 < nxyz; ++i2) { + // c_tmp = coef_sym(order + 2, isym, xyzcomponent[i1], xyzcomponent[i2]); + c_tmp = coef_sym(order + 2, rotation[isym], xyzcomponent[i1], xyzcomponent[i2]); + if (std::abs(c_tmp) > eps12) { + for (i = 0; i < order + 2; ++i) + ind_mapped[i] = 3 * atmn_mapped[i] + xyzcomponent[i2][i]; + + i_prim = min_inprim(order + 2, ind_mapped); + std::swap(ind_mapped[0], ind_mapped[i_prim]); + sort_tail(order + 2, ind_mapped); + + if (!is_zero) { + bool zeroflag = true; + for (i = 0; i < order + 2; ++i) { + zeroflag = zeroflag & (ind[i] == ind_mapped[i]); + } + zeroflag = zeroflag & (std::abs(c_tmp + 1.0) < eps8); + is_zero = zeroflag; + } + + // Add to found list (set) and fcset (vector) if the created is new one. + + if (list_found.find(IntList(order + 2, ind_mapped)) == list_found.end()) { + list_found.insert(IntList(order + 2, ind_mapped)); + + fc_set[order].push_back(FcProperty(order + 2, c_tmp, + ind_mapped, nmother)); + ++ndeps; + + // Add equivalent interaction list (permutation) if there are two or more indices + // which belong to the primitive cell. + // This procedure is necessary for fitting. + + for (i = 0; i < 3 * nat; ++i) is_searched[i] = false; + is_searched[ind_mapped[0]] = true; + for (i = 1; i < order + 2; ++i) { + if ((!is_searched[ind_mapped[i]]) && is_inprim(ind_mapped[i])) { + + for (j = 0; j < order + 2; ++j) ind_mapped_tmp[j] = ind_mapped[j]; + std::swap(ind_mapped_tmp[0], ind_mapped_tmp[i]); + sort_tail(order + 2, ind_mapped_tmp); + fc_set[order].push_back(FcProperty(order + 2, c_tmp, + ind_mapped_tmp, nmother)); + + ++ndeps; + + is_searched[ind_mapped[i]] = true; + } + } + + + } + } + } + } // close symmetry loop + + if (is_zero) { + for (i = 0; i < ndeps; ++i) fc_set[order].pop_back(); + } else { + ndup[order].push_back(ndeps); + ++nmother; + } + + } // close xyz component loop + } // close atom number loop (iterator) + + memory->deallocate(xyzcomponent); + list_found.clear(); + memory->deallocate(atmn); + memory->deallocate(atmn_mapped); + memory->deallocate(ind); + memory->deallocate(ind_mapped); + memory->deallocate(ind_tmp); + memory->deallocate(ind_mapped_tmp); + memory->deallocate(is_searched); + memory->deallocate(rotation); + memory->deallocate(map_sym); +} + void Fcs::generate_fclists(int maxorder) { @@ -252,6 +456,20 @@ double Fcs::coef_sym(const int n, return tmp; } +double Fcs::coef_sym(const int n, + double **rot, + const int *arr1, + const int *arr2) +{ + double tmp = 1.0; + int i; + + for (i = 0; i < n; ++i) { + tmp *= rot[arr2[i]][arr1[i]]; + } + return tmp; +} + bool Fcs::is_ascending(const int n, const int *arr) { int i; diff --git a/alm/fcs.h b/alm/fcs.h index 567bf986..e56dc78c 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -1,7 +1,7 @@ /* fcs.h - Copyright (c) 2014, 2015, 2016 Terumasa Tadano + Copyright (c) 2014--2017 Terumasa Tadano This file is distributed under the terms of the MIT license. Please see the file 'LICENCE.txt' in the root directory @@ -14,6 +14,8 @@ #include #include #include +#include "symmetry.h" +#include "interaction.h" namespace ALM_NS { @@ -22,7 +24,7 @@ namespace ALM_NS public: std::vector elems; // flattened index of (iatom, icoordinate) in the supercell double sign; // factor (+1 or -1) to convert the mother FC to the child - int mother; + int mother; FcProperty(); @@ -58,7 +60,6 @@ namespace ALM_NS int multiplicity; std::vector fclist; ForceConstantTable(); - }; class Fcs: protected Pointers @@ -83,6 +84,12 @@ namespace ALM_NS private: void generate_fclists(int); + void generate_force_constant_table(const int, + std::set *, + std::vector *, + std::string basis = "Cartesian"); + bool is_ascending(const int, const int *); + double coef_sym(const int, double **, const int *, const int *); }; } From b937d6ba9ca5367626157c83379ce44e6247834b Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Tue, 21 Nov 2017 20:27:42 +0900 Subject: [PATCH 06/33] Print out symmetry operations for debug --- alm/symmetry.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index 4498da29..e05a510a 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -69,6 +69,25 @@ void Symmetry::init() // } // std::cout << std::endl; + int counter = 0; + for (auto it = SymmData.begin(); it != SymmData.end(); ++it) { + std::cout << "Symm. No. : " << std::setw(4) << counter + 1; + std::cout << "( " << (*it).compatible_with_lattice << " " << (*it).compatible_with_cartesian << ")" << std::endl; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + std::cout << std::setw(15) << (*it).rotation[i][j]; + } + std::cout << " "; + for (j = 0; j < 3; ++j) { + std::cout << std::setw(15) << (*it).rotation_cart[i][j]; + } + + std::cout << std::endl; + } + std::cout << std::endl; + ++counter; + } + pure_translations(); memory->allocate(map_sym, nat, nsym); From 8c3931180324706e8cb70b3ba7f085e08d9fe403 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Tue, 21 Nov 2017 22:35:31 +0900 Subject: [PATCH 07/33] Debugging the error in constraint_from_symmetry for low-symmetry input --- alm/constraint.cpp | 71 +++++++++++++++++++++++++++++++------------ alm/constraint.h | 3 +- alm/symmetry.cpp | 2 +- anphon/anphon.vcxproj | 2 +- 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 7e08089d..6f02ca38 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -30,6 +30,7 @@ using namespace ALM_NS; Constraint::Constraint(ALM *alm) : Pointers(alm) { + tolerance_constraint = eps12; } Constraint::~Constraint() @@ -403,8 +404,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) memory->deallocate(const_rhs_tmp); } - for (std::vector::iterator p = const_total.begin(); - p != const_total.end(); ++p) { + for (auto p = const_total.begin(); p != const_total.end(); ++p) { for (i = 0; i < N; ++i) { const_mat[irow][i] = (*p).w_const[i]; } @@ -638,6 +638,12 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou atm_index[i] = list_tmp.elems[i] / 3; xyz_index[i] = list_tmp.elems[i] % 3; } +// std::cout << std::endl; +// std::cout << "IFC : " << std::setw(4) << ii + 1; +// for (i = 0; i < order + 2; ++i) { +// std::cout << std::setw(4) << list_tmp.elems[i]; +// } +// std::cout << std::endl; for (isym = 0; isym < symmetry->nsym; ++isym) { @@ -662,11 +668,14 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); if (iter_found != list_found.end()) { c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); + if (std::abs(c_tmp) < eps8) c_tmp = 0.0; const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; +// std::cout << " isym = " << std::setw(4) << isym + 1; +// std::cout << " iloc = " << std::setw(4) << (*iter_found).mother; +// std::cout << " coef = " << std::setw(15) << (*iter_found).sign * c_tmp << std::endl; } } - - if (!is_allzero(const_now_omp, loc_nonzero)) { + if (!is_allzero(const_now_omp, tolerance_constraint, loc_nonzero)) { if (const_now_omp[loc_nonzero] < 0.0) { for (j = 0; j < nparams; ++j) const_now_omp[j] *= -1.0; } @@ -684,8 +693,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou // Merge vectors #pragma omp critical { - for (std::vector>::iterator it = const_omp.begin(); - it != const_omp.end(); ++it) { + for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } } @@ -701,8 +709,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou } // close openmp region memory->allocate(arr_constraint, nparams); - for (std::vector>::reverse_iterator it = const_mat.rbegin(); - it != const_mat.rend(); ++it) { + for (auto it = const_mat.rbegin(); it != const_mat.rend(); ++it) { for (i = 0; i < (*it).size(); ++i) { arr_constraint[i] = (*it)[i]; } @@ -713,8 +720,13 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->deallocate(xyzcomponent); memory->deallocate(arr_constraint); + std::cout << "OK " << std::endl; + + std::cout << "Size of constraint matrix:" << std::endl; + std::cout << const_out[order].size() << std::endl; + std::cout << "tolerance_constraint = " << tolerance_constraint << std::endl; - remove_redundant_rows(nparams, const_out[order], eps8); + remove_redundant_rows(nparams, const_out[order], tolerance_constraint); if (has_constraint_from_symm) { std::cout << " done." << std::endl; @@ -1572,17 +1584,22 @@ void Constraint::remove_redundant_rows(const int n, memory->allocate(mat_tmp, nconst, nparam); + std::cout << "OK2" << std::endl; i = 0; - for (std::vector::iterator p = Constraint_vec.begin(); - p != Constraint_vec.end(); ++p) { + for (auto p = Constraint_vec.begin(); p != Constraint_vec.end(); ++p) { for (j = 0; j < nparam; ++j) { mat_tmp[i][j] = (*p).w_const[j]; } ++i; } - rref(nconst, nparam, mat_tmp, nrank, tolerance); + std::cout << "OK3" << std::endl; + + std::cout << "tolerance = " << tolerance << std::endl; + rref(nconst, nparam, mat_tmp, nrank, eps10); + + std::cout << "OK4" << std::endl; /* // // Transpose matrix A @@ -1619,6 +1636,17 @@ void Constraint::remove_redundant_rows(const int n, memory->allocate(arr_tmp, nparam); Constraint_vec.clear(); + std::cout << "RANK = " << nrank << std::endl; + +// for (i = 0; i < nrank; ++i) { +// for (j = 0; j < nparam; ++j) { +// std::cout << std::setw(15) << mat_tmp[i][j]; +// } +// std::cout << std::endl; +// } +// std::cout << std::endl; +// +// std::cout << "OK4.5" << std::endl; for (i = 0; i < nrank; ++i) { for (j = 0; j < i; ++j) arr_tmp[j] = 0.0; @@ -1627,10 +1655,16 @@ void Constraint::remove_redundant_rows(const int n, arr_tmp[j] = mat_tmp[i][j]; } Constraint_vec.push_back(ConstraintClass(nparam, arr_tmp)); + std::cout << "add " << std::setw(4) << i << std::endl; } + + std::cout << "matrix size after reduction: " << Constraint_vec.size() << std::endl; + std::cout << "OK5" << std::endl; + memory->deallocate(mat_tmp); memory->deallocate(arr_tmp); + } #endif @@ -1664,11 +1698,11 @@ bool Constraint::is_allzero(const std::vector vec, int &loc) return true; } -bool Constraint::is_allzero(const std::vector vec, int &loc) +bool Constraint::is_allzero(const std::vector vec, const double tol, int &loc) { loc = -1; for (int i = 0; i < vec.size(); ++i) { - if (std::abs(vec[i]) > eps) { + if (std::abs(vec[i]) > tol) { loc = i; return false; } @@ -1735,9 +1769,7 @@ void Constraint::rref(int nrows, int irow, icol, jrow, jcol; int pivot; - double tmp, *arr; - - memory->allocate(arr, ncols); + double tmp; nrank = 0; @@ -1760,7 +1792,8 @@ void Constraint::rref(int nrows, if (icol == ncols) break; - if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; + std::cout << mat[pivot][icol] << std::endl; + if (std::abs(mat[pivot][icol]) >= tolerance) ++nrank; if (pivot != irow) { #pragma omp parallel for private(tmp) @@ -1788,6 +1821,4 @@ void Constraint::rref(int nrows, } } } - - memory->deallocate(arr); } diff --git a/alm/constraint.h b/alm/constraint.h index c5c36015..8c1071b4 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -95,6 +95,7 @@ namespace ALM_NS double **const_mat; double *const_rhs; + double tolerance_constraint; bool exist_constraint; bool extra_constraint_from_symmetry; @@ -131,7 +132,7 @@ namespace ALM_NS void setup_rotation_axis(bool [3][3]); bool is_allzero(const int, const double *, const int nshift = 0); bool is_allzero(const std::vector, int &); - bool is_allzero(const std::vector, int &); + bool is_allzero(const std::vector, const double, int &); void remove_redundant_rows(const int, std::vector &, const double tolerance = eps12); diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index e05a510a..c5a94596 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -233,7 +233,7 @@ void Symmetry::setup_symmetry_operation(int nat, } #ifdef _DEBUG - print_symmetrized_coordinate(x); + // print_symmetrized_coordinate(x); #endif } diff --git a/anphon/anphon.vcxproj b/anphon/anphon.vcxproj index 4390d6a1..9661b3f3 100644 --- a/anphon/anphon.vcxproj +++ b/anphon/anphon.vcxproj @@ -43,7 +43,7 @@ $(UniversalCRT_LibraryPath_x86);$(MSMPI_LIB32);C:\fftw3\lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86) - $(UniversalCRT_IncludePath);$(MSMPI_INC);$(MSMPI_INC)x86;C:\fftw3\include;C:\boost\boost_1_60_0;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath) + C:\eigen_c++;$(UniversalCRT_IncludePath);$(MSMPI_INC);$(MSMPI_INC)x86;C:\fftw3\include;C:\boost\boost_1_60_0;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath) $(UniversalCRT_LibraryPath_x86);$(MSMPI_LIB32);C:\fftw3\lib;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86); From 01a9bc608668a292498b717abb238179348b4304 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Thu, 23 Nov 2017 19:48:56 +0900 Subject: [PATCH 08/33] Debugging constraint.cpp ... --- alm/constraint.cpp | 19 ++++++++++++------- alm/patterndisp.cpp | 10 ++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 6f02ca38..bd932404 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -423,7 +423,7 @@ void Constraint::get_mapping_constraint(const int nmax, { int order; unsigned int i; - double const_tol = eps8; + //double const_tol = eps8; bool *fix_forceconstant; std::string *file_forceconstant; @@ -470,7 +470,9 @@ void Constraint::get_mapping_constraint(const int nmax, p != const_in[order].rend(); ++p) { p_index_target = -1; for (i = 0; i < nparam; ++i) { - if (std::abs((*p).w_const[i]) > const_tol) { + std::cout << "scan :" << std::setw(5) << i + 1 + << " " << std::scientific << std::setw(15) << (*p).w_const[i] << std::endl; + if (std::abs((*p).w_const[i]) > eps) { p_index_target = i; break; } @@ -485,7 +487,7 @@ void Constraint::get_mapping_constraint(const int nmax, p_index_tmp.clear(); for (i = p_index_target + 1; i < nparam; ++i) { - if (std::abs((*p).w_const[i]) > const_tol) { + if (std::abs((*p).w_const[i]) > tolerance_constraint) { alpha_tmp.push_back((*p).w_const[i]); p_index_tmp.push_back(i); } @@ -1597,7 +1599,7 @@ void Constraint::remove_redundant_rows(const int n, std::cout << "OK3" << std::endl; std::cout << "tolerance = " << tolerance << std::endl; - rref(nconst, nparam, mat_tmp, nrank, eps10); + rref(nconst, nparam, mat_tmp, nrank, eps8); std::cout << "OK4" << std::endl; @@ -1655,10 +1657,8 @@ void Constraint::remove_redundant_rows(const int n, arr_tmp[j] = mat_tmp[i][j]; } Constraint_vec.push_back(ConstraintClass(nparam, arr_tmp)); - std::cout << "add " << std::setw(4) << i << std::endl; } - std::cout << "matrix size after reduction: " << Constraint_vec.size() << std::endl; std::cout << "OK5" << std::endl; @@ -1793,7 +1793,7 @@ void Constraint::rref(int nrows, if (icol == ncols) break; std::cout << mat[pivot][icol] << std::endl; - if (std::abs(mat[pivot][icol]) >= tolerance) ++nrank; +// if (std::abs(mat[pivot][icol]) >= tolerance) ++nrank; if (pivot != irow) { #pragma omp parallel for private(tmp) @@ -1821,4 +1821,9 @@ void Constraint::rref(int nrows, } } } + + int nmin = std::min(nrows, ncols); + for (int i = 0; i < nmin; ++i) { + if (std::abs(mat[i][i]) > tolerance) ++nrank; + } } diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index e91e2720..3010a2e9 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -57,6 +57,16 @@ void Displace::gen_displacement_pattern() memory->allocate(index_bimap_tmp, maxorder); constraint->constraint_from_symmetry(constsym); + int counter =0; + for (auto it = constsym[0].begin(); it != constsym[0].end(); ++it) { + std::cout << "Const : " << std::setw(5) << counter + 1; + for (auto it1 = (*it).w_const.begin(); it1 != (*it).w_const.end(); ++it1) { + std::cout << std::setw(15) << (*it1); + } + std::cout << std::endl; + ++counter; + } + std::cout << std::endl; constraint->get_mapping_constraint(maxorder, constsym, const_fix_tmp, const_relate_tmp, index_bimap_tmp, true); From c3d5caa7868a6506be0942f53427fe3e00e46362 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Thu, 23 Nov 2017 22:01:14 +0900 Subject: [PATCH 09/33] Use the larger value (1.0e-6) for regarding as non-zero pivot in rref. This threshould may be too large for strongly disroted cells where the symmetry is not perfectly met. In near future, we should implement a function to symmetrize the structure before generating constraints between IFCs due to the space group symmetries. --- alm/constraint.cpp | 59 +++++++++++++-------------------------------- alm/patterndisp.cpp | 18 +++++++------- 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index bd932404..5f744880 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -30,7 +30,7 @@ using namespace ALM_NS; Constraint::Constraint(ALM *alm) : Pointers(alm) { - tolerance_constraint = eps12; + tolerance_constraint = eps6; } Constraint::~Constraint() @@ -470,9 +470,7 @@ void Constraint::get_mapping_constraint(const int nmax, p != const_in[order].rend(); ++p) { p_index_target = -1; for (i = 0; i < nparam; ++i) { - std::cout << "scan :" << std::setw(5) << i + 1 - << " " << std::scientific << std::setw(15) << (*p).w_const[i] << std::endl; - if (std::abs((*p).w_const[i]) > eps) { + if (std::abs((*p).w_const[i]) > tolerance_constraint) { p_index_target = i; break; } @@ -670,14 +668,14 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); if (iter_found != list_found.end()) { c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); - if (std::abs(c_tmp) < eps8) c_tmp = 0.0; + // if (std::abs(c_tmp) < eps6) c_tmp = 0.0; const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; // std::cout << " isym = " << std::setw(4) << isym + 1; // std::cout << " iloc = " << std::setw(4) << (*iter_found).mother; // std::cout << " coef = " << std::setw(15) << (*iter_found).sign * c_tmp << std::endl; } } - if (!is_allzero(const_now_omp, tolerance_constraint, loc_nonzero)) { + if (!is_allzero(const_now_omp, eps8, loc_nonzero)) { if (const_now_omp[loc_nonzero] < 0.0) { for (j = 0; j < nparams; ++j) const_now_omp[j] *= -1.0; } @@ -722,11 +720,10 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->deallocate(xyzcomponent); memory->deallocate(arr_constraint); - std::cout << "OK " << std::endl; - std::cout << "Size of constraint matrix:" << std::endl; - std::cout << const_out[order].size() << std::endl; - std::cout << "tolerance_constraint = " << tolerance_constraint << std::endl; +// std::cout << "Size of constraint matrix:" << std::endl; +// std::cout << const_out[order].size() << std::endl; +// std::cout << "tolerance_constraint = " << tolerance_constraint << std::endl; remove_redundant_rows(nparams, const_out[order], tolerance_constraint); @@ -1586,7 +1583,6 @@ void Constraint::remove_redundant_rows(const int n, memory->allocate(mat_tmp, nconst, nparam); - std::cout << "OK2" << std::endl; i = 0; for (auto p = Constraint_vec.begin(); p != Constraint_vec.end(); ++p) { @@ -1596,12 +1592,7 @@ void Constraint::remove_redundant_rows(const int n, ++i; } - std::cout << "OK3" << std::endl; - - std::cout << "tolerance = " << tolerance << std::endl; - rref(nconst, nparam, mat_tmp, nrank, eps8); - - std::cout << "OK4" << std::endl; + rref(nconst, nparam, mat_tmp, nrank, tolerance); /* // // Transpose matrix A @@ -1638,30 +1629,20 @@ void Constraint::remove_redundant_rows(const int n, memory->allocate(arr_tmp, nparam); Constraint_vec.clear(); - std::cout << "RANK = " << nrank << std::endl; - -// for (i = 0; i < nrank; ++i) { -// for (j = 0; j < nparam; ++j) { -// std::cout << std::setw(15) << mat_tmp[i][j]; -// } -// std::cout << std::endl; -// } -// std::cout << std::endl; -// -// std::cout << "OK4.5" << std::endl; for (i = 0; i < nrank; ++i) { for (j = 0; j < i; ++j) arr_tmp[j] = 0.0; for (j = i; j < nparam; ++j) { - arr_tmp[j] = mat_tmp[i][j]; + if (std::abs(mat_tmp[i][j]) < tolerance) { + arr_tmp[j] = 0.0; + } else { + arr_tmp[j] = mat_tmp[i][j]; + } } Constraint_vec.push_back(ConstraintClass(nparam, arr_tmp)); } - std::cout << "matrix size after reduction: " << Constraint_vec.size() << std::endl; - std::cout << "OK5" << std::endl; - memory->deallocate(mat_tmp); memory->deallocate(arr_tmp); @@ -1792,11 +1773,10 @@ void Constraint::rref(int nrows, if (icol == ncols) break; - std::cout << mat[pivot][icol] << std::endl; -// if (std::abs(mat[pivot][icol]) >= tolerance) ++nrank; + if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; if (pivot != irow) { -#pragma omp parallel for private(tmp) +//#pragma omp parallel for private(tmp) for (jcol = icol; jcol < ncols; ++jcol) { tmp = mat[pivot][jcol]; mat[pivot][jcol] = mat[irow][jcol]; @@ -1806,7 +1786,7 @@ void Constraint::rref(int nrows, tmp = mat[irow][icol]; tmp = 1.0 / tmp; -#pragma omp parallel for +//#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[irow][jcol] *= tmp; } @@ -1815,15 +1795,10 @@ void Constraint::rref(int nrows, if (jrow == irow) continue; tmp = mat[jrow][icol]; -#pragma omp parallel for +//#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[jrow][jcol] -= tmp * mat[irow][jcol]; } } } - - int nmin = std::min(nrows, ncols); - for (int i = 0; i < nmin; ++i) { - if (std::abs(mat[i][i]) > tolerance) ++nrank; - } } diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index 3010a2e9..cf9ad3c1 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -58,15 +58,15 @@ void Displace::gen_displacement_pattern() constraint->constraint_from_symmetry(constsym); int counter =0; - for (auto it = constsym[0].begin(); it != constsym[0].end(); ++it) { - std::cout << "Const : " << std::setw(5) << counter + 1; - for (auto it1 = (*it).w_const.begin(); it1 != (*it).w_const.end(); ++it1) { - std::cout << std::setw(15) << (*it1); - } - std::cout << std::endl; - ++counter; - } - std::cout << std::endl; +// for (auto it = constsym[0].begin(); it != constsym[0].end(); ++it) { +// std::cout << "Const : " << std::setw(5) << counter + 1; +// for (auto it1 = (*it).w_const.begin(); it1 != (*it).w_const.end(); ++it1) { +// std::cout << std::setw(15) << (*it1); +// } +// std::cout << std::endl; +// ++counter; +// } +// std::cout << std::endl; constraint->get_mapping_constraint(maxorder, constsym, const_fix_tmp, const_relate_tmp, index_bimap_tmp, true); From db68cdd66dcf5f7b4c4988285bab644203655836 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Fri, 24 Nov 2017 14:20:36 +0900 Subject: [PATCH 10/33] Testing another parallelization of constraint.cpp --- alm/constraint.cpp | 34 ++++++++++++++++++++++++---------- alm/constraint.h | 11 +++++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 5f744880..6cd29a47 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -557,7 +557,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou int *index_tmp; int **xyzcomponent; int nparams; - + int nfreq_update = 1; double *arr_constraint; bool has_constraint_from_symm = false; std::set list_found; @@ -615,6 +615,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou int *atm_index, *atm_index_symm; int *xyz_index; double c_tmp; + int counter = 0; std::set::iterator iter_found; std::vector const_now_omp; @@ -668,11 +669,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); if (iter_found != list_found.end()) { c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); - // if (std::abs(c_tmp) < eps6) c_tmp = 0.0; const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; -// std::cout << " isym = " << std::setw(4) << isym + 1; -// std::cout << " iloc = " << std::setw(4) << (*iter_found).mother; -// std::cout << " coef = " << std::setw(15) << (*iter_found).sign * c_tmp << std::endl; } } if (!is_allzero(const_now_omp, eps8, loc_nonzero)) { @@ -683,21 +680,26 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou } } // close isym loop - - - // sort-->uniq the array + // ++counter; + // if (counter % nfreq_update == 0) { + // sort-->uniq the array std::sort(const_omp.begin(), const_omp.end()); - const_omp.erase(std::unique(const_omp.begin(), const_omp.end()), + const_omp.erase(std::unique(const_omp.begin(), const_omp.end(), equal_within_eps12), const_omp.end()); + // const_omp.erase(std::unique(const_omp.begin(), const_omp.end()), + // const_omp.end()); // Merge vectors #pragma omp critical { + std::cout << "size = " << const_omp.size() << std::endl; for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } } - const_omp.clear(); + const_omp.clear(); + // } + } // close ii loop @@ -706,6 +708,17 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->deallocate(atm_index_symm); memory->deallocate(xyz_index); + // std::sort(const_omp.begin(), const_omp.end()); + // const_omp.erase(std::unique(const_omp.begin(), const_omp.end(), equal_within_eps12), + // const_omp.end()); + // Merge vectors +//#pragma omp critical +// { +// for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { +// const_mat.push_back(*it); +// } +// } +// const_omp.clear(); } // close openmp region memory->allocate(arr_constraint, nparams); @@ -720,6 +733,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->deallocate(xyzcomponent); memory->deallocate(arr_constraint); + std::cout << "Before rref" << std::endl; // std::cout << "Size of constraint matrix:" << std::endl; // std::cout << const_out[order].size() << std::endl; diff --git a/alm/constraint.h b/alm/constraint.h index 8c1071b4..ac6d04f3 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -78,6 +78,17 @@ namespace ALM_NS std::copy(p_index_in.begin(), p_index_in.end(), std::back_inserter(p_index_orig)); } }; + bool equal_within_eps12(const std::vector &a, const std::vector &b) { + int n = a.size(); + int m = b.size(); + if (n != m) return false; + double res = 0.0; + for (int i = 0; i < n; ++i) { + if (std::abs(a[i] - b[i])> eps12) return false; + } +// if (std::sqrt(res)>eps12) return false; + return true; + } class Constraint: protected Pointers { From c3973681421f0e272f4040bc4cba58ada6121aca Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 24 Nov 2017 17:18:48 +0900 Subject: [PATCH 11/33] Allow users to change the tolerance to detect nonzero elements of constraint matrix. The tolerance can be changed via TOL_CONST tag. Default value if 1.0e-6. --- alm/constraint.cpp | 131 ++++++++++++++++++++++++++------------------ alm/constraint.h | 5 +- alm/input.cpp | 10 +++- alm/patterndisp.cpp | 10 ---- 4 files changed, 90 insertions(+), 66 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 6cd29a47..e3388157 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -30,7 +30,6 @@ using namespace ALM_NS; Constraint::Constraint(ALM *alm) : Pointers(alm) { - tolerance_constraint = eps6; } Constraint::~Constraint() @@ -327,7 +326,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) if (order > 0) { int nparam2 = fcs->ndup[order - 1].size() + fcs->ndup[order].size(); for (i = 0; i < N; ++i) arr_tmp[i] = 0.0; - for (std::vector::iterator p = const_rotation_cross[order].begin(); + for (auto p = const_rotation_cross[order].begin(); p != const_rotation_cross[order].end(); ++p) { ConstraintClass const_now = *p; for (i = 0; i < nparam2; ++i) { @@ -557,7 +556,6 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou int *index_tmp; int **xyzcomponent; int nparams; - int nfreq_update = 1; double *arr_constraint; bool has_constraint_from_symm = false; std::set list_found; @@ -615,7 +613,6 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou int *atm_index, *atm_index_symm; int *xyz_index; double c_tmp; - int counter = 0; std::set::iterator iter_found; std::vector const_now_omp; @@ -630,7 +627,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou const_now_omp.resize(nparams); #ifdef _OPENMP -#pragma omp for private(i, isym, ixyz) +#pragma omp for private(i, isym, ixyz), schedule(static) #endif for (int ii = 0; ii < nfcs; ++ii) { FcProperty list_tmp = fcs->fc_set[order][ii]; @@ -639,12 +636,6 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou atm_index[i] = list_tmp.elems[i] / 3; xyz_index[i] = list_tmp.elems[i] % 3; } -// std::cout << std::endl; -// std::cout << "IFC : " << std::setw(4) << ii + 1; -// for (i = 0; i < order + 2; ++i) { -// std::cout << std::setw(4) << list_tmp.elems[i]; -// } -// std::cout << std::endl; for (isym = 0; isym < symmetry->nsym; ++isym) { @@ -680,26 +671,8 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou } } // close isym loop - // ++counter; - // if (counter % nfreq_update == 0) { - // sort-->uniq the array - std::sort(const_omp.begin(), const_omp.end()); - const_omp.erase(std::unique(const_omp.begin(), const_omp.end(), equal_within_eps12), - const_omp.end()); - // const_omp.erase(std::unique(const_omp.begin(), const_omp.end()), - // const_omp.end()); - - // Merge vectors -#pragma omp critical - { - std::cout << "size = " << const_omp.size() << std::endl; - for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { - const_mat.push_back(*it); - } - } - const_omp.clear(); - // } + if (const_omp.size() > nparams) rref(const_omp, tolerance_constraint); } // close ii loop @@ -708,22 +681,18 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->deallocate(atm_index_symm); memory->deallocate(xyz_index); - // std::sort(const_omp.begin(), const_omp.end()); - // const_omp.erase(std::unique(const_omp.begin(), const_omp.end(), equal_within_eps12), - // const_omp.end()); - // Merge vectors -//#pragma omp critical -// { -// for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { -// const_mat.push_back(*it); -// } -// } -// const_omp.clear(); +#pragma omp critical + { + for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { + const_mat.push_back(*it); + } + } + const_omp.clear(); } // close openmp region memory->allocate(arr_constraint, nparams); - for (auto it = const_mat.rbegin(); it != const_mat.rend(); ++it) { - for (i = 0; i < (*it).size(); ++i) { + for (auto it = const_mat.crbegin(); it != const_mat.crend(); ++it) { + for (i = 0; i < nparams; ++i) { arr_constraint[i] = (*it)[i]; } const_out[order].push_back(ConstraintClass(nparams, @@ -733,12 +702,6 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->deallocate(xyzcomponent); memory->deallocate(arr_constraint); - std::cout << "Before rref" << std::endl; - -// std::cout << "Size of constraint matrix:" << std::endl; -// std::cout << const_out[order].size() << std::endl; -// std::cout << "tolerance_constraint = " << tolerance_constraint << std::endl; - remove_redundant_rows(nparams, const_out[order], tolerance_constraint); if (has_constraint_from_symm) { @@ -1790,7 +1753,7 @@ void Constraint::rref(int nrows, if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; if (pivot != irow) { -//#pragma omp parallel for private(tmp) + //#pragma omp parallel for private(tmp) for (jcol = icol; jcol < ncols; ++jcol) { tmp = mat[pivot][jcol]; mat[pivot][jcol] = mat[irow][jcol]; @@ -1800,7 +1763,7 @@ void Constraint::rref(int nrows, tmp = mat[irow][icol]; tmp = 1.0 / tmp; -//#pragma omp parallel for + //#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[irow][jcol] *= tmp; } @@ -1809,10 +1772,74 @@ void Constraint::rref(int nrows, if (jrow == irow) continue; tmp = mat[jrow][icol]; -//#pragma omp parallel for + //#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[jrow][jcol] -= tmp * mat[irow][jcol]; } } } } + + +void Constraint::rref(std::vector> &mat, const double tolerance) +{ + // Return the reduced row echelon form (rref) of matrix mat. + // In addition, rank of the matrix is estimated. + + int irow, icol, jrow, jcol; + int pivot; + double tmp; + + int nrank = 0; + + icol = 0; + + int nrows = mat.size(); + int ncols = mat[0].size(); + + for (irow = 0; irow < nrows; ++irow) { + + pivot = irow; + + while (std::abs(mat[pivot][icol]) < tolerance) { + ++pivot; + + if (pivot == nrows) { + pivot = irow; + ++icol; + + if (icol == ncols) break; + } + } + + if (icol == ncols) break; + + if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; + + if (pivot != irow) { + for (jcol = icol; jcol < ncols; ++jcol) { + tmp = mat[pivot][jcol]; + mat[pivot][jcol] = mat[irow][jcol]; + mat[irow][jcol] = tmp; + } + } + + tmp = mat[irow][icol]; + tmp = 1.0 / tmp; + for (jcol = icol; jcol < ncols; ++jcol) { + mat[irow][jcol] *= tmp; + } + + for (jrow = 0; jrow < nrows; ++jrow) { + if (jrow == irow) continue; + + tmp = mat[jrow][icol]; + for (jcol = icol; jcol < ncols; ++jcol) { + mat[jrow][jcol] -= tmp * mat[irow][jcol]; + } + } + } + + mat.erase(mat.begin() + nrank, mat.end()); + mat.shrink_to_fit(); +} diff --git a/alm/constraint.h b/alm/constraint.h index ac6d04f3..0a3c35cf 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -78,7 +78,7 @@ namespace ALM_NS std::copy(p_index_in.begin(), p_index_in.end(), std::back_inserter(p_index_orig)); } }; - bool equal_within_eps12(const std::vector &a, const std::vector &b) { + inline bool equal_within_eps12(const std::vector &a, const std::vector &b) { int n = a.size(); int m = b.size(); if (n != m) return false; @@ -148,9 +148,8 @@ namespace ALM_NS void remove_redundant_rows(const int, std::vector &, const double tolerance = eps12); - void remove_redundant_rows2(const int, std::vector &, - const double tolerance = eps12); void rref(int, int, double **, int &, double tolerance = eps12); + void rref(std::vector> &, const double tolerance = eps12); }; extern "C" diff --git a/alm/input.cpp b/alm/input.cpp index ab0a3eaf..00176671 100644 --- a/alm/input.cpp +++ b/alm/input.cpp @@ -107,10 +107,11 @@ void Input::parse_general_vars() std::string *kdname; double **magmom, magmag; double tolerance; + double tolerance_constraint; std::vector kdname_v, periodic_v, magmom_v, str_split; std::string str_allowed_list = "PREFIX MODE NAT NKD NSYM KD PERIODIC PRINTSYM TOLERANCE DBASIS TRIMEVEN\ - MAGMOM NONCOLLINEAR TREVSYM HESSIAN"; + MAGMOM NONCOLLINEAR TREVSYM HESSIAN TOL_CONST"; std::string str_no_defaults = "PREFIX MODE NAT NKD KD"; std::vector no_defaults; std::map general_var_dict; @@ -197,6 +198,12 @@ void Input::parse_general_vars() assign_val(tolerance, "TOLERANCE", general_var_dict); } + if (general_var_dict["TOL_CONST"].empty()) { + tolerance_constraint = eps6; + } else { + assign_val(tolerance_constraint, "TOL_CONST", general_var_dict); + } + // Convert MAGMOM input to array memory->allocate(magmom, nat, 3); lspin = false; @@ -342,6 +349,7 @@ void Input::parse_general_vars() system->noncollinear = noncollinear; symmetry->trev_sym_mag = trevsym; writes->print_hessian = print_hessian; + constraint->tolerance_constraint = tolerance_constraint; if (mode == "suggest") { displace->disp_basis = str_disp_basis; diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index cf9ad3c1..e91e2720 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -57,16 +57,6 @@ void Displace::gen_displacement_pattern() memory->allocate(index_bimap_tmp, maxorder); constraint->constraint_from_symmetry(constsym); - int counter =0; -// for (auto it = constsym[0].begin(); it != constsym[0].end(); ++it) { -// std::cout << "Const : " << std::setw(5) << counter + 1; -// for (auto it1 = (*it).w_const.begin(); it1 != (*it).w_const.end(); ++it1) { -// std::cout << std::setw(15) << (*it1); -// } -// std::cout << std::endl; -// ++counter; -// } -// std::cout << std::endl; constraint->get_mapping_constraint(maxorder, constsym, const_fix_tmp, const_relate_tmp, index_bimap_tmp, true); From 092eb1571c592f09b50e7f909e3780b0f59a8232 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 24 Nov 2017 19:03:24 +0900 Subject: [PATCH 12/33] Use generic function that generate force constant table either in Cartesian or lattice coordinate --- alm/constraint.cpp | 50 ++++----- alm/fcs.cpp | 266 +++++++++++--------------------------------- alm/fcs.h | 16 ++- alm/fitting.cpp | 36 +++--- alm/patterndisp.cpp | 6 +- alm/system.cpp | 14 +-- alm/writes.cpp | 76 ++++++------- 7 files changed, 169 insertions(+), 295 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index e3388157..d56c35eb 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -126,7 +126,7 @@ void Constraint::setup() int N = 0; for (i = 0; i < maxorder; ++i) { - N += fcs->ndup[i].size(); + N += fcs->nequiv[i].size(); } memory->allocate(const_translation, maxorder); @@ -181,7 +181,7 @@ void Constraint::setup() for (order = 0; order < maxorder; ++order) { - nparam = fcs->ndup[order].size(); + nparam = fcs->nequiv[order].size(); memory->allocate(arr_tmp, nparam); for (it_const = const_translation[order].begin(); @@ -260,11 +260,11 @@ void Constraint::setup() } if (fix_harmonic) { Pmax -= const_self[0].size(); - Pmax += fcs->ndup[0].size(); + Pmax += fcs->nequiv[0].size(); } if (fix_cubic) { Pmax -= const_self[1].size(); - Pmax += fcs->ndup[1].size(); + Pmax += fcs->nequiv[1].size(); } memory->allocate(const_mat, Pmax, N); memory->allocate(const_rhs, Pmax); @@ -302,7 +302,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) // Intra-order constraints for (order = 0; order < maxorder; ++order) { - int nparam = fcs->ndup[order].size(); + int nparam = fcs->nequiv[order].size(); if ((order == 0 && !fix_harmonic) || (order == 1 && !fix_cubic) || order > 1) { for (i = 0; i < N; ++i) arr_tmp[i] = 0.0; @@ -324,7 +324,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) int nshift2 = 0; for (order = 0; order < maxorder; ++order) { if (order > 0) { - int nparam2 = fcs->ndup[order - 1].size() + fcs->ndup[order].size(); + int nparam2 = fcs->nequiv[order - 1].size() + fcs->nequiv[order].size(); for (i = 0; i < N; ++i) arr_tmp[i] = 0.0; for (auto p = const_rotation_cross[order].begin(); p != const_rotation_cross[order].end(); ++p) { @@ -334,7 +334,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) } const_total.push_back(ConstraintClass(N, arr_tmp)); } - nshift2 += fcs->ndup[order - 1].size(); + nshift2 += fcs->nequiv[order - 1].size(); } } memory->deallocate(arr_tmp); @@ -349,7 +349,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) std::cout << " of the reference " << fc2_file << std::endl; std::cout << " Constraint for HARMONIC IFCs will be updated accordingly." << std::endl << std::endl; - P += fcs->ndup[0].size(); + P += fcs->nequiv[0].size(); } if (fix_cubic) { @@ -357,7 +357,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) std::cout << " of the reference " << fc3_file << std::endl; std::cout << " Constraint for ANHARM3 IFCs will be updated accordingly." << std::endl << std::endl; - P += fcs->ndup[1].size(); + P += fcs->nequiv[1].size(); } for (i = 0; i < P; ++i) { @@ -372,7 +372,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) if (fix_harmonic) { double *const_rhs_tmp; - int nfcs_tmp = fcs->ndup[0].size(); + int nfcs_tmp = fcs->nequiv[0].size(); memory->allocate(const_rhs_tmp, nfcs_tmp); system->load_reference_system_xml(fc2_file, 0, const_rhs_tmp); @@ -387,9 +387,9 @@ void Constraint::calc_constraint_matrix(const int N, int &P) } if (fix_cubic) { - int ishift = fcs->ndup[0].size(); + int ishift = fcs->nequiv[0].size(); double *const_rhs_tmp; - int nfcs_tmp = fcs->ndup[1].size(); + int nfcs_tmp = fcs->nequiv[1].size(); memory->allocate(const_rhs_tmp, nfcs_tmp); system->load_reference_system_xml(fc3_file, 1, const_rhs_tmp); @@ -445,7 +445,7 @@ void Constraint::get_mapping_constraint(const int nmax, int nparam; for (order = 0; order < nmax; ++order) { - nparam = fcs->ndup[order].size(); + nparam = fcs->nequiv[order].size(); if (fix_forceconstant[order]) { @@ -508,7 +508,7 @@ void Constraint::get_mapping_constraint(const int nmax, for (order = 0; order < nmax; ++order) { - nparam = fcs->ndup[order].size(); + nparam = fcs->nequiv[order].size(); for (i = 0; i < nparam; ++i) { has_constraint[order].push_back(0); @@ -526,7 +526,7 @@ void Constraint::get_mapping_constraint(const int nmax, int icount; for (order = 0; order < nmax; ++order) { - nparam = fcs->ndup[order].size(); + nparam = fcs->nequiv[order].size(); icount = 0; for (i = 0; i < nparam; ++i) { @@ -578,7 +578,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou for (order = 0; order < maxorder; ++order) { - nparams = fcs->ndup[order].size(); + nparams = fcs->nequiv[order].size(); if (has_constraint_from_symm) { std::cout << " " << std::setw(8) << interaction->str_order[order] << " ..."; @@ -590,7 +590,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou // Generate temporary list of parameters list_found.clear(); - for (auto p = fcs->fc_set[order].begin(); p != fcs->fc_set[order].end(); ++p) { + for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { for (i = 0; i < order + 2; ++i) index_tmp[i] = (*p).elems[i]; list_found.insert(FcProperty(order + 2, (*p).sign, index_tmp, (*p).mother)); @@ -600,7 +600,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou memory->allocate(xyzcomponent, nxyz, order + 2); fcs->get_xyzcomponent(order + 2, xyzcomponent); - int nfcs = fcs->fc_set[order].size(); + int nfcs = fcs->fc_table[order].size(); #ifdef _OPENMP #pragma omp parallel @@ -630,7 +630,7 @@ void Constraint::constraint_from_symmetry(std::vector *const_ou #pragma omp for private(i, isym, ixyz), schedule(static) #endif for (int ii = 0; ii < nfcs; ++ii) { - FcProperty list_tmp = fcs->fc_set[order][ii]; + FcProperty list_tmp = fcs->fc_table[order][ii]; for (i = 0; i < order + 2; ++i) { atm_index[i] = list_tmp.elems[i] / 3; @@ -758,7 +758,7 @@ void Constraint::translational_invariance() const_mat.clear(); - nparams = fcs->ndup[order].size(); + nparams = fcs->nequiv[order].size(); if (nparams == 0) { std::cout << " No parameters! Skipped." << std::endl; @@ -769,8 +769,8 @@ void Constraint::translational_invariance() list_found.clear(); - for (std::vector::iterator p = fcs->fc_set[order].begin(); - p != fcs->fc_set[order].end(); ++p) { + for (std::vector::iterator p = fcs->fc_table[order].begin(); + p != fcs->fc_table[order].end(); ++p) { for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } @@ -1047,7 +1047,7 @@ void Constraint::rotational_invariance() for (order = 0; order < maxorder; ++order) { - nparams[order] = fcs->ndup[order].size(); + nparams[order] = fcs->nequiv[order].size(); if (order == 0) { std::cout << " Constraints between " << std::setw(8) @@ -1076,8 +1076,8 @@ void Constraint::rotational_invariance() list_found.clear(); - for (std::vector::iterator p = fcs->fc_set[order].begin(); - p != fcs->fc_set[order].end(); ++p) { + for (std::vector::iterator p = fcs->fc_table[order].begin(); + p != fcs->fc_table[order].end(); ++p) { for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } diff --git a/alm/fcs.cpp b/alm/fcs.cpp index 60371f08..78d788e0 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -32,6 +32,9 @@ Fcs::Fcs(ALM *alm) : Pointers(alm) Fcs::~Fcs() { + memory->deallocate(fc_table); + memory->deallocate(nequiv); + memory->deallocate(fc_zeros); }; void Fcs::init() @@ -42,40 +45,44 @@ void Fcs::init() std::cout << " FORCE CONSTANT" << std::endl; std::cout << " ==============" << std::endl << std::endl; - memory->allocate(fc_set, maxorder); - memory->allocate(ndup, maxorder); + memory->allocate(fc_table, maxorder); + memory->allocate(nequiv, maxorder); + memory->allocate(fc_zeros, maxorder); - generate_fclists(maxorder); + for (i = 0; i < maxorder; ++i) { + generate_force_constant_table(i, interaction->pairs[i], + symmetry->SymmData, "Cartesian", + fc_table[i], nequiv[i], fc_zeros[i], true); + } std::cout << std::endl; for (i = 0; i < maxorder; ++i) { + std::cout << " Number of " << std::setw(9) << interaction->str_order[i] - << " FCs : " << ndup[i].size(); + << " FCs : " << nequiv[i].size(); std::cout << std::endl; } std::cout << std::endl; - for (auto it = ndup[0].begin(); it != ndup[0].end(); ++it) { - std::cout << (*it) << std::endl; - } - // sort fc_set - - for (int order = 0; order < maxorder; ++order) { - if (ndup[order].size() > 0) { - std::sort(fc_set[order].begin(), - fc_set[order].begin() + ndup[order][0]); - int nbegin = ndup[order][0]; - int nend; - for (int mm = 1; mm < ndup[order].size(); ++mm) { - nend = nbegin + ndup[order][mm]; - std::sort(fc_set[order].begin() + nbegin, - fc_set[order].begin() + nend); - nbegin += ndup[order][mm]; - } - } - } + // + // std::vector fc_test, fc_zeros_tmp; + // std::vector nmulti; + // generate_force_constant_table(1, interaction->pairs[1], + // symmetry->SymmData, "Lattice", + // fc_test, nmulti, fc_zeros_tmp, true); + // std::cout << "Nonzero independent IFCs:" << std::setw(5) << nmulti.size() << std::endl; +// std::cout << "Zero IFCs:" << std::endl; +// for (auto it = fc_zeros_tmp.begin(); it != fc_zeros_tmp.end(); ++it) { +// for (i = 0; i < (*it).elems.size(); ++i) { +// std::cout << std::setw(4) << (*it).elems[i]; +// } +// std::cout << std::setw(5) << (*it).mother; +// std::cout << std::endl; +// } +// std::cout << std::endl; + timer->print_elapsed(); std::cout << " -------------------------------------------------------------------" << std::endl; @@ -83,9 +90,13 @@ void Fcs::init() } void Fcs::generate_force_constant_table(const int order, - std::set *pairs, - std::vector *symmop, - std::string basis) + const std::set pairs, + const std::vector symmop, + std::string basis, + std::vector &fc_vec, + std::vector &ndup, + std::vector &fc_zeros, + const bool store_zeros) { int i, j; int i1, i2; @@ -102,7 +113,7 @@ void Fcs::generate_force_constant_table(const int order, int nmother; int nat = system->nat; - int nsym = symmop->size(); + int nsym = symmop.size(); int nsym_in_use; bool is_zero; @@ -119,7 +130,7 @@ void Fcs::generate_force_constant_table(const int order, counter = 0; if (basis == "Cartesian") { - for (auto it = symmop->begin(); it != symmop->end(); ++it) { + for (auto it = symmop.begin(); it != symmop.end(); ++it) { if ((*it).compatible_with_cartesian) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { @@ -136,7 +147,7 @@ void Fcs::generate_force_constant_table(const int order, } else if (basis == "Lattice") { - for (auto it = symmop->begin(); it != symmop->end(); ++it) { + for (auto it = symmop.begin(); it != symmop.end(); ++it) { if ((*it).compatible_with_lattice) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { @@ -167,9 +178,9 @@ void Fcs::generate_force_constant_table(const int order, memory->allocate(ind_mapped_tmp, order + 2); memory->allocate(is_searched, 3 * nat); - - fc_set[order].clear(); - ndup[order].clear(); + fc_vec.clear(); + ndup.clear(); + fc_zeros.clear(); nmother = 0; nxyz = static_cast(std::pow(3.0, order + 2)); @@ -179,7 +190,7 @@ void Fcs::generate_force_constant_table(const int order, std::set list_found; - for (auto iter = pairs->begin(); iter != pairs->end(); ++iter) { + for (auto iter = pairs.begin(); iter != pairs.end(); ++iter) { for (i = 0; i < order + 2; ++i) atmn[i] = (*iter).iarray[i]; @@ -208,7 +219,6 @@ void Fcs::generate_force_constant_table(const int order, if (!is_inprim(order + 2, atmn_mapped)) continue; for (i2 = 0; i2 < nxyz; ++i2) { - // c_tmp = coef_sym(order + 2, isym, xyzcomponent[i1], xyzcomponent[i2]); c_tmp = coef_sym(order + 2, rotation[isym], xyzcomponent[i1], xyzcomponent[i2]); if (std::abs(c_tmp) > eps12) { for (i = 0; i < order + 2; ++i) @@ -232,8 +242,8 @@ void Fcs::generate_force_constant_table(const int order, if (list_found.find(IntList(order + 2, ind_mapped)) == list_found.end()) { list_found.insert(IntList(order + 2, ind_mapped)); - fc_set[order].push_back(FcProperty(order + 2, c_tmp, - ind_mapped, nmother)); + fc_vec.push_back(FcProperty(order + 2, c_tmp, + ind_mapped, nmother)); ++ndeps; // Add equivalent interaction list (permutation) if there are two or more indices @@ -248,8 +258,8 @@ void Fcs::generate_force_constant_table(const int order, for (j = 0; j < order + 2; ++j) ind_mapped_tmp[j] = ind_mapped[j]; std::swap(ind_mapped_tmp[0], ind_mapped_tmp[i]); sort_tail(order + 2, ind_mapped_tmp); - fc_set[order].push_back(FcProperty(order + 2, c_tmp, - ind_mapped_tmp, nmother)); + fc_vec.push_back(FcProperty(order + 2, c_tmp, + ind_mapped_tmp, nmother)); ++ndeps; @@ -264,9 +274,15 @@ void Fcs::generate_force_constant_table(const int order, } // close symmetry loop if (is_zero) { - for (i = 0; i < ndeps; ++i) fc_set[order].pop_back(); + if (store_zeros) { + for (auto it = fc_vec.rbegin(); it != fc_vec.rbegin() + ndeps; ++it) { + (*it).mother = -1; + fc_zeros.push_back(*it); + } + } + for (i = 0; i < ndeps; ++i) fc_vec.pop_back(); } else { - ndup[order].push_back(ndeps); + ndup.push_back(ndeps); ++nmother; } @@ -284,168 +300,22 @@ void Fcs::generate_force_constant_table(const int order, memory->deallocate(is_searched); memory->deallocate(rotation); memory->deallocate(map_sym); -} - - -void Fcs::generate_fclists(int maxorder) -{ - int i, j; - int i1, i2; - int order; - int i_prim; - int *atmn, *atmn_mapped; - int *ind, *ind_mapped; - int *ind_tmp, *ind_mapped_tmp; - int nxyz; - unsigned int isym; - double c_tmp; - - int **xyzcomponent; - - int nmother; - int nat = system->nat; - - bool is_zero; - bool *is_searched; - - std::cout << " Finding symmetrically-independent force constants ..." << std::endl; - - memory->allocate(atmn, maxorder + 1); - memory->allocate(atmn_mapped, maxorder + 1); - memory->allocate(ind, maxorder + 1); - memory->allocate(ind_mapped, maxorder + 1); - memory->allocate(ind_tmp, maxorder - 1); - memory->allocate(ind_mapped_tmp, maxorder + 1); - memory->allocate(is_searched, 3 * nat); - - for (order = 0; order < maxorder; ++order) { - - std::cout << " " << std::setw(8) << interaction->str_order[order] << " ..."; - - fc_set[order].clear(); - ndup[order].clear(); - nmother = 0; - - nxyz = static_cast(std::pow(3.0, order + 2)); - - memory->allocate(xyzcomponent, nxyz, order + 2); - get_xyzcomponent(order + 2, xyzcomponent); - - std::set list_found; - - for (auto iter = interaction->pairs[order].begin(); iter != interaction->pairs[order].end(); ++iter) { - - for (i = 0; i < order + 2; ++i) atmn[i] = (*iter).iarray[i]; - - for (i1 = 0; i1 < nxyz; ++i1) { - for (i = 0; i < order + 2; ++i) - ind[i] = 3 * atmn[i] + xyzcomponent[i1][i]; + // sort fc_vec - if (!is_ascending(order + 2, ind)) continue; - - i_prim = min_inprim(order + 2, ind); - std::swap(ind[0], ind[i_prim]); - sort_tail(order + 2, ind); - - is_zero = false; - - if (list_found.find(IntList(order + 2, ind)) != list_found.end()) continue; // Already exits! - - // Search symmetrically-dependent parameter set - - int ndeps = 0; - - for (isym = 0; isym < symmetry->nsym; ++isym) { - - if (!symmetry->SymmData[isym].compatible_with_cartesian) continue; - - for (i = 0; i < order + 2; ++i) - atmn_mapped[i] = symmetry->map_sym[atmn[i]][isym]; - - if (!is_inprim(order + 2, atmn_mapped)) continue; - - for (i2 = 0; i2 < nxyz; ++i2) { - c_tmp = coef_sym(order + 2, isym, xyzcomponent[i1], xyzcomponent[i2]); - if (std::abs(c_tmp) > eps12) { - for (i = 0; i < order + 2; ++i) - ind_mapped[i] = 3 * atmn_mapped[i] + xyzcomponent[i2][i]; - - i_prim = min_inprim(order + 2, ind_mapped); - std::swap(ind_mapped[0], ind_mapped[i_prim]); - sort_tail(order + 2, ind_mapped); - - if (!is_zero) { - bool zeroflag = true; - for (i = 0; i < order + 2; ++i) { - zeroflag = zeroflag & (ind[i] == ind_mapped[i]); - } - zeroflag = zeroflag & (std::abs(c_tmp + 1.0) < eps8); - is_zero = zeroflag; - } - - // Add to found list (set) and fcset (vector) if the created is new one. - - if (list_found.find(IntList(order + 2, ind_mapped)) == list_found.end()) { - list_found.insert(IntList(order + 2, ind_mapped)); - - fc_set[order].push_back(FcProperty(order + 2, c_tmp, - ind_mapped, nmother)); - ++ndeps; - - // Add equivalent interaction list (permutation) if there are two or more indices - // which belong to the primitive cell. - // This procedure is necessary for fitting. - - for (i = 0; i < 3 * nat; ++i) is_searched[i] = false; - is_searched[ind_mapped[0]] = true; - for (i = 1; i < order + 2; ++i) { - if ((!is_searched[ind_mapped[i]]) && is_inprim(ind_mapped[i])) { - - for (j = 0; j < order + 2; ++j) ind_mapped_tmp[j] = ind_mapped[j]; - std::swap(ind_mapped_tmp[0], ind_mapped_tmp[i]); - sort_tail(order + 2, ind_mapped_tmp); - fc_set[order].push_back(FcProperty(order + 2, c_tmp, - ind_mapped_tmp, nmother)); - - ++ndeps; - - is_searched[ind_mapped[i]] = true; - } - } - - - } - } - } - } // close symmetry loop - - if (is_zero) { - for (i = 0; i < ndeps; ++i) fc_set[order].pop_back(); - } else { - ndup[order].push_back(ndeps); - ++nmother; - } - - } // close xyz component loop - } // close atom number loop (iterator) - - memory->deallocate(xyzcomponent); - list_found.clear(); - std::cout << " done. " << std::endl; - } //close order loop - - memory->deallocate(atmn); - memory->deallocate(atmn_mapped); - memory->deallocate(ind); - memory->deallocate(ind_mapped); - memory->deallocate(ind_tmp); - memory->deallocate(ind_mapped_tmp); - memory->deallocate(is_searched); - - std::cout << " Finished!" << std::endl; + if (ndup.size() > 0) { + std::sort(fc_vec.begin(), fc_vec.begin() + ndup[0]); + int nbegin = ndup[0]; + int nend; + for (int mm = 1; mm < ndup.size(); ++mm) { + nend = nbegin + ndup[mm]; + std::sort(fc_vec.begin() + nbegin, fc_vec.begin() + nend); + nbegin += ndup[mm]; + } + } } + double Fcs::coef_sym(const int n, const int symnum, const int *arr1, diff --git a/alm/fcs.h b/alm/fcs.h index e56dc78c..2b3678e4 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -70,8 +70,9 @@ namespace ALM_NS void init(); - std::vector *ndup; - std::vector *fc_set; + std::vector *nequiv; + std::vector *fc_table; + std::vector *fc_zeros; std::string easyvizint(const int); void get_xyzcomponent(int, int **); @@ -83,11 +84,14 @@ namespace ALM_NS double coef_sym(const int, const int, const int *, const int *); private: - void generate_fclists(int); void generate_force_constant_table(const int, - std::set *, - std::vector *, - std::string basis = "Cartesian"); + const std::set, + const std::vector, + std::string, + std::vector &, + std::vector &, + std::vector &, + const bool); bool is_ascending(const int, const int *); double coef_sym(const int, double **, const int *, const int *); diff --git a/alm/fitting.cpp b/alm/fitting.cpp index fb091ccc..f84bcf4c 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -113,7 +113,7 @@ void Fitting::fitmain() N = 0; for (i = 0; i < maxorder; ++i) { - N += fcs->ndup[i].size(); + N += fcs->nequiv[i].size(); } std::cout << " Total Number of Parameters : " << N << std::endl << std::endl; @@ -710,7 +710,7 @@ void Fitting::fit_algebraic_constraints(int N, param_out[constraint->const_relate[i][j].p_index_target + ishift] = -tmp; } - ishift += fcs->ndup[i].size(); + ishift += fcs->nequiv[i].size(); iparam += constraint->index_bimap[i].size(); } @@ -780,7 +780,7 @@ void Fitting::fit_bootstrap(int N, ofs_fcs_boot << "# Relative Error(%), FCs ..."; for (i = 0; i < interaction->maxorder; ++i) { - ofs_fcs_boot << std::setw(10) << fcs->ndup[i].size(); + ofs_fcs_boot << std::setw(10) << fcs->nequiv[i].size(); } ofs_fcs_boot << std::endl; @@ -916,7 +916,7 @@ void Fitting::fit_consecutively(int N, ofs_fcs_seq << "# Relative Error(%), FCS..."; for (i = 0; i < interaction->maxorder; ++i) { - ofs_fcs_seq << std::setw(10) << fcs->ndup[i].size(); + ofs_fcs_seq << std::setw(10) << fcs->nequiv[i].size(); } ofs_fcs_seq << std::endl; @@ -1053,17 +1053,17 @@ void Fitting::calc_matrix_elements(const int M, mm = 0; - for (std::vector::iterator iter = fcs->ndup[order].begin(); - iter != fcs->ndup[order].end(); ++iter) { + for (std::vector::iterator iter = fcs->nequiv[order].begin(); + iter != fcs->nequiv[order].end(); ++iter) { for (i = 0; i < *iter; ++i) { - ind[0] = fcs->fc_set[order][mm].elems[0]; - k = idata + inprim_index(fcs->fc_set[order][mm].elems[0]); + ind[0] = fcs->fc_table[order][mm].elems[0]; + k = idata + inprim_index(fcs->fc_table[order][mm].elems[0]); amat_tmp = 1.0; for (j = 1; j < order + 2; ++j) { - ind[j] = fcs->fc_set[order][mm].elems[j]; - amat_tmp *= u[irow][fcs->fc_set[order][mm].elems[j]]; + ind[j] = fcs->fc_table[order][mm].elems[j]; + amat_tmp *= u[irow][fcs->fc_table[order][mm].elems[j]]; } - amat[k][iparam] -= gamma(order + 2, ind) * fcs->fc_set[order][mm].sign * amat_tmp; + amat[k][iparam] -= gamma(order + 2, ind) * fcs->fc_table[order][mm].sign * amat_tmp; ++mm; } ++iparam; @@ -1164,18 +1164,18 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, mm = 0; - for (std::vector::iterator iter = fcs->ndup[order].begin(); - iter != fcs->ndup[order].end(); ++iter) { + for (std::vector::iterator iter = fcs->nequiv[order].begin(); + iter != fcs->nequiv[order].end(); ++iter) { for (i = 0; i < *iter; ++i) { - ind[0] = fcs->fc_set[order][mm].elems[0]; + ind[0] = fcs->fc_table[order][mm].elems[0]; k = inprim_index(ind[0]); amat_tmp = 1.0; for (j = 1; j < order + 2; ++j) { - ind[j] = fcs->fc_set[order][mm].elems[j]; - amat_tmp *= u[irow][fcs->fc_set[order][mm].elems[j]]; + ind[j] = fcs->fc_table[order][mm].elems[j]; + amat_tmp *= u[irow][fcs->fc_table[order][mm].elems[j]]; } - amat_orig[k][iparam] -= gamma(order + 2, ind) * fcs->fc_set[order][mm].sign * amat_tmp; + amat_orig[k][iparam] -= gamma(order + 2, ind) * fcs->fc_table[order][mm].sign * amat_tmp; ++mm; } ++iparam; @@ -1220,7 +1220,7 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, } } - ishift += fcs->ndup[order].size(); + ishift += fcs->nequiv[order].size(); iparam += constraint->index_bimap[order].size(); } diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index e91e2720..195eabf3 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -98,7 +98,7 @@ void Displace::gen_displacement_pattern() m = 0; - for (i = 0; i < fcs->ndup[order].size(); ++i) { + for (i = 0; i < fcs->nequiv[order].size(); ++i) { if (include_set[order].find(i) != include_set[order].end()) { @@ -108,7 +108,7 @@ void Displace::gen_displacement_pattern() // Here, duplicate entries will be removed. // For example, (iij) will be reduced to (ij). for (j = 0; j < order + 1; ++j) { - group_tmp.push_back(fcs->fc_set[order][m].elems[j]); + group_tmp.push_back(fcs->fc_table[order][m].elems[j]); } group_tmp.erase(std::unique(group_tmp.begin(), group_tmp.end()), group_tmp.end()); @@ -118,7 +118,7 @@ void Displace::gen_displacement_pattern() } - m += fcs->ndup[order][i]; + m += fcs->nequiv[order][i]; } } memory->deallocate(include_set); diff --git a/alm/system.cpp b/alm/system.cpp index edacf1ca..0b313909 100644 --- a/alm/system.cpp +++ b/alm/system.cpp @@ -260,7 +260,7 @@ void System::load_reference_system_xml(std::string file_reference_fcs, nfcs_ref = boost::lexical_cast( get_value_from_xml(pt, "Data.ForceConstants.HarmonicUnique.NFC2")); - if (nfcs_ref != fcs->ndup[0].size()) { + if (nfcs_ref != fcs->nequiv[0].size()) { error->exit("load_reference_system_xml", "The number of harmonic force constants is not the same."); } @@ -269,7 +269,7 @@ void System::load_reference_system_xml(std::string file_reference_fcs, nfcs_ref = boost::lexical_cast( get_value_from_xml(pt, "Data.ForceConstants.CubicUnique.NFC3")); - if (nfcs_ref != fcs->ndup[1].size()) { + if (nfcs_ref != fcs->nequiv[1].size()) { error->exit("load_reference_system_xml", "The number of cubic force constants is not the same."); } @@ -316,8 +316,8 @@ void System::load_reference_system_xml(std::string file_reference_fcs, list_found.clear(); - for (std::vector::iterator p = fcs->fc_set[order_fcs].begin(); - p != fcs->fc_set[order_fcs].end(); ++p) { + for (std::vector::iterator p = fcs->fc_table[order_fcs].begin(); + p != fcs->fc_table[order_fcs].end(); ++p) { FcProperty list_tmp = *p; // Using copy constructor for (i = 0; i < nterms; ++i) { ind[i] = list_tmp.elems[i]; @@ -368,7 +368,7 @@ void System::load_reference_system() bool is_found_system = false; int nparam_harmonic_ref; - int nparam_harmonic = fcs->ndup[0].size(); + int nparam_harmonic = fcs->nequiv[0].size(); std::string str_tmp; @@ -506,8 +506,8 @@ void System::load_reference_system() memory->allocate(ind, 2); list_found.clear(); - for (std::vector::iterator p = fcs->fc_set[0].begin(); - p != fcs->fc_set[0].end(); ++p) { + for (std::vector::iterator p = fcs->fc_table[0].begin(); + p != fcs->fc_table[0].end(); ++p) { for (i = 0; i < 2; ++i) ind[i] = (*p).elems[i]; list_found.insert(FcProperty(2, (*p).sign, ind, (*p).mother)); } diff --git a/alm/writes.cpp b/alm/writes.cpp index 0cced368..1e7d6c79 100644 --- a/alm/writes.cpp +++ b/alm/writes.cpp @@ -145,11 +145,11 @@ void Writes::write_force_constants() m = 0; - if (fcs->ndup[order].size() > 0) { + if (fcs->nequiv[order].size() > 0) { ofs_fcs << std::endl << std::setw(6) << str_fcs[order] << std::endl; - for (ui = 0; ui < fcs->ndup[order].size(); ++ui) { + for (ui = 0; ui < fcs->nequiv[order].size(); ++ui) { ofs_fcs << std::setw(8) << k + 1 << std::setw(8) << ui + 1 << std::setw(18) << std::setprecision(7) @@ -157,9 +157,9 @@ void Writes::write_force_constants() atom_tmp.clear(); for (l = 1; l < order + 2; ++l) { - atom_tmp.push_back(fcs->fc_set[order][m].elems[l] / 3); + atom_tmp.push_back(fcs->fc_table[order][m].elems[l] / 3); } - j = symmetry->map_s2p[fcs->fc_set[order][m].elems[0] / 3].atom_num; + j = symmetry->map_s2p[fcs->fc_table[order][m].elems[0] / 3].atom_num; std::sort(atom_tmp.begin(), atom_tmp.end()); iter_cluster = interaction->mindist_cluster[order][j].find( @@ -181,12 +181,12 @@ void Writes::write_force_constants() for (l = 0; l < order + 2; ++l) { ofs_fcs << std::setw(7) - << fcs->easyvizint(fcs->fc_set[order][m].elems[l]); + << fcs->easyvizint(fcs->fc_table[order][m].elems[l]); } ofs_fcs << std::setw(12) << std::setprecision(3) << std::fixed << distmax << std::endl; - m += fcs->ndup[order][ui]; + m += fcs->nequiv[order][ui]; ++k; } } @@ -198,7 +198,7 @@ void Writes::write_force_constants() ofs_fcs << " -------------- Constraints from crystal symmetry --------------" << std::endl << std::endl;; for (order = 0; order < maxorder; ++order) { - int nparam = fcs->ndup[order].size(); + int nparam = fcs->nequiv[order].size(); for (std::vector::iterator p = constraint->const_symmetry[order].begin(); @@ -238,24 +238,24 @@ void Writes::write_force_constants() id = 0; - if (fcs->ndup[order].size() > 0) { + if (fcs->nequiv[order].size() > 0) { ofs_fcs << std::endl << std::setw(6) << str_fcs[order] << std::endl; - for (unsigned int iuniq = 0; iuniq < fcs->ndup[order].size(); ++iuniq) { + for (unsigned int iuniq = 0; iuniq < fcs->nequiv[order].size(); ++iuniq) { str_tmp = " # FC" + boost::lexical_cast(order + 2) + "_"; str_tmp += boost::lexical_cast(iuniq + 1); - ofs_fcs << str_tmp << std::setw(5) << fcs->ndup[order][iuniq] + ofs_fcs << str_tmp << std::setw(5) << fcs->nequiv[order][iuniq] << std::setw(16) << std::scientific << std::setprecision(7) << fitting->params[ip] << std::endl; - for (j = 0; j < fcs->ndup[order][iuniq]; ++j) { + for (j = 0; j < fcs->nequiv[order][iuniq]; ++j) { ofs_fcs << std::setw(5) << j + 1 << std::setw(12) - << std::setprecision(5) << std::fixed << fcs->fc_set[order][id].sign; + << std::setprecision(5) << std::fixed << fcs->fc_table[order][id].sign; for (k = 0; k < order + 2; ++k) { ofs_fcs << std::setw(6) - << fcs->easyvizint(fcs->fc_set[order][id].elems[k]); + << fcs->easyvizint(fcs->fc_table[order][id].elems[k]); } ofs_fcs << std::endl; ++id; @@ -420,7 +420,7 @@ void Writes::write_misc_xml() pt.put("Data.ForceConstants", ""); str_tmp.clear(); - pt.put("Data.ForceConstants.HarmonicUnique.NFC2", fcs->ndup[0].size()); + pt.put("Data.ForceConstants.HarmonicUnique.NFC2", fcs->nequiv[0].size()); int ihead = 0; int k = 0; @@ -429,21 +429,21 @@ void Writes::write_misc_xml() memory->allocate(pair_tmp, nelem); - for (unsigned int ui = 0; ui < fcs->ndup[0].size(); ++ui) { + for (unsigned int ui = 0; ui < fcs->nequiv[0].size(); ++ui) { for (i = 0; i < 2; ++i) { - pair_tmp[i] = fcs->fc_set[0][ihead].elems[i] / 3; + pair_tmp[i] = fcs->fc_table[0][ihead].elems[i] / 3; } j = symmetry->map_s2p[pair_tmp[0]].atom_num; ptree &child = pt.add("Data.ForceConstants.HarmonicUnique.FC2", double2string(fitting->params[k])); child.put(".pairs", - boost::lexical_cast(fcs->fc_set[0][ihead].elems[0]) - + " " + boost::lexical_cast(fcs->fc_set[0][ihead].elems[1])); + boost::lexical_cast(fcs->fc_table[0][ihead].elems[0]) + + " " + boost::lexical_cast(fcs->fc_table[0][ihead].elems[1])); child.put(".multiplicity", interaction->mindist_pairs[pair_tmp[0]][pair_tmp[1]].size()); - ihead += fcs->ndup[0][ui]; + ihead += fcs->nequiv[0][ui]; ++k; } ihead = 0; @@ -455,11 +455,11 @@ void Writes::write_misc_xml() if (interaction->maxorder > 1) { - pt.put("Data.ForceConstants.CubicUnique.NFC3", fcs->ndup[1].size()); + pt.put("Data.ForceConstants.CubicUnique.NFC3", fcs->nequiv[1].size()); - for (unsigned int ui = 0; ui < fcs->ndup[1].size(); ++ui) { + for (unsigned int ui = 0; ui < fcs->nequiv[1].size(); ++ui) { for (i = 0; i < 3; ++i) { - pair_tmp[i] = fcs->fc_set[1][ihead].elems[i] / 3; + pair_tmp[i] = fcs->fc_table[1][ihead].elems[i] / 3; } j = symmetry->map_s2p[pair_tmp[0]].atom_num; @@ -481,21 +481,21 @@ void Writes::write_misc_xml() ptree &child = pt.add("Data.ForceConstants.CubicUnique.FC3", double2string(fitting->params[k])); child.put(".pairs", - boost::lexical_cast(fcs->fc_set[1][ihead].elems[0]) - + " " + boost::lexical_cast(fcs->fc_set[1][ihead].elems[1]) - + " " + boost::lexical_cast(fcs->fc_set[1][ihead].elems[2])); + boost::lexical_cast(fcs->fc_table[1][ihead].elems[0]) + + " " + boost::lexical_cast(fcs->fc_table[1][ihead].elems[1]) + + " " + boost::lexical_cast(fcs->fc_table[1][ihead].elems[2])); child.put(".multiplicity", multiplicity); - ihead += fcs->ndup[1][ui]; + ihead += fcs->nequiv[1][ui]; ++k; } } int ip, ishift; - std::sort(fcs->fc_set[0].begin(), fcs->fc_set[0].end()); + std::sort(fcs->fc_table[0].begin(), fcs->fc_table[0].end()); - for (std::vector::iterator it = fcs->fc_set[0].begin(); - it != fcs->fc_set[0].end(); ++it) { + for (std::vector::iterator it = fcs->fc_table[0].begin(); + it != fcs->fc_table[0].end(); ++it) { FcProperty fctmp = *it; ip = fctmp.mother; @@ -517,7 +517,7 @@ void Writes::write_misc_xml() } } - ishift = fcs->ndup[0].size(); + ishift = fcs->nequiv[0].size(); // Print anharmonic force constants to the xml file. @@ -527,10 +527,10 @@ void Writes::write_misc_xml() std::string elementname; for (order = 1; order < interaction->maxorder; ++order) { - std::sort(fcs->fc_set[order].begin(), fcs->fc_set[order].end()); + std::sort(fcs->fc_table[order].begin(), fcs->fc_table[order].end()); - for (std::vector::iterator it = fcs->fc_set[order].begin(); - it != fcs->fc_set[order].end(); ++it) { + for (std::vector::iterator it = fcs->fc_table[order].begin(); + it != fcs->fc_table[order].end(); ++it) { FcProperty fctmp = *it; ip = fctmp.mother + ishift; @@ -578,7 +578,7 @@ void Writes::write_misc_xml() error->exit("write_misc_xml", "This cannot happen."); } } - ishift += fcs->ndup[order].size(); + ishift += fcs->nequiv[order].size(); } using namespace boost::property_tree::xml_parser; @@ -617,8 +617,8 @@ void Writes::write_hessian() } } - for (std::vector::iterator it = fcs->fc_set[0].begin(); - it != fcs->fc_set[0].end(); ++it) { + for (std::vector::iterator it = fcs->fc_table[0].begin(); + it != fcs->fc_table[0].end(); ++it) { FcProperty fctmp = *it; ip = fctmp.mother; @@ -658,8 +658,8 @@ void Writes::write_hessian() ofs_fc2.open(file_fc2.c_str(), std::ios::out); ofs_fc2 << " # iat, icrd, jat, icrd, icell, relvec, fc2" << std::endl; double vec[3]; - for (std::vector::iterator it = fcs->fc_set[0].begin(); - it != fcs->fc_set[0].end(); ++it) { + for (std::vector::iterator it = fcs->fc_table[0].begin(); + it != fcs->fc_table[0].end(); ++it) { FcProperty fctmp = *it; ip = fctmp.mother; From 1ef6281e3b9895e4a46f1db4412fbec0d5b3d0b9 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 24 Nov 2017 21:18:35 +0900 Subject: [PATCH 13/33] (Probably) improve the efficiency for hexagonal systems --- alm/alamode.cpp | 2 +- alm/constraint.cpp | 545 +++++++++++++++++++++++++++++--------------- alm/constraint.h | 30 ++- alm/fcs.cpp | 27 +-- alm/fcs.h | 5 +- alm/patterndisp.cpp | 139 ++++++++--- alm/patterndisp.h | 10 +- alm/symmetry.cpp | 36 +-- alm/writes.cpp | 6 +- 9 files changed, 533 insertions(+), 267 deletions(-) diff --git a/alm/alamode.cpp b/alm/alamode.cpp index 46244c24..5f1a6616 100644 --- a/alm/alamode.cpp +++ b/alm/alamode.cpp @@ -57,6 +57,7 @@ ALM::ALM(int narg, char **arg) if (mode == "fitting") { + fcs->init(); constraint->setup(); fitting->fitmain(); writes->writeall(); @@ -94,7 +95,6 @@ void ALM::initialize() files->init(); symmetry->init(); interaction->init(); - fcs->init(); } ALM::~ALM() diff --git a/alm/constraint.cpp b/alm/constraint.cpp index d56c35eb..8ad80bd3 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -107,7 +107,7 @@ void Constraint::setup() extra_constraint_from_symmetry = false; memory->allocate(const_symmetry, interaction->maxorder); - constraint_from_symmetry(const_symmetry); + generate_symmetry_constraint_in_cartesian(const_symmetry); for (int order = 0; order < interaction->maxorder; ++order) { if (const_symmetry[order].size() > 0) extra_constraint_from_symmetry = true; } @@ -243,7 +243,7 @@ void Constraint::setup() memory->allocate(const_relate, maxorder); memory->allocate(index_bimap, maxorder); - get_mapping_constraint(maxorder, const_self, const_fix, + get_mapping_constraint(maxorder, fcs->nequiv, const_self, const_fix, const_relate, index_bimap, false); for (order = 0; order < maxorder; ++order) { @@ -414,6 +414,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) void Constraint::get_mapping_constraint(const int nmax, + std::vector *nequiv, std::vector *const_in, std::vector *const_fix_out, std::vector *const_relate_out, @@ -445,7 +446,7 @@ void Constraint::get_mapping_constraint(const int nmax, int nparam; for (order = 0; order < nmax; ++order) { - nparam = fcs->nequiv[order].size(); + nparam = nequiv[order].size(); if (fix_forceconstant[order]) { @@ -465,8 +466,7 @@ void Constraint::get_mapping_constraint(const int nmax, std::vector alpha_tmp; std::vector p_index_tmp; - for (std::vector::reverse_iterator p = const_in[order].rbegin(); - p != const_in[order].rend(); ++p) { + for (auto p = const_in[order].rbegin(); p != const_in[order].rend(); ++p) { p_index_target = -1; for (i = 0; i < nparam; ++i) { if (std::abs((*p).w_const[i]) > tolerance_constraint) { @@ -508,7 +508,7 @@ void Constraint::get_mapping_constraint(const int nmax, for (order = 0; order < nmax; ++order) { - nparam = fcs->nequiv[order].size(); + nparam = nequiv[order].size(); for (i = 0; i < nparam; ++i) { has_constraint[order].push_back(0); @@ -526,7 +526,7 @@ void Constraint::get_mapping_constraint(const int nmax, int icount; for (order = 0; order < nmax; ++order) { - nparam = fcs->nequiv[order].size(); + nparam = nequiv[order].size(); icount = 0; for (i = 0; i < nparam; ++i) { @@ -542,180 +542,417 @@ void Constraint::get_mapping_constraint(const int nmax, memory->deallocate(has_constraint); } - -void Constraint::constraint_from_symmetry(std::vector *const_out) +void Constraint::generate_symmetry_constraint_in_cartesian(std::vector *const_out) { // Create constraint matrices arising from the crystal symmetry. - int i; unsigned int isym; - int ixyz, nxyz; int order; int maxorder = interaction->maxorder; - - int *index_tmp; - int **xyzcomponent; - int nparams; - double *arr_constraint; bool has_constraint_from_symm = false; - std::set list_found; - std::vector> const_mat; for (isym = 0; isym < symmetry->nsym; ++isym) { if (symmetry->SymmData[isym].compatible_with_cartesian) continue; has_constraint_from_symm = true; } - for (order = 0; order < maxorder; ++order) const_out[order].clear(); - if (has_constraint_from_symm) { std::cout << " Generating constraints from crystal symmetry ..." << std::endl; } - memory->allocate(index_tmp, maxorder + 1); + for (order = 0; order < maxorder; ++order) { + if (has_constraint_from_symm) { + std::cout << " " << std::setw(8) << interaction->str_order[order] << " ..."; + } + get_symmetry_constraint(order, interaction->pairs[order], + symmetry->SymmData, "Cartesian", + fcs->fc_table[order], fcs->nequiv[order], + const_out[order]); + if (has_constraint_from_symm) { + std::cout << " done." << std::endl; + } + } + if (has_constraint_from_symm) { + std::cout << " Finished !" << std::endl << std::endl; + } +} + +//void Constraint::constraint_from_symmetry(std::vector *const_out) +//{ +// // Create constraint matrices arising from the crystal symmetry. +// +// int i; +// unsigned int isym; +// int ixyz, nxyz; +// int order; +// int maxorder = interaction->maxorder; +// +// int *index_tmp; +// int **xyzcomponent; +// int nparams; +// double *arr_constraint; +// bool has_constraint_from_symm = false; +// std::set list_found; +// std::vector> const_mat; +// +// for (isym = 0; isym < symmetry->nsym; ++isym) { +// if (symmetry->SymmData[isym].compatible_with_cartesian) continue; +// has_constraint_from_symm = true; +// } +// +// for (order = 0; order < maxorder; ++order) const_out[order].clear(); +// +// if (has_constraint_from_symm) { +// std::cout << " Generating constraints from crystal symmetry ..." << std::endl; +// } +// +// memory->allocate(index_tmp, maxorder + 1); +// +// const_mat.clear(); +// +// for (order = 0; order < maxorder; ++order) { +// +// nparams = fcs->nequiv[order].size(); +// +// if (has_constraint_from_symm) { +// std::cout << " " << std::setw(8) << interaction->str_order[order] << " ..."; +// if (nparams == 0) { +// std::cout << " No parameters! Skipped." << std::endl; +// continue; +// } +// } +// +// // Generate temporary list of parameters +// list_found.clear(); +// for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { +// for (i = 0; i < order + 2; ++i) index_tmp[i] = (*p).elems[i]; +// list_found.insert(FcProperty(order + 2, (*p).sign, +// index_tmp, (*p).mother)); +// } +// +// nxyz = static_cast(std::pow(static_cast(3), order + 2)); +// memory->allocate(xyzcomponent, nxyz, order + 2); +// fcs->get_xyzcomponent(order + 2, xyzcomponent); +// +// int nfcs = fcs->fc_table[order].size(); +// +//#ifdef _OPENMP +//#pragma omp parallel +//#endif +// { +// int j; +// int i_prim; +// int loc_nonzero; +// int *ind; +// int *atm_index, *atm_index_symm; +// int *xyz_index; +// double c_tmp; +// +// std::set::iterator iter_found; +// std::vector const_now_omp; +// std::vector> const_omp; +// +// memory->allocate(ind, order + 2); +// memory->allocate(atm_index, order + 2); +// memory->allocate(atm_index_symm, order + 2); +// memory->allocate(xyz_index, order + 2); +// +// const_omp.clear(); +// const_now_omp.resize(nparams); +// +//#ifdef _OPENMP +//#pragma omp for private(i, isym, ixyz), schedule(static) +//#endif +// for (int ii = 0; ii < nfcs; ++ii) { +// FcProperty list_tmp = fcs->fc_table[order][ii]; +// +// for (i = 0; i < order + 2; ++i) { +// atm_index[i] = list_tmp.elems[i] / 3; +// xyz_index[i] = list_tmp.elems[i] % 3; +// } +// +// for (isym = 0; isym < symmetry->nsym; ++isym) { +// +// if (symmetry->SymmData[isym].compatible_with_cartesian) continue; +// +// for (i = 0; i < order + 2; ++i) +// atm_index_symm[i] = symmetry->map_sym[atm_index[i]][isym]; +// if (!fcs->is_inprim(order + 2, atm_index_symm)) continue; +// +// for (i = 0; i < nparams; ++i) const_now_omp[i] = 0.0; +// +// const_now_omp[list_tmp.mother] = -list_tmp.sign; +// +// for (ixyz = 0; ixyz < nxyz; ++ixyz) { +// for (i = 0; i < order + 2; ++i) +// ind[i] = 3 * atm_index_symm[i] + xyzcomponent[ixyz][i]; +// +// i_prim = fcs->min_inprim(order + 2, ind); +// std::swap(ind[0], ind[i_prim]); +// fcs->sort_tail(order + 2, ind); +// +// iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); +// if (iter_found != list_found.end()) { +// c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); +// const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; +// } +// } +// if (!is_allzero(const_now_omp, eps8, loc_nonzero)) { +// if (const_now_omp[loc_nonzero] < 0.0) { +// for (j = 0; j < nparams; ++j) const_now_omp[j] *= -1.0; +// } +// const_omp.push_back(const_now_omp); +// } +// +// } // close isym loop +// +// if (const_omp.size() > nparams) rref(const_omp, tolerance_constraint); +// +// } // close ii loop +// +// memory->deallocate(ind); +// memory->deallocate(atm_index); +// memory->deallocate(atm_index_symm); +// memory->deallocate(xyz_index); +// +//#pragma omp critical +// { +// for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { +// const_mat.push_back(*it); +// } +// } +// const_omp.clear(); +// } // close openmp region +// +// memory->allocate(arr_constraint, nparams); +// for (auto it = const_mat.crbegin(); it != const_mat.crend(); ++it) { +// for (i = 0; i < nparams; ++i) { +// arr_constraint[i] = (*it)[i]; +// } +// const_out[order].push_back(ConstraintClass(nparams, +// arr_constraint)); +// } +// const_mat.clear(); +// +// memory->deallocate(xyzcomponent); +// memory->deallocate(arr_constraint); +// remove_redundant_rows(nparams, const_out[order], tolerance_constraint); +// +// if (has_constraint_from_symm) { +// std::cout << " done." << std::endl; +// } +// } // close loop order +// +// memory->deallocate(index_tmp); +// +// if (has_constraint_from_symm) { +// std::cout << " Finished !" << std::endl << std::endl; +// } +//} + +void Constraint::get_symmetry_constraint(const int order, const std::set pairs, + const std::vector symmop, + const std::string basis, + const std::vector fc_table, + const std::vector nequiv, + std::vector &const_out) +{ + // Create constraint matrices arising from the crystal symmetry. + + int i, j; + unsigned int isym; + int ixyz, nxyz; + int *index_tmp; + int **xyzcomponent; + int nparams; + int counter; + int nsym_in_use; + double *arr_constraint; + bool has_constraint_from_symm = false; + std::set list_found; + std::vector> const_mat; + int **map_sym; + double ***rotation; + + if (order < 0) return; + + int nsym = symmop.size(); + int nat = system->nat; + nparams = nequiv.size(); + + if (nparams == 0) return; + + memory->allocate(rotation, nsym, 3, 3); + memory->allocate(map_sym, nat, nsym); + memory->allocate(index_tmp, order + 2); + nxyz = static_cast(std::pow(static_cast(3), order + 2)); + memory->allocate(xyzcomponent, nxyz, order + 2); + fcs->get_xyzcomponent(order + 2, xyzcomponent); + nsym_in_use = 0; + counter = 0; const_mat.clear(); + int nfcs = fc_table.size(); - for (order = 0; order < maxorder; ++order) { + if (basis == "Cartesian") { - nparams = fcs->nequiv[order].size(); + for (auto it = symmop.begin(); it != symmop.end(); ++it) { - if (has_constraint_from_symm) { - std::cout << " " << std::setw(8) << interaction->str_order[order] << " ..."; - if (nparams == 0) { - std::cout << " No parameters! Skipped." << std::endl; - continue; + if (!(*it).compatible_with_cartesian) { + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + rotation[nsym_in_use][i][j] = (*it).rotation_cart[i][j]; + } + } + for (i = 0; i < nat; ++i) { + map_sym[i][nsym_in_use] = symmetry->map_sym[i][counter]; + } + ++nsym_in_use; } + ++counter; } - // Generate temporary list of parameters - list_found.clear(); - for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { - for (i = 0; i < order + 2; ++i) index_tmp[i] = (*p).elems[i]; - list_found.insert(FcProperty(order + 2, (*p).sign, - index_tmp, (*p).mother)); + } else if (basis == "Lattice") { + + for (auto it = symmop.begin(); it != symmop.end(); ++it) { + if (!(*it).compatible_with_lattice) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + rotation[nsym_in_use][i][j] + = static_cast((*it).rotation[i][j]); + } + } + for (i = 0; i < nat; ++i) { + map_sym[i][nsym_in_use] = symmetry->map_sym[i][counter]; + } + ++nsym_in_use; + } + ++counter; } - nxyz = static_cast(std::pow(static_cast(3), order + 2)); - memory->allocate(xyzcomponent, nxyz, order + 2); - fcs->get_xyzcomponent(order + 2, xyzcomponent); - int nfcs = fcs->fc_table[order].size(); + } else { + memory->deallocate(rotation); + memory->deallocate(map_sym); + error->exit("get_symmetry_constraint", "Invalid basis input"); + } + + // Generate temporary list of parameters + list_found.clear(); + for (auto p = fc_table.begin(); p != fc_table.end(); ++p) { + for (i = 0; i < order + 2; ++i) index_tmp[i] = (*p).elems[i]; + list_found.insert(FcProperty(order + 2, (*p).sign, + index_tmp, (*p).mother)); + } + #ifdef _OPENMP #pragma omp parallel #endif - { - int j; - int i_prim; - int loc_nonzero; - int *ind; - int *atm_index, *atm_index_symm; - int *xyz_index; - double c_tmp; - - std::set::iterator iter_found; - std::vector const_now_omp; - std::vector> const_omp; - - memory->allocate(ind, order + 2); - memory->allocate(atm_index, order + 2); - memory->allocate(atm_index_symm, order + 2); - memory->allocate(xyz_index, order + 2); - - const_omp.clear(); - const_now_omp.resize(nparams); + { + int j; + int i_prim; + int loc_nonzero; + int *ind; + int *atm_index, *atm_index_symm; + int *xyz_index; + double c_tmp; + + std::set::iterator iter_found; + std::vector const_now_omp; + std::vector> const_omp; + + memory->allocate(ind, order + 2); + memory->allocate(atm_index, order + 2); + memory->allocate(atm_index_symm, order + 2); + memory->allocate(xyz_index, order + 2); + + const_omp.clear(); + const_now_omp.resize(nparams); #ifdef _OPENMP #pragma omp for private(i, isym, ixyz), schedule(static) #endif - for (int ii = 0; ii < nfcs; ++ii) { - FcProperty list_tmp = fcs->fc_table[order][ii]; - - for (i = 0; i < order + 2; ++i) { - atm_index[i] = list_tmp.elems[i] / 3; - xyz_index[i] = list_tmp.elems[i] % 3; - } + for (int ii = 0; ii < nfcs; ++ii) { + FcProperty list_tmp = fc_table[ii]; - for (isym = 0; isym < symmetry->nsym; ++isym) { + for (i = 0; i < order + 2; ++i) { + atm_index[i] = list_tmp.elems[i] / 3; + xyz_index[i] = list_tmp.elems[i] % 3; + } - if (symmetry->SymmData[isym].compatible_with_cartesian) continue; + for (isym = 0; isym < nsym_in_use; ++isym) { - for (i = 0; i < order + 2; ++i) - atm_index_symm[i] = symmetry->map_sym[atm_index[i]][isym]; - if (!fcs->is_inprim(order + 2, atm_index_symm)) continue; + for (i = 0; i < order + 2; ++i) + atm_index_symm[i] = map_sym[atm_index[i]][isym]; + if (!fcs->is_inprim(order + 2, atm_index_symm)) continue; - for (i = 0; i < nparams; ++i) const_now_omp[i] = 0.0; + for (i = 0; i < nparams; ++i) const_now_omp[i] = 0.0; - const_now_omp[list_tmp.mother] = -list_tmp.sign; + const_now_omp[list_tmp.mother] = -list_tmp.sign; - for (ixyz = 0; ixyz < nxyz; ++ixyz) { - for (i = 0; i < order + 2; ++i) - ind[i] = 3 * atm_index_symm[i] + xyzcomponent[ixyz][i]; + for (ixyz = 0; ixyz < nxyz; ++ixyz) { + for (i = 0; i < order + 2; ++i) + ind[i] = 3 * atm_index_symm[i] + xyzcomponent[ixyz][i]; - i_prim = fcs->min_inprim(order + 2, ind); - std::swap(ind[0], ind[i_prim]); - fcs->sort_tail(order + 2, ind); + i_prim = fcs->min_inprim(order + 2, ind); + std::swap(ind[0], ind[i_prim]); + fcs->sort_tail(order + 2, ind); - iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); - if (iter_found != list_found.end()) { - c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); - const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; - } + iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); + if (iter_found != list_found.end()) { + c_tmp = fcs->coef_sym(order + 2, rotation[isym], xyz_index, xyzcomponent[ixyz]); + const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; } - if (!is_allzero(const_now_omp, eps8, loc_nonzero)) { - if (const_now_omp[loc_nonzero] < 0.0) { - for (j = 0; j < nparams; ++j) const_now_omp[j] *= -1.0; - } - const_omp.push_back(const_now_omp); + } + if (!is_allzero(const_now_omp, eps8, loc_nonzero)) { + if (const_now_omp[loc_nonzero] < 0.0) { + for (j = 0; j < nparams; ++j) const_now_omp[j] *= -1.0; } + const_omp.push_back(const_now_omp); + } - } // close isym loop + } // close isym loop - if (const_omp.size() > nparams) rref(const_omp, tolerance_constraint); + if (const_omp.size() > nparams) rref(const_omp, tolerance_constraint); - } // close ii loop + } // close ii loop - memory->deallocate(ind); - memory->deallocate(atm_index); - memory->deallocate(atm_index_symm); - memory->deallocate(xyz_index); + memory->deallocate(ind); + memory->deallocate(atm_index); + memory->deallocate(atm_index_symm); + memory->deallocate(xyz_index); #pragma omp critical - { - for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { - const_mat.push_back(*it); - } - } - const_omp.clear(); - } // close openmp region - - memory->allocate(arr_constraint, nparams); - for (auto it = const_mat.crbegin(); it != const_mat.crend(); ++it) { - for (i = 0; i < nparams; ++i) { - arr_constraint[i] = (*it)[i]; + { + for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { + const_mat.push_back(*it); } - const_out[order].push_back(ConstraintClass(nparams, - arr_constraint)); } - const_mat.clear(); + const_omp.clear(); + } // close openmp region - memory->deallocate(xyzcomponent); - memory->deallocate(arr_constraint); - remove_redundant_rows(nparams, const_out[order], tolerance_constraint); - - if (has_constraint_from_symm) { - std::cout << " done." << std::endl; + memory->allocate(arr_constraint, nparams); + for (auto it = const_mat.crbegin(); it != const_mat.crend(); ++it) { + for (i = 0; i < nparams; ++i) { + arr_constraint[i] = (*it)[i]; } - } // close loop order + const_out.push_back(ConstraintClass(nparams, + arr_constraint)); + } + const_mat.clear(); + memory->deallocate(xyzcomponent); + memory->deallocate(arr_constraint); memory->deallocate(index_tmp); + memory->deallocate(rotation); + memory->deallocate(map_sym); - if (has_constraint_from_symm) { - std::cout << " Finished !" << std::endl << std::endl; - } + remove_redundant_rows(nparams, const_out, tolerance_constraint); } + void Constraint::translational_invariance() { // Create constraint matrix for the translational invariance (aka acoustic sum rule). @@ -1481,72 +1718,6 @@ void Constraint::remove_redundant_rows(const int n, std::vector &Constraint_vec, const double tolerance) { -#ifdef _USE_EIGEN_DISABLED - - // This function doesn't make the reduced row echelon form of the constraint matrix. - // It just returns the image of the matrix, though they are similar. - - using namespace Eigen; - int i; - int nrow = n; - int ncol = Constraint_vec.size(); - double *arr_tmp; - double **mat; - - if (ncol > 0) { - memory->allocate(arr_tmp, nrow); - MatrixXd mat_tmp(nrow, ncol); - - int icol = 0; - - for (std::vector::iterator p = Constraint_vec.begin(); p != Constraint_vec.end(); ++p) { - ConstraintClass const_now = *p; - for (i = 0; i < nrow; ++i) { - mat_tmp(i, icol) = const_now.w_const[i]; - } - ++icol; - } - - FullPivLU lu_decomp(mat_tmp); - lu_decomp.setThreshold(tolerance); - int nrank = lu_decomp.rank(); - MatrixXd c_reduced = lu_decomp.image(mat_tmp); - - memory->allocate(mat, nrank, nrow); - - i = 0; - for (icol = 0; icol < nrank; ++icol) { - for (int irow = 0; irow < nrow; ++irow) { - mat[icol][irow] = c_reduced(irow, icol); - } - } - // std::cout << "nrank = " << nrank << std::flush << std::endl; - rref(nrank, nrow, mat, nrank, tolerance); - - Constraint_vec.clear(); - - for (i = 0; i < nrank; ++i) { - for (int j = 0; j < i; ++j) arr_tmp[j] = 0.0; - - for (int j = i; j < nrow; ++j) { - arr_tmp[j] = mat[i][j]; - } - Constraint_vec.push_back(ConstraintClass(nrow, arr_tmp)); - } - - memory->deallocate(mat); - - // for (icol = 0; icol < nrank; ++icol) { - // for (int irow = 0; irow < nrow; ++irow) { - // arr_tmp[irow] = c_reduced(irow, icol); - // } - - // Constraint_Set.insert(ConstraintClass(nrow, arr_tmp)); - // } - - memory->deallocate(arr_tmp); - } -#else int i, j; int nparam = n; @@ -1624,8 +1795,6 @@ void Constraint::remove_redundant_rows(const int n, memory->deallocate(arr_tmp); } - -#endif } int Constraint::levi_civita(const int i, const int j, const int k) diff --git a/alm/constraint.h b/alm/constraint.h index 0a3c35cf..9e566e20 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -16,6 +16,9 @@ #include #include "pointers.h" #include "constants.h" +#include "interaction.h" +#include "symmetry.h" +#include "fcs.h" #include namespace ALM_NS @@ -29,8 +32,8 @@ namespace ALM_NS ConstraintClass(const ConstraintClass &a) { - for (std::vector::const_iterator p = a.w_const.begin(); - p != a.w_const.end(); ++p) { + for (std::vector::const_iterator p = a.w_const.begin(); + p != a.w_const.end(); ++p) { w_const.push_back(*p); } } @@ -78,15 +81,17 @@ namespace ALM_NS std::copy(p_index_in.begin(), p_index_in.end(), std::back_inserter(p_index_orig)); } }; - inline bool equal_within_eps12(const std::vector &a, const std::vector &b) { + + inline bool equal_within_eps12(const std::vector &a, const std::vector &b) + { int n = a.size(); int m = b.size(); if (n != m) return false; double res = 0.0; for (int i = 0; i < n; ++i) { - if (std::abs(a[i] - b[i])> eps12) return false; + if (std::abs(a[i] - b[i]) > eps12) return false; } -// if (std::sqrt(res)>eps12) return false; + // if (std::sqrt(res)>eps12) return false; return true; } @@ -117,9 +122,16 @@ namespace ALM_NS std::vector *const_relate; boost::bimap *index_bimap; - void constraint_from_symmetry(std::vector *); + //void constraint_from_symmetry(std::vector *); + void get_symmetry_constraint(const int, const std::set, + const std::vector, + const std::string, + const std::vector, + const std::vector, + std::vector &); - void get_mapping_constraint(const int, std::vector *, + void get_mapping_constraint(const int, std::vector *, + std::vector *, std::vector *, std::vector *, boost::bimap *, const bool); @@ -150,6 +162,9 @@ namespace ALM_NS void rref(int, int, double **, int &, double tolerance = eps12); void rref(std::vector> &, const double tolerance = eps12); + + void generate_symmetry_constraint_in_cartesian(std::vector *); + }; extern "C" @@ -157,4 +172,3 @@ namespace ALM_NS void dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info); } } - diff --git a/alm/fcs.cpp b/alm/fcs.cpp index 78d788e0..a2b4f54c 100644 --- a/alm/fcs.cpp +++ b/alm/fcs.cpp @@ -32,9 +32,11 @@ Fcs::Fcs(ALM *alm) : Pointers(alm) Fcs::~Fcs() { - memory->deallocate(fc_table); - memory->deallocate(nequiv); - memory->deallocate(fc_zeros); + if (alm->mode == "fitting") { + memory->deallocate(fc_table); + memory->deallocate(nequiv); + memory->deallocate(fc_zeros); + } }; void Fcs::init() @@ -57,7 +59,6 @@ void Fcs::init() std::cout << std::endl; for (i = 0; i < maxorder; ++i) { - std::cout << " Number of " << std::setw(9) << interaction->str_order[i] << " FCs : " << nequiv[i].size(); @@ -73,15 +74,15 @@ void Fcs::init() // symmetry->SymmData, "Lattice", // fc_test, nmulti, fc_zeros_tmp, true); // std::cout << "Nonzero independent IFCs:" << std::setw(5) << nmulti.size() << std::endl; -// std::cout << "Zero IFCs:" << std::endl; -// for (auto it = fc_zeros_tmp.begin(); it != fc_zeros_tmp.end(); ++it) { -// for (i = 0; i < (*it).elems.size(); ++i) { -// std::cout << std::setw(4) << (*it).elems[i]; -// } -// std::cout << std::setw(5) << (*it).mother; -// std::cout << std::endl; -// } -// std::cout << std::endl; + // std::cout << "Zero IFCs:" << std::endl; + // for (auto it = fc_zeros_tmp.begin(); it != fc_zeros_tmp.end(); ++it) { + // for (i = 0; i < (*it).elems.size(); ++i) { + // std::cout << std::setw(4) << (*it).elems[i]; + // } + // std::cout << std::setw(5) << (*it).mother; + // std::cout << std::endl; + // } + // std::cout << std::endl; timer->print_elapsed(); diff --git a/alm/fcs.h b/alm/fcs.h index 2b3678e4..741f6856 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -82,8 +82,8 @@ namespace ALM_NS bool is_inprim(const int); int min_inprim(const int, const int *); double coef_sym(const int, const int, const int *, const int *); + double coef_sym(const int, double **, const int *, const int *); - private: void generate_force_constant_table(const int, const std::set, const std::vector, @@ -93,7 +93,8 @@ namespace ALM_NS std::vector &, const bool); + private: + bool is_ascending(const int, const int *); - double coef_sym(const int, double **, const int *, const int *); }; } diff --git a/alm/patterndisp.cpp b/alm/patterndisp.cpp index 195eabf3..5a832028 100644 --- a/alm/patterndisp.cpp +++ b/alm/patterndisp.cpp @@ -40,6 +40,7 @@ void Displace::gen_displacement_pattern() { int i, j, m, order; int maxorder = interaction->maxorder; + std::string preferred_basis; std::vector group_tmp; std::vector *constsym; @@ -47,17 +48,50 @@ void Displace::gen_displacement_pattern() std::set *include_set; std::set *dispset; + std::vector *nequiv; + std::vector *fc_table, *fc_zeros; + std::vector *const_fix_tmp; std::vector *const_relate_tmp; boost::bimap *index_bimap_tmp; + std::cout << " DISPLACEMENT PATTERN" << std::endl; + std::cout << " ====================" << std::endl << std::endl; + + // Decide preferred basis (Cartesian or Lattice) + int ncompat_cart = 0; + int ncompat_latt = 0; + for (auto it = symmetry->SymmData.begin(); it != symmetry->SymmData.end(); ++it) { + if ((*it).compatible_with_cartesian) ++ncompat_cart; + if ((*it).compatible_with_lattice) ++ncompat_latt; + } + if (ncompat_cart >= ncompat_latt) { + preferred_basis = "Cartesian"; + } else { + preferred_basis = "Lattice"; + } + + memory->allocate(fc_table, maxorder); + memory->allocate(fc_zeros, maxorder); memory->allocate(constsym, maxorder); + memory->allocate(nequiv, maxorder); memory->allocate(const_fix_tmp, maxorder); memory->allocate(const_relate_tmp, maxorder); memory->allocate(index_bimap_tmp, maxorder); - constraint->constraint_from_symmetry(constsym); - constraint->get_mapping_constraint(maxorder, constsym, const_fix_tmp, + for (order = 0; order < maxorder; ++order) { + fcs->generate_force_constant_table(order, interaction->pairs[order], + symmetry->SymmData, preferred_basis, + fc_table[order], nequiv[order], + fc_zeros[order], false); + + constraint->get_symmetry_constraint(order, interaction->pairs[order], + symmetry->SymmData, preferred_basis, + fc_table[order], nequiv[order], + constsym[order]); + } + + constraint->get_mapping_constraint(maxorder, nequiv, constsym, const_fix_tmp, const_relate_tmp, index_bimap_tmp, true); for (order = 0; order < maxorder; ++order) { @@ -70,6 +104,7 @@ void Displace::gen_displacement_pattern() memory->deallocate(constsym); memory->deallocate(const_fix_tmp); memory->deallocate(const_relate_tmp); + memory->deallocate(fc_zeros); memory->allocate(include_set, maxorder); @@ -85,12 +120,12 @@ void Displace::gen_displacement_pattern() memory->deallocate(index_bimap_tmp); - std::cout << " Generating displacement patterns in "; - if (disp_basis[0] == 'C') { - std::cout << "Cartesian coordinate..."; - } else { - std::cout << "fractional coordinate..."; - } + std::cout << " Generating displacement patterns in "; + // if (disp_basis[0] == 'C') { + std::cout << "Cartesian coordinate... "; + // } else { + // std::cout << "fractional coordinate..."; + // } memory->allocate(dispset, maxorder); @@ -98,7 +133,7 @@ void Displace::gen_displacement_pattern() m = 0; - for (i = 0; i < fcs->nequiv[order].size(); ++i) { + for (i = 0; i < nequiv[order].size(); ++i) { if (include_set[order].find(i) != include_set[order].end()) { @@ -108,7 +143,7 @@ void Displace::gen_displacement_pattern() // Here, duplicate entries will be removed. // For example, (iij) will be reduced to (ij). for (j = 0; j < order + 1; ++j) { - group_tmp.push_back(fcs->fc_table[order][m].elems[j]); + group_tmp.push_back(fc_table[order][m].elems[j]); } group_tmp.erase(std::unique(group_tmp.begin(), group_tmp.end()), group_tmp.end()); @@ -118,23 +153,35 @@ void Displace::gen_displacement_pattern() } - m += fcs->nequiv[order][i]; + m += nequiv[order][i]; } } memory->deallocate(include_set); + memory->deallocate(nequiv); + memory->deallocate(fc_table); memory->allocate(pattern_all, maxorder); - generate_pattern_all(maxorder, pattern_all, dispset); + generate_pattern_all(maxorder, pattern_all, + dispset, preferred_basis); memory->deallocate(dispset); std::cout << " done!" << std::endl; + std::cout << std::endl; + + for (order = 0; order < maxorder; ++order) { + std::cout << " Number of disp. patterns for " << std::setw(9) + << interaction->str_order[order] << " : " + << pattern_all[order].size() << std::endl; + } + std::cout << std::endl; } void Displace::generate_pattern_all(const int N, std::vector *pattern, - std::set *dispset_in) + std::set *dispset_in, + const std::string preferred_basis) { int i, j; int order; @@ -158,8 +205,7 @@ void Displace::generate_pattern_all(const int N, pattern[order].clear(); - for (std::set::iterator it = dispset_in[order].begin(); - it != dispset_in[order].end(); ++it) { + for (auto it = dispset_in[order].begin(); it != dispset_in[order].end(); ++it) { atoms.clear(); directions.clear(); @@ -184,7 +230,7 @@ void Displace::generate_pattern_all(const int N, if (trim_dispsign_for_evenfunc) { find_unique_sign_pairs(natom_disp, sign_prod[natom_disp - 1], - nums, sign_reduced); + nums, sign_reduced, preferred_basis); } else { sign_reduced.clear(); std::copy(sign_prod[natom_disp - 1].begin(), @@ -196,8 +242,7 @@ void Displace::generate_pattern_all(const int N, std::copy(directions.begin(), directions.end(), std::back_inserter(directions_copy)); - for (std::vector>::const_iterator it2 = sign_reduced.begin(); - it2 != sign_reduced.end(); ++it2) { + for (auto it2 = sign_reduced.cbegin(); it2 != sign_reduced.cend(); ++it2) { directions.clear(); for (i = 0; i < (*it2).size(); ++i) { @@ -207,11 +252,19 @@ void Displace::generate_pattern_all(const int N, disp_tmp[j] = directions_copy[3 * i + j] * sign_double; } - if (disp_basis[0] == 'F') { - rotvec(disp_tmp, disp_tmp, system->rlavec); - for (j = 0; j < 3; ++j) { - disp_tmp[j] /= 2.0 * pi; - } + // if (disp_basis[0] == 'F') { + // rotvec(disp_tmp, disp_tmp, system->rlavec); + // for (j = 0; j < 3; ++j) { + // disp_tmp[j] /= 2.0 * pi; + // } + // } + + if (preferred_basis == "Lattice") { + rotvec(disp_tmp, disp_tmp, system->lavec); + double norm = 0.0; + for (j = 0; j < 3; ++j) norm += disp_tmp[j] * disp_tmp[j]; + norm = std::sqrt(norm); + for (j = 0; j < 3; ++j) disp_tmp[j] /= norm; } for (j = 0; j < 3; ++j) { @@ -254,7 +307,8 @@ void Displace::generate_signvecs(const int N, void Displace::find_unique_sign_pairs(const int N, std::vector> sign_in, std::vector pair_in, - std::vector> &sign_out) + std::vector> &sign_out, + const std::string preferred_basis) { int isym, i, j, k; int mapped_atom; @@ -334,9 +388,21 @@ void Displace::find_unique_sign_pairs(const int N, for (j = 0; j < 3; ++j) { disp_sym[mapped_atom][j] = 0.0; - for (k = 0; k < 3; ++k) { - disp_sym[mapped_atom][j] - += symmetry->SymmData[isym].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; + + if (preferred_basis == "Cartesian") { + for (k = 0; k < 3; ++k) { + disp_sym[mapped_atom][j] + += symmetry->SymmData[isym].rotation_cart[j][k] * disp[list_disp_atom[i]][k]; + } + } else if (preferred_basis == "Lattice") { + for (k = 0; k < 3; ++k) { + disp_sym[mapped_atom][j] + += static_cast(symmetry->SymmData[isym].rotation[j][k]) + * disp[list_disp_atom[i]][k]; + } + } else { + error->exit("find_unique_sign_pairs", + "Invalid basis. This cannot happen."); } disp_tmp = disp_sym[mapped_atom][j]; @@ -388,10 +454,23 @@ void Displace::find_unique_sign_pairs(const int N, for (j = 0; j < 3; ++j) { disp_sym[mapped_atom][j] = 0.0; - for (k = 0; k < 3; ++k) { - disp_sym[mapped_atom][j] += symmetry->SymmData[symnum_vec[isym]].rotation_cart[j][k] - * disp[list_disp_atom[i]][k]; + if (preferred_basis == "Cartesian") { + for (k = 0; k < 3; ++k) { + disp_sym[mapped_atom][j] + += symmetry->SymmData[symnum_vec[isym]].rotation_cart[j][k] + * disp[list_disp_atom[i]][k]; + } + } else if (preferred_basis == "Lattice") { + for (k = 0; k < 3; ++k) { + disp_sym[mapped_atom][j] + += static_cast(symmetry->SymmData[symnum_vec[isym]].rotation[j][k]) + * disp[list_disp_atom[i]][k]; + } + } else { + error->exit("find_unique_sign_pairs", + "Invalid basis. This cannot happen."); } + disp_tmp = disp_sym[mapped_atom][j]; if (std::abs(disp_tmp) > eps) { diff --git a/alm/patterndisp.h b/alm/patterndisp.h index 1bb23cb4..387acaa7 100644 --- a/alm/patterndisp.h +++ b/alm/patterndisp.h @@ -134,15 +134,17 @@ namespace ALM_NS std::vector disp_harm, disp_harm_best; void generate_pattern_all(const int, std::vector *, - std::set *); + std::set *, + const std::string); void generate_signvecs(const int, - std::vector > &, + std::vector> &, std::vector); void find_unique_sign_pairs(const int, - std::vector >, + std::vector>, std::vector, - std::vector > &); + std::vector> &, + const std::string); }; } diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index c5a94596..c20d1d49 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -69,24 +69,24 @@ void Symmetry::init() // } // std::cout << std::endl; - int counter = 0; - for (auto it = SymmData.begin(); it != SymmData.end(); ++it) { - std::cout << "Symm. No. : " << std::setw(4) << counter + 1; - std::cout << "( " << (*it).compatible_with_lattice << " " << (*it).compatible_with_cartesian << ")" << std::endl; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - std::cout << std::setw(15) << (*it).rotation[i][j]; - } - std::cout << " "; - for (j = 0; j < 3; ++j) { - std::cout << std::setw(15) << (*it).rotation_cart[i][j]; - } - - std::cout << std::endl; - } - std::cout << std::endl; - ++counter; - } +// int counter = 0; +// for (auto it = SymmData.begin(); it != SymmData.end(); ++it) { +// std::cout << "Symm. No. : " << std::setw(4) << counter + 1; +// std::cout << "( " << (*it).compatible_with_lattice << " " << (*it).compatible_with_cartesian << ")" << std::endl; +// for (i = 0; i < 3; ++i) { +// for (j = 0; j < 3; ++j) { +// std::cout << std::setw(15) << (*it).rotation[i][j]; +// } +// std::cout << " "; +// for (j = 0; j < 3; ++j) { +// std::cout << std::setw(15) << (*it).rotation_cart[i][j]; +// } +// +// std::cout << std::endl; +// } +// std::cout << std::endl; +// ++counter; +// } pure_translations(); diff --git a/alm/writes.cpp b/alm/writes.cpp index 1e7d6c79..4d6a8d1b 100644 --- a/alm/writes.cpp +++ b/alm/writes.cpp @@ -280,8 +280,8 @@ void Writes::write_displacement_pattern() int counter; std::ofstream ofs_pattern; - - std::cout << " Suggested displacement patterns are printed in the following files: " << std::endl; + std::cout << std::endl; + std::cout << " Displacement patterns are saved in the following files: " << std::endl; for (order = 0; order < maxorder; ++order) { ofs_pattern.open(files->file_disp_pattern[order].c_str(), std::ios::out); @@ -293,7 +293,7 @@ void Writes::write_displacement_pattern() ofs_pattern << "Basis : " << displace->disp_basis[0] << std::endl; - for (std::vector::iterator it = displace->pattern_all[order].begin(); + for (auto it = displace->pattern_all[order].begin(); it != displace->pattern_all[order].end(); ++it) { AtomWithDirection entry = *it; From 007aaddd858ab48952ed3b9524bc8616ba245376 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Fri, 24 Nov 2017 21:45:35 +0900 Subject: [PATCH 14/33] Refactor symmetry.cpp --- alm/symmetry.cpp | 94 ++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/alm/symmetry.cpp b/alm/symmetry.cpp index 9b528f7d..a78a7c30 100644 --- a/alm/symmetry.cpp +++ b/alm/symmetry.cpp @@ -69,24 +69,24 @@ void Symmetry::init() // } // std::cout << std::endl; -// int counter = 0; -// for (auto it = SymmData.begin(); it != SymmData.end(); ++it) { -// std::cout << "Symm. No. : " << std::setw(4) << counter + 1; -// std::cout << "( " << (*it).compatible_with_lattice << " " << (*it).compatible_with_cartesian << ")" << std::endl; -// for (i = 0; i < 3; ++i) { -// for (j = 0; j < 3; ++j) { -// std::cout << std::setw(15) << (*it).rotation[i][j]; -// } -// std::cout << " "; -// for (j = 0; j < 3; ++j) { -// std::cout << std::setw(15) << (*it).rotation_cart[i][j]; -// } -// -// std::cout << std::endl; -// } -// std::cout << std::endl; -// ++counter; -// } + // int counter = 0; + // for (auto it = SymmData.begin(); it != SymmData.end(); ++it) { + // std::cout << "Symm. No. : " << std::setw(4) << counter + 1; + // std::cout << "( " << (*it).compatible_with_lattice << " " << (*it).compatible_with_cartesian << ")" << std::endl; + // for (i = 0; i < 3; ++i) { + // for (j = 0; j < 3; ++j) { + // std::cout << std::setw(15) << (*it).rotation[i][j]; + // } + // std::cout << " "; + // for (j = 0; j < 3; ++j) { + // std::cout << std::setw(15) << (*it).rotation_cart[i][j]; + // } + // + // std::cout << std::endl; + // } + // std::cout << std::endl; + // ++counter; + // } pure_translations(); @@ -233,7 +233,7 @@ void Symmetry::setup_symmetry_operation(int nat, } #ifdef _DEBUG - // print_symmetrized_coordinate(x); + // print_symmetrized_coordinate(x); #endif } @@ -509,37 +509,37 @@ void Symmetry::find_crystal_symmetry(int nat, for (j = 0; j < 3; ++j) { rot_cart[i][j] /= (2.0 * pi); } - } + } if (system->lspin && system->noncollinear) { for (i = 0; i < 3; ++i) { mag[i] = system->magmom[jat][i]; mag_rot[i] = system->magmom[iat][i]; - } + } - rotvec(mag_rot, mag_rot, rot_cart); + rotvec(mag_rot, mag_rot, rot_cart); - // In the case of improper rotation, the factor -1 should be multiplied - // because the inversion operation doesn't flip the spin. - if (!is_proper(rot_cart)) { - for (i = 0; i < 3; ++i) { - mag_rot[i] = -mag_rot[i]; + // In the case of improper rotation, the factor -1 should be multiplied + // because the inversion operation doesn't flip the spin. + if (!is_proper(rot_cart)) { + for (i = 0; i < 3; ++i) { + mag_rot[i] = -mag_rot[i]; + } } - } - mag_sym1 = (std::pow(mag[0] - mag_rot[0], 2.0) - + std::pow(mag[1] - mag_rot[1], 2.0) - + std::pow(mag[2] - mag_rot[2], 2.0)) < eps6; + mag_sym1 = (std::pow(mag[0] - mag_rot[0], 2.0) + + std::pow(mag[1] - mag_rot[1], 2.0) + + std::pow(mag[2] - mag_rot[2], 2.0)) < eps6; - mag_sym2 = (std::pow(mag[0] + mag_rot[0], 2.0) - + std::pow(mag[1] + mag_rot[1], 2.0) - + std::pow(mag[2] + mag_rot[2], 2.0)) < eps6; + mag_sym2 = (std::pow(mag[0] + mag_rot[0], 2.0) + + std::pow(mag[1] + mag_rot[1], 2.0) + + std::pow(mag[2] + mag_rot[2], 2.0)) < eps6; - if (!mag_sym1 && !mag_sym2) { - isok = false; - } else if (!mag_sym1 && mag_sym2 && !trev_sym_mag) { - isok = false; + if (!mag_sym1 && !mag_sym2) { + isok = false; + } else if (!mag_sym1 && mag_sym2 && !trev_sym_mag) { + isok = false; } } } @@ -571,21 +571,21 @@ void Symmetry::symop_in_cart(double rot_cart[3][3], double sym_tmp[3][3]; double tmp[3][3]; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { sym_tmp[i][j] = static_cast(rot_lattice[i][j]); - } } + } - matmul3(tmp, sym_tmp, rlavec); + matmul3(tmp, sym_tmp, rlavec); matmul3(rot_cart, lavec, tmp); - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { rot_cart[i][j] = rot_cart[i][j] / (2.0 * pi); - } } } +} void Symmetry::pure_translations() @@ -736,13 +736,13 @@ bool Symmetry::is_compatible(const T rot[3][3], int nfinite; double rot_double[3][3]; - nfinite = 0; + nfinite = 0; for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { rot_double[i][j] = static_cast(rot[i][j]); if (std::abs(rot_double[i][j]) > tolerance_zero) ++nfinite; - } } + } if (nfinite == 3) return true; From 4d3454d62afd1f585e489020cc695fd3d2a5f812 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Sat, 25 Nov 2017 16:40:27 +0900 Subject: [PATCH 15/33] Fixed minor memory leak issues --- alm/constraint.cpp | 35 ++++++++++++++++++++++++----------- alm/interaction.cpp | 6 ++++++ alm/system.cpp | 27 ++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 8ad80bd3..42b10678 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -30,22 +30,33 @@ using namespace ALM_NS; Constraint::Constraint(ALM *alm) : Pointers(alm) { + const_symmetry = nullptr; + const_fix = nullptr; + const_relate = nullptr; + index_bimap = nullptr; + const_mat = nullptr; + const_rhs = nullptr; } Constraint::~Constraint() { - if (exist_constraint && alm->mode == "fitting") { - + if (const_symmetry) { memory->deallocate(const_symmetry); - - if (constraint_algebraic) { - memory->deallocate(const_fix); - memory->deallocate(const_relate); - memory->deallocate(index_bimap); - } else { - memory->deallocate(const_mat); - memory->deallocate(const_rhs); - } + } + if (const_fix) { + memory->deallocate(const_fix); + } + if (const_relate) { + memory->deallocate(const_relate); + } + if (index_bimap) { + memory->deallocate(index_bimap); + } + if (const_mat) { + memory->deallocate(const_mat); + } + if (const_rhs) { + memory->deallocate(const_rhs); } } @@ -540,6 +551,8 @@ void Constraint::get_mapping_constraint(const int nmax, } memory->deallocate(has_constraint); + memory->deallocate(fix_forceconstant); + memory->deallocate(file_forceconstant); } void Constraint::generate_symmetry_constraint_in_cartesian(std::vector *const_out) diff --git a/alm/interaction.cpp b/alm/interaction.cpp index 68262a6e..ae429b08 100644 --- a/alm/interaction.cpp +++ b/alm/interaction.cpp @@ -30,6 +30,7 @@ using namespace ALM_NS; Interaction::Interaction(ALM *alm) : Pointers(alm) { + rcs = nullptr; } Interaction::~Interaction() @@ -43,6 +44,9 @@ Interaction::~Interaction() memory->deallocate(interaction_pair); memory->deallocate(mindist_cluster); memory->deallocate(distall); + if (rcs) { + memory->deallocate(rcs); + } } void Interaction::init() @@ -193,6 +197,8 @@ void Interaction::generate_coordinate_of_periodic_images(const unsigned int nat, for (ja = -1; ja <= 1; ++ja) { for (ka = -1; ka <= 1; ++ka) { + if (ia == 0 && ja == 0 && ka == 0) continue; + ++icell; // When periodic flag is zero along an axis, diff --git a/alm/system.cpp b/alm/system.cpp index 0b313909..3267c5f3 100644 --- a/alm/system.cpp +++ b/alm/system.cpp @@ -32,13 +32,34 @@ using namespace ALM_NS; System::System(ALM *alm): Pointers(alm) { + kdname = nullptr; + kd = nullptr; + xcoord = nullptr; + magmom = nullptr; + x_cartesian = nullptr; + atomlist_class = nullptr; } System::~System() { - memory->deallocate(x_cartesian); - memory->deallocate(atomlist_class); - memory->deallocate(magmom); + if (kdname) { + memory->deallocate(kdname); + } + if (kd) { + memory->deallocate(kd); + } + if (xcoord) { + memory->deallocate(xcoord); + } + if (magmom) { + memory->deallocate(magmom); + } + if (x_cartesian) { + memory->deallocate(x_cartesian); + } + if (atomlist_class) { + memory->deallocate(atomlist_class); + } } void System::init() From 3f41331211958af89ccac7a602f60dad20893a4e Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Tue, 28 Nov 2017 15:22:49 +0900 Subject: [PATCH 16/33] Testing the connection of band dispersion using the similarity of eigenvectors --- anphon/dynamical.cpp | 113 +++++++++++++++++++++++++++++++++++++-- anphon/dynamical.h | 3 ++ anphon/parsephon.cpp | 11 +++- anphon/write_phonons.cpp | 47 ++++++++++++++-- 4 files changed, 162 insertions(+), 12 deletions(-) diff --git a/anphon/dynamical.cpp b/anphon/dynamical.cpp index 5681a333..561040a4 100644 --- a/anphon/dynamical.cpp +++ b/anphon/dynamical.cpp @@ -28,12 +28,14 @@ #include "phonon_dos.h" #include "gruneisen.h" #include "ewald.h" +#include using namespace PHON_NS; Dynamical::Dynamical(PHON *phon): Pointers(phon) { + index_bconnect = nullptr; } Dynamical::~Dynamical() @@ -114,6 +116,7 @@ void Dynamical::setup_dynamical(std::string mode) MPI_Bcast(&eigenvectors, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD); MPI_Bcast(&nonanalytic, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD); + MPI_Bcast(&band_connection, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD); if (nonanalytic) { memory->allocate(borncharge, system->natmin, 3, 3); @@ -148,6 +151,10 @@ void PHON_NS::Dynamical::finish_dynamical() if (nonanalytic) { memory->deallocate(borncharge); } + + if (index_bconnect) { + memory->deallocate(index_bconnect); + } } @@ -741,6 +748,11 @@ void Dynamical::diagonalize_dynamical_all() } } + if (band_connection > 0 && kpoint->kpoint_mode == 1) { + memory->allocate(index_bconnect, nk, neval); + connect_band_by_eigen_similarity(evec_phonon, index_bconnect); + } + if (mympi->my_rank == 0) { std::cout << "done!" << std::endl; } @@ -852,8 +864,8 @@ void Dynamical::load_born() for (j = 0; j < 3; ++j) { for (k = 0; k < 3; ++k) { - std::cout << std::setw(15) << std::fixed - << std::setprecision(6) << borncharge[i][j][k]; + std::cout << std::setw(15) << std::fixed + << std::setprecision(6) << borncharge[i][j][k]; } std::cout << std::endl; } @@ -930,7 +942,7 @@ void Dynamical::load_born() } } } - + for (iat = 0; iat < system->natmin; ++iat) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { @@ -963,14 +975,14 @@ void Dynamical::load_born() } } memory->deallocate(born_sym); - + if (diff_sym > eps8 || res > eps10) { std::cout << std::endl; std::cout << " Symmetrized Born effective charge tensor in Cartesian coordinate." << std::endl; for (i = 0; i < system->natmin; ++i) { std::cout << " Atom" << std::setw(5) << i + 1 << "(" << std::setw(3) << system->symbol_kd[system->kd[system->map_p2s[i][0]]] << ") :" << std::endl; - + for (j = 0; j < 3; ++j) { for (k = 0; k < 3; ++k) { std::cout << std::setw(15) << borncharge[i][j][k]; @@ -1055,3 +1067,94 @@ void Dynamical::calc_atomic_participation_ratio(std::complex *evec, doub for (iat = 0; iat < natmin; ++iat) ret[iat] /= std::sqrt(static_cast(natmin) * sum); } + + +void Dynamical::connect_band_by_eigen_similarity(std::complex ***evec, + int **index_sorted) +{ + int ik, is, js, ks; + unsigned int nk = kpoint->nk; + unsigned int ns = neval; + int loc; + std::vector index; + std::complex **evec_tmp; + std::vector> abs_similarity; + std::complex dprod; + std::vector found; + + memory->allocate(evec_tmp, ns, ns); + + for (ik = 0; ik < nk; ++ik) { + for (is = 0; is < ns; ++is) { + index_sorted[ik][is] = 0; + } + } + + index.resize(ns); + found.resize(ns); + abs_similarity.resize(ns); + for (is = 0; is < ns; ++is) { + abs_similarity[is].resize(ns); + } + + for (int i = 0; i < ns; ++i) index[i] = i; + + for (ik = 0; ik < nk; ++ik) { + + if (ik == 0) { + for (is = 0; is < ns; ++is) { + for (js = 0; js < ns; ++js) { + if (is == js) { + abs_similarity[is][js] = 1.0; + } else { + abs_similarity[is][js] = 0.0; + } + } + } + } else { +//#ifdef _OPENMP +//#pragma omp parallel for private(js, ks, dprod) +//#endif + for (is = 0; is < ns; ++is) { + for (js = 0; js < ns; ++js) { + dprod = std::complex(0.0, 0.0); + for (ks = 0; ks < ns; ++ks) { + dprod += std::conj(evec[ik][is][ks]) * evec_tmp[js][ks]; + } + abs_similarity[is][js] = std::abs(dprod); + } + } + } + + for (auto &v : found) v = 0; + + for (is = 0; is < ns; ++is) { + + for (auto it = abs_similarity[is].begin(); it != abs_similarity[is].end(); ++it) { + std::cout << (*it) << std::endl; + } + std::cout << std::endl; + // Argsort abs_similarity[is] (use C++11 lambda) + iota(index.begin(), index.end(), 0); + std::sort(index.begin(), index.end(), + [&abs_similarity, is](int i1, int i2) { + return abs_similarity[is][i1] > abs_similarity[is][i2]; + }); + + loc = index[0]; + index_sorted[ik][loc] = is; + found[loc] = 1; + for (js = 0; js < ns; ++js) abs_similarity[js][loc] = -1.0; + for (js = 0; js < ns; ++js) { + evec_tmp[loc][js] = evec[ik][is][js]; + } + } + + if (std::any_of(found.begin(), found.end(), [](int i1) { return i1 == 0; })) { + error->exit("connect_band_by_eigen_similarity", + "Could not identify the connection."); + } + + } + memory->deallocate(evec_tmp); +} diff --git a/anphon/dynamical.h b/anphon/dynamical.h index 9d17fc6f..6a5f455a 100644 --- a/anphon/dynamical.h +++ b/anphon/dynamical.h @@ -53,11 +53,13 @@ namespace PHON_NS bool print_eigenvectors; unsigned int nonanalytic; bool participation_ratio; + unsigned int band_connection; std::string file_born; double na_sigma; double **eval_phonon; + int **index_bconnect; std::complex ***evec_phonon; double dielec[3][3]; double ***borncharge; @@ -101,6 +103,7 @@ namespace PHON_NS void prepare_mindist_list(std::vector **); void calc_atomic_participation_ratio(std::complex *, double *); double distance(double *, double *); + void connect_band_by_eigen_similarity(std::complex ***, int **); // void calc_analytic_k(double *, double ****, std::complex **); // void modify_eigenvectors_sym(); diff --git a/anphon/parsephon.cpp b/anphon/parsephon.cpp index e8caccd9..992e2bb1 100644 --- a/anphon/parsephon.cpp +++ b/anphon/parsephon.cpp @@ -120,6 +120,7 @@ void Input::parse_general_vars() bool selenergy_offdiagonal; bool update_fc2; bool classical; + unsigned int band_connection; struct stat st; std::string prefix, mode, fcsinfo, fc2info; @@ -128,7 +129,7 @@ void Input::parse_general_vars() std::string str_tmp; std::string str_allowed_list = "PREFIX MODE NSYM TOLERANCE PRINTSYM FCSXML FC2XML TMIN TMAX DT \ NBANDS NONANALYTIC BORNINFO NA_SIGMA ISMEAR EPSILON EMIN EMAX DELTA_E \ - RESTART TREVSYM NKD KD MASS TRISYM PREC_EWALD CLASSICAL"; + RESTART TREVSYM NKD KD MASS TRISYM PREC_EWALD CLASSICAL BCONNECT"; std::string str_no_defaults = "PREFIX MODE FCSXML NKD KD MASS"; std::vector no_defaults; std::vector kdname_v, masskd_v; @@ -207,6 +208,7 @@ void Input::parse_general_vars() sym_time_reversal = false; use_triplet_symmetry = true; classical = false; + band_connection = 0; prec_ewald = 1.0e-12; @@ -253,9 +255,13 @@ void Input::parse_general_vars() assign_val(epsilon, "EPSILON", general_var_dict); assign_val(na_sigma, "NA_SIGMA", general_var_dict); assign_val(classical, "CLASSICAL", general_var_dict); - + assign_val(band_connection, "BCONNECT", general_var_dict); assign_val(use_triplet_symmetry, "TRISYM", general_var_dict); + if (band_connection < 0 || band_connection > 2) { + error->exit("parse_general_vars", "BCONNECT-tag can take 0, 1, or 2."); + } + if (nonanalytic == 3) { assign_val(prec_ewald, "PREC_EWALD", general_var_dict); if (prec_ewald <= 0.0 || prec_ewald >= 1.0) { @@ -314,6 +320,7 @@ void Input::parse_general_vars() dynamical->na_sigma = na_sigma; writes->nbands = nbands; dynamical->file_born = borninfo; + dynamical->band_connection = band_connection; integration->epsilon = epsilon; fcs_phonon->file_fcs = fcsinfo; if (!fc2info.empty()) { diff --git a/anphon/write_phonons.cpp b/anphon/write_phonons.cpp index b21d633b..e0eaaa9f 100644 --- a/anphon/write_phonons.cpp +++ b/anphon/write_phonons.cpp @@ -101,6 +101,7 @@ void Writes::write_input_vars() << "; EPSILON = " << integration->epsilon << std::endl; std::cout << std::endl; std::cout << " CLASSICAL = " << thermodynamics->classical << std::endl; + std::cout << " BCONNECT = " << dynamical->band_connection << std::endl; std::cout << std::endl; if (phon->mode == "RTA") { @@ -597,18 +598,54 @@ void Writes::write_phonon_bands() ofs_bands << "#" << str_kval << std::endl; ofs_bands << "# k-axis, Eigenvalues [cm^-1]" << std::endl; - for (i = 0; i < nk; ++i) { - ofs_bands << std::setw(8) << std::fixed << kaxis[i]; - for (j = 0; j < nbands; ++j) { - ofs_bands << std::setw(15) << std::scientific << in_kayser(eval[i][j]); + if (dynamical->band_connection == 0) { + for (i = 0; i < nk; ++i) { + ofs_bands << std::setw(8) << std::fixed << kaxis[i]; + for (j = 0; j < nbands; ++j) { + ofs_bands << std::setw(15) << std::scientific << in_kayser(eval[i][j]); + } + ofs_bands << std::endl; + } + } else { + for (i = 0; i < nk; ++i) { + ofs_bands << std::setw(8) << std::fixed << kaxis[i]; + for (j = 0; j < nbands; ++j) { + ofs_bands << std::setw(15) << std::scientific + << in_kayser(eval[i][dynamical->index_bconnect[i][j]]); + } + ofs_bands << std::endl; } - ofs_bands << std::endl; } ofs_bands.close(); std::cout << " " << std::setw(input->job_title.length() + 12) << std::left << file_bands; std::cout << " : Phonon band structure" << std::endl; + + if (dynamical->band_connection == 2) { + std::ofstream ofs_connect; + std::string file_connect = input->job_title + ".connection"; + + ofs_connect.open(file_connect.c_str(), std::ios::out); + if (!ofs_connect) + error->exit("write_phonon_bands", + "cannot open file_connect"); + + ofs_connect << "# " << str_kpath << std::endl; + ofs_connect << "#" << str_kval << std::endl; + ofs_connect << "# k-axis, mapping" << std::endl; + + for (i = 0; i < nk; ++i) { + ofs_connect << std::setw(8) << std::fixed << kaxis[i]; + for (j = 0; j < nbands; ++j) { + ofs_connect << std::setw(5) << dynamical->index_bconnect[i][j] + 1; + } + ofs_connect << std::endl; + } + ofs_connect.close(); + std::cout << " " << std::setw(input->job_title.length() + 12) << std::left << file_connect; + std::cout << " : Connectivity map information of band dispersion" << std::endl; + } } void Writes::write_phonon_vel() From e59d62cf54b5b3bc51475cceda15b8aa3f28dc2c Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Tue, 28 Nov 2017 15:32:01 +0900 Subject: [PATCH 17/33] The BCONNECT seems to work correctly --- anphon/dynamical.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/anphon/dynamical.cpp b/anphon/dynamical.cpp index 561040a4..a6eb626a 100644 --- a/anphon/dynamical.cpp +++ b/anphon/dynamical.cpp @@ -1112,9 +1112,9 @@ void Dynamical::connect_band_by_eigen_similarity(std::complex ***evec, } } } else { -//#ifdef _OPENMP -//#pragma omp parallel for private(js, ks, dprod) -//#endif +#ifdef _OPENMP +#pragma omp parallel for private(js, ks, dprod) +#endif for (is = 0; is < ns; ++is) { for (js = 0; js < ns; ++js) { dprod = std::complex(0.0, 0.0); @@ -1130,10 +1130,6 @@ void Dynamical::connect_band_by_eigen_similarity(std::complex ***evec, for (is = 0; is < ns; ++is) { - for (auto it = abs_similarity[is].begin(); it != abs_similarity[is].end(); ++it) { - std::cout << (*it) << std::endl; - } - std::cout << std::endl; // Argsort abs_similarity[is] (use C++11 lambda) iota(index.begin(), index.end(), 0); std::sort(index.begin(), index.end(), From 2274bc3220fc522c9fa900aa38c03e931d7cfc39 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Tue, 28 Nov 2017 22:03:27 +0900 Subject: [PATCH 18/33] Cleanup the codes --- alm/alamode.h | 1 - alm/combination.h | 5 ++- alm/constraint.h | 1 - alm/error.h | 1 - alm/interaction.h | 11 +++--- alm/memory.h | 1 - alm/pointers.h | 9 +++-- alm/system.h | 1 - alm/timer.h | 1 - alm/writes.cpp | 82 +++++++++++++++++++-------------------- alm/writes.h | 12 ++++-- anphon/pointers.h | 9 +++-- anphon/relaxation.cpp | 6 +-- anphon/scph.cpp | 2 +- anphon/selfenergy.cpp | 2 +- anphon/thermodynamics.cpp | 7 ++-- anphon/write_phonons.cpp | 8 ++-- tools/analyze_phonons.cpp | 4 +- 18 files changed, 84 insertions(+), 79 deletions(-) diff --git a/alm/alamode.h b/alm/alamode.h index 3a2771c3..7fdbb494 100644 --- a/alm/alamode.h +++ b/alm/alamode.h @@ -40,4 +40,3 @@ namespace ALM_NS std::string mode; }; } - diff --git a/alm/combination.h b/alm/combination.h index c0c8f93c..492f4c13 100644 --- a/alm/combination.h +++ b/alm/combination.h @@ -25,7 +25,9 @@ namespace ALM_NS public: - CombinationWithRepetition() {}; + CombinationWithRepetition() + { + }; template CombinationWithRepetition(InputIter begin, @@ -75,4 +77,3 @@ namespace ALM_NS } }; } - diff --git a/alm/constraint.h b/alm/constraint.h index 9e566e20..baa6ea0e 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -164,7 +164,6 @@ namespace ALM_NS void rref(std::vector> &, const double tolerance = eps12); void generate_symmetry_constraint_in_cartesian(std::vector *); - }; extern "C" diff --git a/alm/error.h b/alm/error.h index 1b76c3bc..7d90525a 100644 --- a/alm/error.h +++ b/alm/error.h @@ -27,4 +27,3 @@ namespace ALM_NS void exit(const char *, const char *, const char *); }; } - diff --git a/alm/interaction.h b/alm/interaction.h index a4a3036e..c62cef8a 100644 --- a/alm/interaction.h +++ b/alm/interaction.h @@ -177,13 +177,13 @@ namespace ALM_NS { public: std::vector atom; - std::vector > cell; + std::vector> cell; double distmax; MinimumDistanceCluster(); MinimumDistanceCluster(const std::vector atom_in, - const std::vector > cell_in, + const std::vector> cell_in, const double dist_in) { for (int i = 0; i < atom_in.size(); ++i) { @@ -196,7 +196,7 @@ namespace ALM_NS } MinimumDistanceCluster(const std::vector atom_in, - const std::vector > cell_in) + const std::vector> cell_in) { for (int i = 0; i < atom_in.size(); ++i) { atom.push_back(atom_in[i]); @@ -279,11 +279,10 @@ namespace ALM_NS std::vector **, int *, std::set **); - void cell_combination(std::vector >, + void cell_combination(std::vector>, int, std::vector, - std::vector > &); + std::vector> &); void generate_pairs(std::set *, std::set **); }; } - diff --git a/alm/memory.h b/alm/memory.h index 4da3cdc7..bf0bca7e 100644 --- a/alm/memory.h +++ b/alm/memory.h @@ -169,4 +169,3 @@ namespace ALM_NS } }; } - diff --git a/alm/pointers.h b/alm/pointers.h index f1bec298..77e7af4b 100644 --- a/alm/pointers.h +++ b/alm/pointers.h @@ -31,9 +31,13 @@ namespace ALM_NS displace(ptr->displace), writes(ptr->writes), error(ptr->error), - timer(ptr->timer) {} + timer(ptr->timer) + { + } - virtual ~Pointers() {} + virtual ~Pointers() + { + } protected: ALM *alm; @@ -52,4 +56,3 @@ namespace ALM_NS Timer *&timer; }; } - diff --git a/alm/system.h b/alm/system.h index a358760b..450ea699 100644 --- a/alm/system.h +++ b/alm/system.h @@ -68,4 +68,3 @@ namespace ALM_NS void setup_atomic_class(int *); }; } - diff --git a/alm/timer.h b/alm/timer.h index 760923c3..1c963a8d 100644 --- a/alm/timer.h +++ b/alm/timer.h @@ -42,4 +42,3 @@ namespace ALM_NS #endif }; } - diff --git a/alm/writes.cpp b/alm/writes.cpp index 4d6a8d1b..f84e4271 100644 --- a/alm/writes.cpp +++ b/alm/writes.cpp @@ -495,7 +495,7 @@ void Writes::write_misc_xml() std::sort(fcs->fc_table[0].begin(), fcs->fc_table[0].end()); for (std::vector::iterator it = fcs->fc_table[0].begin(); - it != fcs->fc_table[0].end(); ++it) { + it != fcs->fc_table[0].end(); ++it) { FcProperty fctmp = *it; ip = fctmp.mother; @@ -530,7 +530,7 @@ void Writes::write_misc_xml() std::sort(fcs->fc_table[order].begin(), fcs->fc_table[order].end()); for (std::vector::iterator it = fcs->fc_table[order].begin(); - it != fcs->fc_table[order].end(); ++it) { + it != fcs->fc_table[order].end(); ++it) { FcProperty fctmp = *it; ip = fctmp.mother + ishift; @@ -652,45 +652,45 @@ void Writes::write_hessian() std::cout << " Complete Hessian matrix : " << files->file_hes << std::endl; - /* - std::string file_fc2 = files->job_title + ".fc2"; - std::ofstream ofs_fc2; - ofs_fc2.open(file_fc2.c_str(), std::ios::out); - ofs_fc2 << " # iat, icrd, jat, icrd, icell, relvec, fc2" << std::endl; - double vec[3]; - for (std::vector::iterator it = fcs->fc_table[0].begin(); - it != fcs->fc_table[0].end(); ++it) { - FcProperty fctmp = *it; - ip = fctmp.mother; - - for (i = 0; i < 2; ++i) pair_tmp[i] = fctmp.elems[i] / 3; - for (itran = 0; itran < symmetry->ntran; ++itran) { - for (i = 0; i < 2; ++i) { - pair_tran[i] = symmetry->map_sym[pair_tmp[i]][symmetry->symnum_tran[itran]]; - } - for (std::vector::iterator - it2 = interaction->mindist_pairs[pair_tran[0]][pair_tran[1]].begin(); - it2 != interaction->mindist_pairs[pair_tran[0]][pair_tran[1]].end(); ++it2) { - int multiplicity = interaction->mindist_pairs[pair_tran[0]][pair_tran[1]].size(); - for (i = 0; i < 3; ++i) { - vec[i] = interaction->x_image[(*it2).cell][pair_tran[1]][i] - - interaction->x_image[0][pair_tran[0]][i]; - } - ofs_fc2 << std::setw(5) << pair_tran[0] + 1 << std::setw(5) << fctmp.elems[0] % 3 + 1; - ofs_fc2 << std::setw(5) << pair_tran[1] + 1 << std::setw(5) << fctmp.elems[1] % 3 + 1; - ofs_fc2 << std::setw(5) << (*it2).cell + 1; - ofs_fc2 << std::setw(15) << vec[0]; - ofs_fc2 << std::setw(15) << vec[1]; - ofs_fc2 << std::setw(15) << vec[2]; - - ofs_fc2 << std::setw(15) - << fitting->params[ip] * fctmp.sign / static_cast(multiplicity); - ofs_fc2 << std::endl; - } - } - } - ofs_fc2.close(); - */ + /* + std::string file_fc2 = files->job_title + ".fc2"; + std::ofstream ofs_fc2; + ofs_fc2.open(file_fc2.c_str(), std::ios::out); + ofs_fc2 << " # iat, icrd, jat, icrd, icell, relvec, fc2" << std::endl; + double vec[3]; + for (std::vector::iterator it = fcs->fc_table[0].begin(); + it != fcs->fc_table[0].end(); ++it) { + FcProperty fctmp = *it; + ip = fctmp.mother; + + for (i = 0; i < 2; ++i) pair_tmp[i] = fctmp.elems[i] / 3; + for (itran = 0; itran < symmetry->ntran; ++itran) { + for (i = 0; i < 2; ++i) { + pair_tran[i] = symmetry->map_sym[pair_tmp[i]][symmetry->symnum_tran[itran]]; + } + for (std::vector::iterator + it2 = interaction->mindist_pairs[pair_tran[0]][pair_tran[1]].begin(); + it2 != interaction->mindist_pairs[pair_tran[0]][pair_tran[1]].end(); ++it2) { + int multiplicity = interaction->mindist_pairs[pair_tran[0]][pair_tran[1]].size(); + for (i = 0; i < 3; ++i) { + vec[i] = interaction->x_image[(*it2).cell][pair_tran[1]][i] + - interaction->x_image[0][pair_tran[0]][i]; + } + ofs_fc2 << std::setw(5) << pair_tran[0] + 1 << std::setw(5) << fctmp.elems[0] % 3 + 1; + ofs_fc2 << std::setw(5) << pair_tran[1] + 1 << std::setw(5) << fctmp.elems[1] % 3 + 1; + ofs_fc2 << std::setw(5) << (*it2).cell + 1; + ofs_fc2 << std::setw(15) << vec[0]; + ofs_fc2 << std::setw(15) << vec[1]; + ofs_fc2 << std::setw(15) << vec[2]; + + ofs_fc2 << std::setw(15) + << fitting->params[ip] * fctmp.sign / static_cast(multiplicity); + ofs_fc2 << std::endl; + } + } + } + ofs_fc2.close(); + */ } std::string Writes::double2string(const double d, const int nprec) diff --git a/alm/writes.h b/alm/writes.h index 0e48f7b8..7225e6bc 100644 --- a/alm/writes.h +++ b/alm/writes.h @@ -24,11 +24,15 @@ namespace ALM_NS int kind; int atom, tran; - AtomProperty() {}; + AtomProperty() + { + }; AtomProperty(const AtomProperty &other) : x(other.x), y(other.y), z(other.z), - kind(other.kind), atom(other.atom), tran(other.tran) {}; + kind(other.kind), atom(other.atom), tran(other.tran) + { + }; AtomProperty(const double *pos, const int kind_in, @@ -52,7 +56,9 @@ namespace ALM_NS int nat, natmin, ntran; int nspecies; - SystemInfo() {}; + SystemInfo() + { + }; }; class Writes: protected Pointers diff --git a/anphon/pointers.h b/anphon/pointers.h index ac2946ca..6b681003 100644 --- a/anphon/pointers.h +++ b/anphon/pointers.h @@ -40,9 +40,13 @@ namespace PHON_NS isotope(ptr->isotope), scph(ptr->scph), ewald(ptr->ewald), - timer(ptr->timer) {} + timer(ptr->timer) + { + } - virtual ~Pointers() {} + virtual ~Pointers() + { + } protected: PHON *phon; @@ -70,4 +74,3 @@ namespace PHON_NS Timer *&timer; }; } - diff --git a/anphon/relaxation.cpp b/anphon/relaxation.cpp index b1ae48e4..43be072d 100644 --- a/anphon/relaxation.cpp +++ b/anphon/relaxation.cpp @@ -1208,7 +1208,7 @@ void Relaxation::calc_frequency_resolved_final_state(const unsigned int N, n1 = f1 + f2 + 1.0; n2 = f1 - f2; } - + if (integration->ismear == 0) { prod_tmp[0] = n1 * (delta_lorentz(omega0 - omega_inner[0] - omega_inner[1], epsilon) @@ -2542,7 +2542,7 @@ void Relaxation::print_momentum_resolved_final_state(const unsigned int NT, n1 = f1 + f2 + 1.0; n2 = f1 - f2; } - + if (selection_type == 0) { gamma_k[k][iT] += V3norm * n1; @@ -3120,7 +3120,7 @@ void Relaxation::calc_self3omega_tetrahedron(const double Temp, n1 = f1 + f2 + 1.0; n2 = f1 - f2; } - + //#pragma omp critical ret_private[nomega * ithread + iomega] += v3_arr[ik][ib] * (n1 * weight_tetra[0][ik] - 2.0 * n2 * weight_tetra[1][ik]); diff --git a/anphon/scph.cpp b/anphon/scph.cpp index 0b9bb89d..1ee007fa 100644 --- a/anphon/scph.cpp +++ b/anphon/scph.cpp @@ -115,7 +115,7 @@ void Scph::exec_scph() write_scph_bands(eval_anharm); } else if (kpoint->kpoint_mode == 2) { write_scph_dos(eval_anharm); - // write_scph_thermodynamics(eval_anharm); + // write_scph_thermodynamics(eval_anharm); if (writes->print_msd) { write_scph_msd(eval_anharm, evec_anharm); } diff --git a/anphon/selfenergy.cpp b/anphon/selfenergy.cpp index c1d161e5..b1cf66a1 100644 --- a/anphon/selfenergy.cpp +++ b/anphon/selfenergy.cpp @@ -127,7 +127,7 @@ void Selfenergy::selfenergy_tadpole(const unsigned int N, } else { n2 = thermodynamics->fB(omega2, T_tmp); ret_mpi[i] += v3_tmp2 * (2.0 * n2 + 1.0); - } + } } } } diff --git a/anphon/thermodynamics.cpp b/anphon/thermodynamics.cpp index f9f94d54..cb57a4cb 100644 --- a/anphon/thermodynamics.cpp +++ b/anphon/thermodynamics.cpp @@ -273,7 +273,7 @@ double Thermodynamics::free_energy(const double T) x = omega / (T * T_to_Ryd); ret += std::log(x); } - + return T * T_to_Ryd * ret / static_cast(nk); } else { @@ -297,7 +297,6 @@ double Thermodynamics::free_energy(const double T) return T * T_to_Ryd * ret / static_cast(nk); } - } double Thermodynamics::disp2_avg(const double T, @@ -325,7 +324,7 @@ double Thermodynamics::disp2_avg(const double T, if (omega < eps8) continue; ret += real(dynamical->evec_phonon[ik][is][ns1] - * std::conj(dynamical->evec_phonon[ik][is][ns2])) + * std::conj(dynamical->evec_phonon[ik][is][ns2])) * T * T_to_Ryd / (omega * omega); } } else { @@ -340,7 +339,7 @@ double Thermodynamics::disp2_avg(const double T, if (omega < eps8) continue; ret += real(dynamical->evec_phonon[ik][is][ns1] - * std::conj(dynamical->evec_phonon[ik][is][ns2])) + * std::conj(dynamical->evec_phonon[ik][is][ns2])) * (fB(omega, T) + 0.5) / omega; } } diff --git a/anphon/write_phonons.cpp b/anphon/write_phonons.cpp index e0eaaa9f..17a192bd 100644 --- a/anphon/write_phonons.cpp +++ b/anphon/write_phonons.cpp @@ -282,7 +282,7 @@ void Writes::setup_result_io() } if (static_cast(is_classical) != thermodynamics->classical) { error->warn("setup_result_io", - "CLASSICAL val is not consistent"); + "CLASSICAL val is not consistent"); } found_tag = false; @@ -610,8 +610,8 @@ void Writes::write_phonon_bands() for (i = 0; i < nk; ++i) { ofs_bands << std::setw(8) << std::fixed << kaxis[i]; for (j = 0; j < nbands; ++j) { - ofs_bands << std::setw(15) << std::scientific - << in_kayser(eval[i][dynamical->index_bconnect[i][j]]); + ofs_bands << std::setw(15) << std::scientific + << in_kayser(eval[i][dynamical->index_bconnect[i][j]]); } ofs_bands << std::endl; } @@ -629,7 +629,7 @@ void Writes::write_phonon_bands() ofs_connect.open(file_connect.c_str(), std::ios::out); if (!ofs_connect) error->exit("write_phonon_bands", - "cannot open file_connect"); + "cannot open file_connect"); ofs_connect << "# " << str_kpath << std::endl; ofs_connect << "#" << str_kval << std::endl; diff --git a/tools/analyze_phonons.cpp b/tools/analyze_phonons.cpp index 917878d0..e9352dc9 100644 --- a/tools/analyze_phonons.cpp +++ b/tools/analyze_phonons.cpp @@ -563,7 +563,7 @@ void calc_kappa_cumulative(double max_length, double delta_length, int itemp) } else { c_tmp = Cv(omega[ik][is], temp[itemp]); } - + vel_tmp = pow(vel[ik][is][0][0], 2) + pow(vel[ik][is][0][1], 2) + pow(vel[ik][is][0][2], 2); @@ -782,7 +782,7 @@ void calc_kappa_boundary2(double max_length, double delta_length, int itemp, int c_tmp = k_Boltzmann; } else { c_tmp = Cv(omega[ik][is], temp[itemp]); - } + } for (i = 0; i < nsame; ++i) { From f0f2f7b6497f478a3ed1f7b456f2844c48a4a475 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Mon, 25 Dec 2017 13:02:21 +0900 Subject: [PATCH 19/33] cleanup codes --- alm/fitting.cpp | 1 - alm/symmetry.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/alm/fitting.cpp b/alm/fitting.cpp index f84bcf4c..bb1149c0 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -124,7 +124,6 @@ void Fitting::fitmain() if (constraint->constraint_algebraic) { - N_new = 0; for (i = 0; i < maxorder; ++i) { N_new += constraint->index_bimap[i].size(); diff --git a/alm/symmetry.h b/alm/symmetry.h index 8836cfa1..33511447 100644 --- a/alm/symmetry.h +++ b/alm/symmetry.h @@ -155,7 +155,7 @@ namespace ALM_NS void find_lattice_symmetry(double [3][3], std::vector &); void find_crystal_symmetry(int, int, - std::vector *, double **x, + std::vector *, double **, std::vector, std::vector &); From 9996b6b1f03139da82feaed5148e711dfb02f2fe Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Mon, 25 Dec 2017 21:09:58 +0900 Subject: [PATCH 20/33] Added codes to optimize the performance of translational_invariance. Still not successful. --- alm/constraint.cpp | 254 ++++++++++++++++++++++++++++++++++++++++++--- alm/constraint.h | 8 ++ 2 files changed, 249 insertions(+), 13 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 42b10678..62af28f4 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -1066,7 +1066,7 @@ void Constraint::translational_invariance() iter_found = list_found.find( FcProperty(order + 2, 1.0, intarr, 1)); - // If found a IFC + // If found an IFC if (iter_found != list_found.end()) { // Round the coefficient to integer const_now[(*iter_found).mother] += nint((*iter_found).sign); @@ -1193,8 +1193,7 @@ void Constraint::translational_invariance() // Merge vectors #pragma omp critical { - for (std::vector>::iterator it = const_omp.begin(); - it != const_omp.end(); ++it) { + for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } } @@ -1214,17 +1213,20 @@ void Constraint::translational_invariance() std::sort(const_mat.begin(), const_mat.end()); const_mat.erase(std::unique(const_mat.begin(), const_mat.end()), const_mat.end()); - // timer->print_elapsed(); + + // rref_nofraction3(const_mat); + } // close loop i memory->deallocate(xyzcomponent); memory->deallocate(intarr); memory->deallocate(intarr_copy); // Copy to constraint class - +#ifdef _USE_EIGEN + rref_nofraction3(const_mat); +#endif const_translation[order].clear(); - for (std::vector>::reverse_iterator it = const_mat.rbegin(); - it != const_mat.rend(); ++it) { + for (auto it = const_mat.rbegin(); it != const_mat.rend(); ++it) { for (i = 0; i < (*it).size(); ++i) { arr_constraint[i] = static_cast((*it)[i]); } @@ -1233,7 +1235,7 @@ void Constraint::translational_invariance() } const_mat.clear(); memory->deallocate(arr_constraint); - +// std::cout << "HERE " << std::endl; remove_redundant_rows(nparams, const_translation[order], eps8); std::cout << " done." << std::endl; @@ -1365,7 +1367,7 @@ void Constraint::rotational_invariance() for (j = 0; j < nparam_sub; ++j) arr_constraint[j] = 0.0; - for (std::vector::iterator iter_list = interaction_list_now.begin(); + for (auto iter_list = interaction_list_now.begin(); iter_list != interaction_list_now.end(); ++iter_list) { jat = *iter_list; @@ -1490,7 +1492,7 @@ void Constraint::rotational_invariance() for (j = 0; j < nparam_sub; ++j) arr_constraint[j] = 0.0; // Loop for m_{N+1}, a_{N+1} - for (std::vector::iterator iter_list = interaction_list.begin(); + for (auto iter_list = interaction_list.begin(); iter_list != interaction_list.end(); ++iter_list) { jat = *iter_list; @@ -1810,6 +1812,7 @@ void Constraint::remove_redundant_rows(const int n, } } + int Constraint::levi_civita(const int i, const int j, const int k) { int epsilon = (j - i) * (k - i) * (k - j) / 2; @@ -1935,7 +1938,7 @@ void Constraint::rref(int nrows, if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; if (pivot != irow) { - //#pragma omp parallel for private(tmp) +#pragma omp parallel for private(tmp) for (jcol = icol; jcol < ncols; ++jcol) { tmp = mat[pivot][jcol]; mat[pivot][jcol] = mat[irow][jcol]; @@ -1945,7 +1948,7 @@ void Constraint::rref(int nrows, tmp = mat[irow][icol]; tmp = 1.0 / tmp; - //#pragma omp parallel for +#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[irow][jcol] *= tmp; } @@ -1954,7 +1957,7 @@ void Constraint::rref(int nrows, if (jrow == irow) continue; tmp = mat[jrow][icol]; - //#pragma omp parallel for +#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[jrow][jcol] -= tmp * mat[irow][jcol]; } @@ -2025,3 +2028,228 @@ void Constraint::rref(std::vector> &mat, const double tolera mat.erase(mat.begin() + nrank, mat.end()); mat.shrink_to_fit(); } + + +void Constraint::rref_nofraction(std::vector> &mat) +{ + // Return the reduced row echelon form (rref) of matrix mat. + // In addition, rank of the matrix is estimated. + + int irow, icol, jrow, jcol; + int pivot; + int tmp, tmp2; + + int nrank = 0; + + icol = 0; + + int nrows = mat.size(); + int ncols = mat[0].size(); + + for (irow = 0; irow < nrows; ++irow) { + + pivot = irow; + + while (mat[pivot][icol] == 0) { + ++pivot; + + if (pivot == nrows) { + pivot = irow; + ++icol; + + if (icol == ncols) break; + } + } + + if (icol == ncols) break; + + if (std::abs(mat[pivot][icol]) > 0) ++nrank; + + // swap rows + if (pivot != irow) { +#pragma omp parallel for private(tmp) + for (jcol = icol; jcol < ncols; ++jcol) { + tmp = mat[pivot][jcol]; + mat[pivot][jcol] = mat[irow][jcol]; + mat[irow][jcol] = tmp; + } + } + + tmp = mat[irow][icol]; + + for (jrow = 0; jrow < nrows; ++jrow) { + if (jrow == irow) continue; + + tmp2 = mat[jrow][icol]; +#pragma omp parallel for + for (jcol = icol; jcol < ncols; ++jcol) { + mat[jrow][jcol] = mat[jrow][jcol] * tmp - tmp2 * mat[irow][jcol]; + } + } + } + + mat.erase(mat.begin() + nrank, mat.end()); + mat.shrink_to_fit(); +} + + +void Constraint::rref_nofraction2(std::vector> &mat) +{ + // Return the reduced row echelon form (rref) of matrix mat. + // In addition, rank of the matrix is estimated. + + int irow, icol, jrow, jcol; + int pivot; + int tmp, tmp2; + + int nrank = 0; + + icol = 0; + + float *mat_flatten; + float **Umat; + int *ipiv; + int info; + + int nrows = mat.size(); + int ncols = mat[0].size(); + + + int k = 0; + memory->allocate(mat_flatten, nrows*ncols); + memory->allocate(ipiv, std::min(nrows,ncols)); + memory->allocate(Umat, nrows, ncols); + for (icol = 0; icol < ncols; ++icol) { + for (irow = 0; irow < nrows; ++irow) { + mat_flatten[k++] = static_cast(mat[irow][icol]); + } + } + std::cout << "Size of matrix: " << nrows << "x" << ncols << std::endl; + std::cout << "Start LU decomposition" << std::endl; + sgetrf_(&nrows, &ncols, mat_flatten, &nrows, ipiv, &info); + std::cout << "Finish LU decomposition" << std::endl; + std::cout << "INFO = " << info << std::endl; + std::cout << "Matrix U:" << std::endl; + + k = 0; + for (icol = 0; icol < ncols; ++icol) { + for (irow = 0; irow < nrows; ++irow) { + if (irow > icol) { + Umat[irow][icol] = 0.0; + } else { + Umat[irow][icol] = mat_flatten[k]; + } + ++k; + } + } + int nzeros = 0; + float max = 0.0; + for (irow = 0; irow < nrows; ++irow) { + max = 0.0; + for (icol = 0; icol < ncols; ++icol) { + std::cout << std::setw(5) << Umat[irow][icol]; + max = std::max(max, std::abs(Umat[irow][icol])); + } + std::cout << std::endl; + std::cout << "max = " << max << std::endl; + } + std::cout << std::endl; + memory->deallocate(mat_flatten); + memory->deallocate(ipiv); + memory->deallocate(Umat); + + for (irow = 0; irow < nrows; ++irow) { + + pivot = irow; + + while (mat[pivot][icol] == 0) { + ++pivot; + + if (pivot == nrows) { + pivot = irow; + ++icol; + + if (icol == ncols) break; + } + } + + if (icol == ncols) break; + + if (std::abs(mat[pivot][icol]) > 0) ++nrank; + + // swap rows + if (pivot != irow) { +#pragma omp parallel for private(tmp) + for (jcol = icol; jcol < ncols; ++jcol) { + tmp = mat[pivot][jcol]; + mat[pivot][jcol] = mat[irow][jcol]; + mat[irow][jcol] = tmp; + } + } + + tmp = mat[irow][icol]; + + for (jrow = 0; jrow < nrows; ++jrow) { + if (jrow == irow) continue; + + tmp2 = mat[jrow][icol]; +#pragma omp parallel for + for (jcol = icol; jcol < ncols; ++jcol) { + mat[jrow][jcol] = mat[jrow][jcol] * tmp - tmp2 * mat[irow][jcol]; + } + } + } + + mat.erase(mat.begin() + nrank, mat.end()); + mat.shrink_to_fit(); +} + + +#ifdef _USE_EIGEN +void Constraint::rref_nofraction3(std::vector> &mat) +{ + // Return the reduced row echelon form (rref) of matrix mat. + // In addition, rank of the matrix is estimated. + + using namespace Eigen; + + int irow, icol, jrow, jcol; + int pivot; + int tmp, tmp2; + + int nrank = 0; + + icol = 0; + + int nrows = mat.size(); + int ncols = mat[0].size(); + + MatrixXf A(ncols, nrows); + + for (irow = 0; irow < nrows; ++irow) { + for (icol = 0; icol < ncols; ++icol) { + A(icol, irow) = static_cast(mat[irow][icol]); + } + } +// std::cout << "Start LU decomposition" << std::endl; + FullPivLU lu_decomp(A); +// std::cout << "Finish LU decomposition" << std::endl; + nrank = lu_decomp.rank(); + MatrixXf B = lu_decomp.image(A).transpose(); + + // std::cout << "rank = " << lu_decomp.rank() << std::endl; + // std::cout << "image of matrix A:" << std::endl; + // std::cout << lu_decomp.image(A) << std::endl; + + for (irow = 0; irow < nrank; ++irow) { + for (icol = 0; icol < ncols; ++icol) { +// std::cout << std::setw(3) << B(irow, icol); + mat[irow][icol] = static_cast(B(irow, icol) + 0.5); + } +// std::cout << std::endl; + } + + mat.erase(mat.begin() + nrank, mat.end()); + mat.shrink_to_fit(); +} +#endif diff --git a/alm/constraint.h b/alm/constraint.h index baa6ea0e..504c980f 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -159,9 +159,15 @@ namespace ALM_NS void remove_redundant_rows(const int, std::vector &, const double tolerance = eps12); + // void remove_redundant_rows_integer(const int, std::vector> &); void rref(int, int, double **, int &, double tolerance = eps12); void rref(std::vector> &, const double tolerance = eps12); + void rref_nofraction(std::vector> &); + void rref_nofraction2(std::vector> &); +#ifdef _USE_EIGEN + void rref_nofraction3(std::vector> &); +#endif void generate_symmetry_constraint_in_cartesian(std::vector *); }; @@ -169,5 +175,7 @@ namespace ALM_NS extern "C" { void dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info); + void sgetrf_(int *m, int *n, float *a, int *lda, int *ipiv, int *info); + } } From 63dfc901be1b5bb7a985db42a5c25a127cb1889a Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Tue, 26 Dec 2017 18:50:20 +0900 Subject: [PATCH 21/33] Unfortunately, optimization of translational_invariance() seems not to work well. Maybe, I need to use the (sparse) QR decomposition to achieve speed up. --- alm/constraint.cpp | 366 +++------------------------------------------ alm/constraint.h | 3 +- 2 files changed, 21 insertions(+), 348 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 62af28f4..a62b0844 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -318,8 +318,7 @@ void Constraint::calc_constraint_matrix(const int N, int &P) if ((order == 0 && !fix_harmonic) || (order == 1 && !fix_cubic) || order > 1) { for (i = 0; i < N; ++i) arr_tmp[i] = 0.0; - for (std::vector::iterator p = const_self[order].begin(); - p != const_self[order].end(); ++p) { + for (auto p = const_self[order].begin(); p != const_self[order].end(); ++p) { ConstraintClass const_now = *p; for (i = 0; i < nparam; ++i) { arr_tmp[nshift + i] = const_now.w_const[i]; @@ -591,179 +590,6 @@ void Constraint::generate_symmetry_constraint_in_cartesian(std::vector *const_out) -//{ -// // Create constraint matrices arising from the crystal symmetry. -// -// int i; -// unsigned int isym; -// int ixyz, nxyz; -// int order; -// int maxorder = interaction->maxorder; -// -// int *index_tmp; -// int **xyzcomponent; -// int nparams; -// double *arr_constraint; -// bool has_constraint_from_symm = false; -// std::set list_found; -// std::vector> const_mat; -// -// for (isym = 0; isym < symmetry->nsym; ++isym) { -// if (symmetry->SymmData[isym].compatible_with_cartesian) continue; -// has_constraint_from_symm = true; -// } -// -// for (order = 0; order < maxorder; ++order) const_out[order].clear(); -// -// if (has_constraint_from_symm) { -// std::cout << " Generating constraints from crystal symmetry ..." << std::endl; -// } -// -// memory->allocate(index_tmp, maxorder + 1); -// -// const_mat.clear(); -// -// for (order = 0; order < maxorder; ++order) { -// -// nparams = fcs->nequiv[order].size(); -// -// if (has_constraint_from_symm) { -// std::cout << " " << std::setw(8) << interaction->str_order[order] << " ..."; -// if (nparams == 0) { -// std::cout << " No parameters! Skipped." << std::endl; -// continue; -// } -// } -// -// // Generate temporary list of parameters -// list_found.clear(); -// for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { -// for (i = 0; i < order + 2; ++i) index_tmp[i] = (*p).elems[i]; -// list_found.insert(FcProperty(order + 2, (*p).sign, -// index_tmp, (*p).mother)); -// } -// -// nxyz = static_cast(std::pow(static_cast(3), order + 2)); -// memory->allocate(xyzcomponent, nxyz, order + 2); -// fcs->get_xyzcomponent(order + 2, xyzcomponent); -// -// int nfcs = fcs->fc_table[order].size(); -// -//#ifdef _OPENMP -//#pragma omp parallel -//#endif -// { -// int j; -// int i_prim; -// int loc_nonzero; -// int *ind; -// int *atm_index, *atm_index_symm; -// int *xyz_index; -// double c_tmp; -// -// std::set::iterator iter_found; -// std::vector const_now_omp; -// std::vector> const_omp; -// -// memory->allocate(ind, order + 2); -// memory->allocate(atm_index, order + 2); -// memory->allocate(atm_index_symm, order + 2); -// memory->allocate(xyz_index, order + 2); -// -// const_omp.clear(); -// const_now_omp.resize(nparams); -// -//#ifdef _OPENMP -//#pragma omp for private(i, isym, ixyz), schedule(static) -//#endif -// for (int ii = 0; ii < nfcs; ++ii) { -// FcProperty list_tmp = fcs->fc_table[order][ii]; -// -// for (i = 0; i < order + 2; ++i) { -// atm_index[i] = list_tmp.elems[i] / 3; -// xyz_index[i] = list_tmp.elems[i] % 3; -// } -// -// for (isym = 0; isym < symmetry->nsym; ++isym) { -// -// if (symmetry->SymmData[isym].compatible_with_cartesian) continue; -// -// for (i = 0; i < order + 2; ++i) -// atm_index_symm[i] = symmetry->map_sym[atm_index[i]][isym]; -// if (!fcs->is_inprim(order + 2, atm_index_symm)) continue; -// -// for (i = 0; i < nparams; ++i) const_now_omp[i] = 0.0; -// -// const_now_omp[list_tmp.mother] = -list_tmp.sign; -// -// for (ixyz = 0; ixyz < nxyz; ++ixyz) { -// for (i = 0; i < order + 2; ++i) -// ind[i] = 3 * atm_index_symm[i] + xyzcomponent[ixyz][i]; -// -// i_prim = fcs->min_inprim(order + 2, ind); -// std::swap(ind[0], ind[i_prim]); -// fcs->sort_tail(order + 2, ind); -// -// iter_found = list_found.find(FcProperty(order + 2, 1.0, ind, 1)); -// if (iter_found != list_found.end()) { -// c_tmp = fcs->coef_sym(order + 2, isym, xyz_index, xyzcomponent[ixyz]); -// const_now_omp[(*iter_found).mother] += (*iter_found).sign * c_tmp; -// } -// } -// if (!is_allzero(const_now_omp, eps8, loc_nonzero)) { -// if (const_now_omp[loc_nonzero] < 0.0) { -// for (j = 0; j < nparams; ++j) const_now_omp[j] *= -1.0; -// } -// const_omp.push_back(const_now_omp); -// } -// -// } // close isym loop -// -// if (const_omp.size() > nparams) rref(const_omp, tolerance_constraint); -// -// } // close ii loop -// -// memory->deallocate(ind); -// memory->deallocate(atm_index); -// memory->deallocate(atm_index_symm); -// memory->deallocate(xyz_index); -// -//#pragma omp critical -// { -// for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { -// const_mat.push_back(*it); -// } -// } -// const_omp.clear(); -// } // close openmp region -// -// memory->allocate(arr_constraint, nparams); -// for (auto it = const_mat.crbegin(); it != const_mat.crend(); ++it) { -// for (i = 0; i < nparams; ++i) { -// arr_constraint[i] = (*it)[i]; -// } -// const_out[order].push_back(ConstraintClass(nparams, -// arr_constraint)); -// } -// const_mat.clear(); -// -// memory->deallocate(xyzcomponent); -// memory->deallocate(arr_constraint); -// remove_redundant_rows(nparams, const_out[order], tolerance_constraint); -// -// if (has_constraint_from_symm) { -// std::cout << " done." << std::endl; -// } -// } // close loop order -// -// memory->deallocate(index_tmp); -// -// if (has_constraint_from_symm) { -// std::cout << " Finished !" << std::endl << std::endl; -// } -//} - void Constraint::get_symmetry_constraint(const int order, const std::set pairs, const std::vector symmop, const std::string basis, @@ -1019,8 +845,7 @@ void Constraint::translational_invariance() list_found.clear(); - for (std::vector::iterator p = fcs->fc_table[order].begin(); - p != fcs->fc_table[order].end(); ++p) { + for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } @@ -1191,13 +1016,13 @@ void Constraint::translational_invariance() const_omp.end()); // Merge vectors -#pragma omp critical + #pragma omp critical { for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } } - const_omp.clear(); + const_omp.clear(); }// close idata (openmp main loop) @@ -1213,29 +1038,26 @@ void Constraint::translational_invariance() std::sort(const_mat.begin(), const_mat.end()); const_mat.erase(std::unique(const_mat.begin(), const_mat.end()), const_mat.end()); - - // rref_nofraction3(const_mat); - + // timer->print_elapsed(); } // close loop i memory->deallocate(xyzcomponent); memory->deallocate(intarr); memory->deallocate(intarr_copy); + // Copy to constraint class -#ifdef _USE_EIGEN - rref_nofraction3(const_mat); -#endif const_translation[order].clear(); - for (auto it = const_mat.rbegin(); it != const_mat.rend(); ++it) { + for (std::vector>::reverse_iterator it = const_mat.rbegin(); + it != const_mat.rend(); ++it) { for (i = 0; i < (*it).size(); ++i) { arr_constraint[i] = static_cast((*it)[i]); - } + } const_translation[order].push_back(ConstraintClass(nparams, arr_constraint)); } const_mat.clear(); memory->deallocate(arr_constraint); -// std::cout << "HERE " << std::endl; + remove_redundant_rows(nparams, const_translation[order], eps8); std::cout << " done." << std::endl; @@ -1757,38 +1579,6 @@ void Constraint::remove_redundant_rows(const int n, rref(nconst, nparam, mat_tmp, nrank, tolerance); - /* - // // Transpose matrix A - - memory->allocate(arr_tmp, nconst * nparam); - - k = 0; - - for (j = 0; j < nparam; ++j) { - for (i = 0; i < nconst; ++i) { - arr_tmp[k++] = mat_tmp[i][j]; - } - } - - // Perform LU decomposition - - int nmin = std::min(nconst, nparam); - memory->allocate(ipiv, nmin); - - dgetrf_(&nconst, &nparam, arr_tmp, &nconst, ipiv, &INFO); - - k = 0; - - for (j = 0; j < nparam; ++j) { - for (i = 0; i < nconst; ++i) { - mat_tmp[i][j] = arr_tmp[k++]; - } - } - - memory->deallocate(arr_tmp); - memory->deallocate(ipiv); - */ - memory->allocate(arr_tmp, nparam); Constraint_vec.clear(); @@ -1938,7 +1728,7 @@ void Constraint::rref(int nrows, if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; if (pivot != irow) { -#pragma omp parallel for private(tmp) +//#pragma omp parallel for private(tmp) for (jcol = icol; jcol < ncols; ++jcol) { tmp = mat[pivot][jcol]; mat[pivot][jcol] = mat[irow][jcol]; @@ -1948,7 +1738,7 @@ void Constraint::rref(int nrows, tmp = mat[irow][icol]; tmp = 1.0 / tmp; -#pragma omp parallel for +//#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[irow][jcol] *= tmp; } @@ -1957,7 +1747,7 @@ void Constraint::rref(int nrows, if (jrow == irow) continue; tmp = mat[jrow][icol]; -#pragma omp parallel for +//#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[jrow][jcol] -= tmp * mat[irow][jcol]; } @@ -1980,6 +1770,9 @@ void Constraint::rref(std::vector> &mat, const double tolera icol = 0; int nrows = mat.size(); + + if (nrows == 0) return; + int ncols = mat[0].size(); for (irow = 0; irow < nrows; ++irow) { @@ -2030,6 +1823,7 @@ void Constraint::rref(std::vector> &mat, const double tolera } +/* void Constraint::rref_nofraction(std::vector> &mat) { // Return the reduced row echelon form (rref) of matrix mat. @@ -2091,125 +1885,13 @@ void Constraint::rref_nofraction(std::vector> &mat) mat.erase(mat.begin() + nrank, mat.end()); mat.shrink_to_fit(); } - - -void Constraint::rref_nofraction2(std::vector> &mat) -{ - // Return the reduced row echelon form (rref) of matrix mat. - // In addition, rank of the matrix is estimated. - - int irow, icol, jrow, jcol; - int pivot; - int tmp, tmp2; - - int nrank = 0; - - icol = 0; - - float *mat_flatten; - float **Umat; - int *ipiv; - int info; - - int nrows = mat.size(); - int ncols = mat[0].size(); - - - int k = 0; - memory->allocate(mat_flatten, nrows*ncols); - memory->allocate(ipiv, std::min(nrows,ncols)); - memory->allocate(Umat, nrows, ncols); - for (icol = 0; icol < ncols; ++icol) { - for (irow = 0; irow < nrows; ++irow) { - mat_flatten[k++] = static_cast(mat[irow][icol]); - } - } - std::cout << "Size of matrix: " << nrows << "x" << ncols << std::endl; - std::cout << "Start LU decomposition" << std::endl; - sgetrf_(&nrows, &ncols, mat_flatten, &nrows, ipiv, &info); - std::cout << "Finish LU decomposition" << std::endl; - std::cout << "INFO = " << info << std::endl; - std::cout << "Matrix U:" << std::endl; - - k = 0; - for (icol = 0; icol < ncols; ++icol) { - for (irow = 0; irow < nrows; ++irow) { - if (irow > icol) { - Umat[irow][icol] = 0.0; - } else { - Umat[irow][icol] = mat_flatten[k]; - } - ++k; - } - } - int nzeros = 0; - float max = 0.0; - for (irow = 0; irow < nrows; ++irow) { - max = 0.0; - for (icol = 0; icol < ncols; ++icol) { - std::cout << std::setw(5) << Umat[irow][icol]; - max = std::max(max, std::abs(Umat[irow][icol])); - } - std::cout << std::endl; - std::cout << "max = " << max << std::endl; - } - std::cout << std::endl; - memory->deallocate(mat_flatten); - memory->deallocate(ipiv); - memory->deallocate(Umat); - - for (irow = 0; irow < nrows; ++irow) { - - pivot = irow; - - while (mat[pivot][icol] == 0) { - ++pivot; - - if (pivot == nrows) { - pivot = irow; - ++icol; - - if (icol == ncols) break; - } - } - - if (icol == ncols) break; - - if (std::abs(mat[pivot][icol]) > 0) ++nrank; - - // swap rows - if (pivot != irow) { -#pragma omp parallel for private(tmp) - for (jcol = icol; jcol < ncols; ++jcol) { - tmp = mat[pivot][jcol]; - mat[pivot][jcol] = mat[irow][jcol]; - mat[irow][jcol] = tmp; - } - } - - tmp = mat[irow][icol]; - - for (jrow = 0; jrow < nrows; ++jrow) { - if (jrow == irow) continue; - - tmp2 = mat[jrow][icol]; -#pragma omp parallel for - for (jcol = icol; jcol < ncols; ++jcol) { - mat[jrow][jcol] = mat[jrow][jcol] * tmp - tmp2 * mat[irow][jcol]; - } - } - } - - mat.erase(mat.begin() + nrank, mat.end()); - mat.shrink_to_fit(); -} +*/ #ifdef _USE_EIGEN -void Constraint::rref_nofraction3(std::vector> &mat) +void Constraint::get_column_space(std::vector> &mat) { - // Return the reduced row echelon form (rref) of matrix mat. - // In addition, rank of the matrix is estimated. + // Return the column space of matrix mat. using namespace Eigen; @@ -2231,22 +1913,14 @@ void Constraint::rref_nofraction3(std::vector> &mat) A(icol, irow) = static_cast(mat[irow][icol]); } } -// std::cout << "Start LU decomposition" << std::endl; FullPivLU lu_decomp(A); -// std::cout << "Finish LU decomposition" << std::endl; nrank = lu_decomp.rank(); MatrixXf B = lu_decomp.image(A).transpose(); - - // std::cout << "rank = " << lu_decomp.rank() << std::endl; - // std::cout << "image of matrix A:" << std::endl; - // std::cout << lu_decomp.image(A) << std::endl; for (irow = 0; irow < nrank; ++irow) { for (icol = 0; icol < ncols; ++icol) { -// std::cout << std::setw(3) << B(irow, icol); mat[irow][icol] = static_cast(B(irow, icol) + 0.5); } -// std::cout << std::endl; } mat.erase(mat.begin() + nrank, mat.end()); diff --git a/alm/constraint.h b/alm/constraint.h index 504c980f..910bd3be 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -164,9 +164,8 @@ namespace ALM_NS void rref(int, int, double **, int &, double tolerance = eps12); void rref(std::vector> &, const double tolerance = eps12); void rref_nofraction(std::vector> &); - void rref_nofraction2(std::vector> &); #ifdef _USE_EIGEN - void rref_nofraction3(std::vector> &); + void get_column_space(std::vector> &); #endif void generate_symmetry_constraint_in_cartesian(std::vector *); From 014813adb1fcff21bc5bcff009720c116d545552 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Wed, 27 Dec 2017 16:13:46 +0900 Subject: [PATCH 22/33] changed set to unordered_set --- alm/constraint.cpp | 40 +++++++++++++++++++--------------------- alm/fcs.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index a62b0844..61c52d58 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -21,6 +21,7 @@ #include "error.h" #include #include "mathfunctions.h" +#include #ifdef _USE_EIGEN #include @@ -609,7 +610,7 @@ void Constraint::get_symmetry_constraint(const int order, const std::set list_found; + std::unordered_set list_found; std::vector> const_mat; int **map_sym; double ***rotation; @@ -698,7 +699,7 @@ void Constraint::get_symmetry_constraint(const int order, const std::set::iterator iter_found; + std::unordered_set::iterator iter_found; std::vector const_now_omp; std::vector> const_omp; @@ -816,8 +817,8 @@ void Constraint::translational_invariance() double *arr_constraint; std::vector intlist, data; - std::set list_found; - std::set::iterator iter_found; + std::unordered_set list_found; + std::unordered_set::iterator iter_found; std::vector> data_vec; std::vector list_vec; std::vector::iterator iter_vec; @@ -1016,13 +1017,13 @@ void Constraint::translational_invariance() const_omp.end()); // Merge vectors - #pragma omp critical +#pragma omp critical { for (auto it = const_omp.begin(); it != const_omp.end(); ++it) { const_mat.push_back(*it); } } - const_omp.clear(); + const_omp.clear(); }// close idata (openmp main loop) @@ -1047,11 +1048,10 @@ void Constraint::translational_invariance() // Copy to constraint class const_translation[order].clear(); - for (std::vector>::reverse_iterator it = const_mat.rbegin(); - it != const_mat.rend(); ++it) { + for (auto it = const_mat.rbegin(); it != const_mat.rend(); ++it) { for (i = 0; i < (*it).size(); ++i) { arr_constraint[i] = static_cast((*it)[i]); - } + } const_translation[order].push_back(ConstraintClass(nparams, arr_constraint)); } @@ -1104,9 +1104,9 @@ void Constraint::rotational_invariance() std::vector interaction_list, interaction_list_old, interaction_list_now; - std::set list_found; - std::set list_found_last; - std::set::iterator iter_found; + std::unordered_set list_found; + std::unordered_set list_found_last; + std::unordered_set::iterator iter_found; CombinationWithRepetition g; @@ -1142,7 +1142,7 @@ void Constraint::rotational_invariance() memory->allocate(interaction_tmp, order + 2); if (order > 0) { - list_found_last = list_found; + list_found_last = list_found; nxyz = static_cast(pow(static_cast(3), order)); memory->allocate(xyzcomponent, nxyz, order); fcs->get_xyzcomponent(order, xyzcomponent); @@ -1150,8 +1150,7 @@ void Constraint::rotational_invariance() list_found.clear(); - for (std::vector::iterator p = fcs->fc_table[order].begin(); - p != fcs->fc_table[order].end(); ++p) { + for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } @@ -1225,8 +1224,7 @@ void Constraint::rotational_invariance() if (iter_found != list_found.end()) { - arr_constraint[(*iter_found).mother] - += (*iter_found).sign * vec_for_rot[nu]; + arr_constraint[(*iter_found).mother] += (*iter_found).sign * vec_for_rot[nu]; } // Exchange mu <--> nu and repeat again. @@ -1728,7 +1726,7 @@ void Constraint::rref(int nrows, if (std::abs(mat[pivot][icol]) > tolerance) ++nrank; if (pivot != irow) { -//#pragma omp parallel for private(tmp) + //#pragma omp parallel for private(tmp) for (jcol = icol; jcol < ncols; ++jcol) { tmp = mat[pivot][jcol]; mat[pivot][jcol] = mat[irow][jcol]; @@ -1738,7 +1736,7 @@ void Constraint::rref(int nrows, tmp = mat[irow][icol]; tmp = 1.0 / tmp; -//#pragma omp parallel for + //#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[irow][jcol] *= tmp; } @@ -1747,7 +1745,7 @@ void Constraint::rref(int nrows, if (jrow == irow) continue; tmp = mat[jrow][icol]; -//#pragma omp parallel for + //#pragma omp parallel for for (jcol = icol; jcol < ncols; ++jcol) { mat[jrow][jcol] -= tmp * mat[irow][jcol]; } @@ -1891,7 +1889,7 @@ void Constraint::rref_nofraction(std::vector> &mat) #ifdef _USE_EIGEN void Constraint::get_column_space(std::vector> &mat) { - // Return the column space of matrix mat. +// Return the column space of matrix mat. using namespace Eigen; diff --git a/alm/fcs.h b/alm/fcs.h index 741f6856..967fd696 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -51,6 +51,17 @@ namespace ALM_NS return std::lexicographical_compare(elems.begin(), elems.end(), a.elems.begin(), a.elems.end()); } + + bool operator==(const FcProperty &a) const + { + int n = elems.size(); + int n_ = a.elems.size(); + if (n != n_) return false; + for (int i = 0; i < n; ++i) { + if (elems[i] != a.elems[i]) return false; + } + return true; + } }; class ForceConstantTable @@ -98,3 +109,21 @@ namespace ALM_NS bool is_ascending(const int, const int *); }; } + + +namespace std +{ + template <> + struct hash + { + std::size_t operator () (ALM_NS::FcProperty const &obj) const + { + hash hasher; + size_t seed = 0; + for (auto i : obj.elems) { + seed ^= hasher(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + return seed; + } + }; +} From 2dcd5f32975a74c1d1b15c7f4151cd564ee3e920 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Wed, 27 Dec 2017 16:54:16 +0900 Subject: [PATCH 23/33] Added comment in fcs.h --- alm/fcs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/alm/fcs.h b/alm/fcs.h index 967fd696..b74cc114 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -110,7 +110,8 @@ namespace ALM_NS }; } - +// Define a hash function for FcProperty class +// Use boost::hash_combine namespace std { template <> From dcdfeee23b211e59ac3fe8e56cb5249ad0e6004c Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Fri, 29 Dec 2017 17:35:27 +0900 Subject: [PATCH 24/33] extract.py spports python3 --- tools/extract.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/extract.py b/tools/extract.py index a2009262..2adcefa8 100755 --- a/tools/extract.py +++ b/tools/extract.py @@ -124,7 +124,7 @@ def print_displacements_VASP(xml_files, for search_target in xml_files: x = get_coordinate_VASP(search_target, nat) - ndata = len(x) / (3 * nat) + ndata = len(x) // (3 * nat) x = np.reshape(x, (ndata, nat, 3)) for idata in range(ndata): @@ -179,7 +179,7 @@ def print_atomicforces_VASP(xml_files, for search_target in xml_files: data = get_atomicforces_VASP(search_target) - ndata = len(data) / (3 * nat) + ndata = len(data) // (3 * nat) data = np.reshape(data, (ndata, nat, 3)) for idata in range(ndata): @@ -938,6 +938,7 @@ def refold(x): elif len(conditions) - conditions.count(True) > 1: print("Error : --VASP, --QE, --xTAPP, and --LAMMPS cannot be given simultaneously.") +cannot be given simultaneously.") exit(1) elif options.VASP: From c504950630885adb0238b4eccefb7a97486a3fe2 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Thu, 4 Jan 2018 13:59:02 +0900 Subject: [PATCH 25/33] Fix files where merge was unsuccessful --- alm/input.cpp | 2 ++ tools/extract.py | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/alm/input.cpp b/alm/input.cpp index 00176671..3b4853b2 100644 --- a/alm/input.cpp +++ b/alm/input.cpp @@ -457,6 +457,8 @@ void Input::parse_cell_parameter() system->lavec[i][j] = a * lavec_tmp[i][j]; } } + line_vec.clear(); + line_split.clear(); } void Input::parse_interaction_vars() diff --git a/tools/extract.py b/tools/extract.py index 2adcefa8..1ea29bb3 100755 --- a/tools/extract.py +++ b/tools/extract.py @@ -938,7 +938,6 @@ def refold(x): elif len(conditions) - conditions.count(True) > 1: print("Error : --VASP, --QE, --xTAPP, and --LAMMPS cannot be given simultaneously.") -cannot be given simultaneously.") exit(1) elif options.VASP: From e162e74918040a1153bf05ec5f55085c6cd34865 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Mon, 8 Jan 2018 02:09:12 +0900 Subject: [PATCH 26/33] Fix a segfalut error for a huge matrix --- alm/fitting.cpp | 28 +++++++++++++--------------- alm/memory.h | 10 ++++++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/alm/fitting.cpp b/alm/fitting.cpp index bb1149c0..272d772e 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -132,10 +132,10 @@ void Fitting::fitmain() << N_new << std::endl << std::endl; // memory->allocate(amat, M, N_new); - memory->allocate(amat_1D, N_new * M); + unsigned long NM = static_cast(N_new) * static_cast(M); + memory->allocate(amat_1D, NM); memory->allocate(fsum, M); memory->allocate(fsum_orig, M); - calc_matrix_elements_algebraic_constraint(M, N, N_new, nat, natmin, ndata_used, nmulti, maxorder, u, f, amat_1D, fsum, fsum_orig); @@ -1068,6 +1068,7 @@ void Fitting::calc_matrix_elements(const int M, ++iparam; } } + } memory->deallocate(ind); @@ -1092,16 +1093,15 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, double *bvec, double *bvec_orig) { - int i, j; - int irow; - int ncycle; + long i, j; + long irow; + long ncycle; std::cout << " Calculation of matrix elements for direct fitting started ... "; - + ncycle = ndata_fit * nmulti; - int natmin3 = 3 * natmin; - - + long natmin3 = 3 * static_cast(natmin); + #ifdef _OPENMP #pragma omp parallel for private(j) #endif @@ -1118,10 +1118,10 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, #endif { int *ind; - int mm, order, iat, k; - int im, idata, iparam; - int ishift; - int iold, inew; + long mm, order, iat, k; + long im, idata, iparam; + long ishift; + long iold, inew; double amat_tmp; double **amat_orig; double **amat_mod; @@ -1230,7 +1230,6 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, amat[natmin3 * ncycle * j + i + idata] = amat_mod[i][j]; } } - } memory->deallocate(ind); @@ -1238,7 +1237,6 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, memory->deallocate(amat_mod); } - std::cout << "done!" << std::endl << std::endl; } diff --git a/alm/memory.h b/alm/memory.h index bf0bca7e..307ed217 100644 --- a/alm/memory.h +++ b/alm/memory.h @@ -25,8 +25,8 @@ namespace ALM_NS // allocator - template - T* allocate(T *&arr, const unsigned int n1) + template + T* allocate(T *&arr, const A n1) { try { arr = new T [n1]; @@ -144,9 +144,11 @@ namespace ALM_NS // memsize calculator - unsigned long memsize_in_MB(const int size_of_one, const unsigned int n1) + + template + unsigned long memsize_in_MB(const int size_of_one, const A n1) { - unsigned long n = n1 * size_of_one; + unsigned long n = static_cast(n1) * size_of_one; return n / 1000000; } From 352f69eba215f90acf35cbb462e65f69361c0474 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Sun, 28 Jan 2018 20:48:00 +0900 Subject: [PATCH 27/33] Fix a bug in the symmetrization of Born effective charge This is an important bug fix. --- anphon/dynamical.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anphon/dynamical.cpp b/anphon/dynamical.cpp index a6eb626a..cf7ee820 100644 --- a/anphon/dynamical.cpp +++ b/anphon/dynamical.cpp @@ -935,7 +935,7 @@ void Dynamical::load_born() for (j = 0; j < 3; ++j) { for (k = 0; k < 3; ++k) { for (m = 0; m < 3; ++m) { - born_sym[iat][i][j] += rot[i][k] * rot[j][m] * borncharge[iat_sym][k][m]; + born_sym[iat_sym][i][j] += rot[i][k] * rot[j][m] * borncharge[iat][k][m]; } } } @@ -957,7 +957,7 @@ void Dynamical::load_born() for (iat = 0; iat < system->natmin; ++iat) { for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { - diff_sym = std::max(res, std::abs(borncharge[iat][i][j] - born_sym[iat][i][j])); + diff_sym = std::max(diff_sym, std::abs(borncharge[iat][i][j] - born_sym[iat][i][j])); } } } From 8f9e82bcd51693c073773a491e2a7eaca9e161e0 Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Sun, 28 Jan 2018 21:08:56 +0900 Subject: [PATCH 28/33] New tag BORNSYM to swith on/off the symmetrization of Born effective charges --- anphon/dynamical.cpp | 10 +++++++--- anphon/dynamical.h | 3 ++- anphon/parsephon.cpp | 8 ++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/anphon/dynamical.cpp b/anphon/dynamical.cpp index cf7ee820..6f79ab46 100644 --- a/anphon/dynamical.cpp +++ b/anphon/dynamical.cpp @@ -36,6 +36,7 @@ using namespace PHON_NS; Dynamical::Dynamical(PHON *phon): Pointers(phon) { index_bconnect = nullptr; + symmetrize_borncharge = 0; } Dynamical::~Dynamical() @@ -121,7 +122,7 @@ void Dynamical::setup_dynamical(std::string mode) if (nonanalytic) { memory->allocate(borncharge, system->natmin, 3, 3); - if (mympi->my_rank == 0) load_born(); + if (mympi->my_rank == 0) load_born(symmetrize_borncharge); MPI_Bcast(&dielec[0][0], 9, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Bcast(&borncharge[0][0][0], 9 * system->natmin, MPI_DOUBLE, 0, MPI_COMM_WORLD); @@ -817,7 +818,7 @@ void Dynamical::modify_eigenvectors() } -void Dynamical::load_born() +void Dynamical::load_born(const unsigned int flag_symmborn) { // Read the dielectric tensor and born effective charges from file_born @@ -892,7 +893,7 @@ void Dynamical::load_born() if (res > eps10) { std::cout << std::endl; std::cout << " WARNING: Born effective charges do not satisfy the acoustic sum rule." << std::endl; - std::cout << " The born effective charges are modified to follow the ASR." << std::endl; + std::cout << " The born effective charges are modified to satisfy the ASR." << std::endl; for (i = 0; i < system->natmin; ++i) { for (j = 0; j < 3; ++j) { @@ -903,6 +904,8 @@ void Dynamical::load_born() } } + if (flag_symmborn) { + // Symmetrize Born effective charges. Necessary to avoid the violation of ASR // particularly for NONANALYTIC=3 (Ewald summation). @@ -991,6 +994,7 @@ void Dynamical::load_born() } } } + } std::cout << std::scientific; } diff --git a/anphon/dynamical.h b/anphon/dynamical.h index 6a5f455a..9d84b345 100644 --- a/anphon/dynamical.h +++ b/anphon/dynamical.h @@ -51,6 +51,7 @@ namespace PHON_NS unsigned int neval; bool eigenvectors; bool print_eigenvectors; + unsigned int symmetrize_borncharge; unsigned int nonanalytic; bool participation_ratio; unsigned int band_connection; @@ -98,7 +99,7 @@ namespace PHON_NS private: - void load_born(); + void load_born(const unsigned int); void prepare_mindist_list(std::vector **); void calc_atomic_participation_ratio(std::complex *, double *); diff --git a/anphon/parsephon.cpp b/anphon/parsephon.cpp index 992e2bb1..59bbcfa3 100644 --- a/anphon/parsephon.cpp +++ b/anphon/parsephon.cpp @@ -120,6 +120,7 @@ void Input::parse_general_vars() bool selenergy_offdiagonal; bool update_fc2; bool classical; + unsigned int bornsym; unsigned int band_connection; struct stat st; @@ -129,7 +130,7 @@ void Input::parse_general_vars() std::string str_tmp; std::string str_allowed_list = "PREFIX MODE NSYM TOLERANCE PRINTSYM FCSXML FC2XML TMIN TMAX DT \ NBANDS NONANALYTIC BORNINFO NA_SIGMA ISMEAR EPSILON EMIN EMAX DELTA_E \ - RESTART TREVSYM NKD KD MASS TRISYM PREC_EWALD CLASSICAL BCONNECT"; + RESTART TREVSYM NKD KD MASS TRISYM PREC_EWALD CLASSICAL BCONNECT BORNSYM"; std::string str_no_defaults = "PREFIX MODE FCSXML NKD KD MASS"; std::vector no_defaults; std::vector kdname_v, masskd_v; @@ -209,6 +210,7 @@ void Input::parse_general_vars() use_triplet_symmetry = true; classical = false; band_connection = 0; + bornsym = 0; prec_ewald = 1.0e-12; @@ -257,8 +259,9 @@ void Input::parse_general_vars() assign_val(classical, "CLASSICAL", general_var_dict); assign_val(band_connection, "BCONNECT", general_var_dict); assign_val(use_triplet_symmetry, "TRISYM", general_var_dict); + assign_val(bornsym, "BORNSYM", general_var_dict); - if (band_connection < 0 || band_connection > 2) { + if (band_connection > 2) { error->exit("parse_general_vars", "BCONNECT-tag can take 0, 1, or 2."); } @@ -318,6 +321,7 @@ void Input::parse_general_vars() dynamical->nonanalytic = nonanalytic; dynamical->na_sigma = na_sigma; + dynamical->symmetrize_borncharge = bornsym; writes->nbands = nbands; dynamical->file_born = borninfo; dynamical->band_connection = band_connection; From b07d8d33210dba14c6861c8f324243e0ae19762e Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Sun, 28 Jan 2018 21:28:39 +0900 Subject: [PATCH 29/33] Fix a typo in the formalism of alm regarding the point group symmetry. Don't worry. A correct formula has been used inside the code. --- docs/source/formalism/formalism_alm.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/formalism/formalism_alm.rst b/docs/source/formalism/formalism_alm.rst index d936d6d9..aec8c3a9 100644 --- a/docs/source/formalism/formalism_alm.rst +++ b/docs/source/formalism/formalism_alm.rst @@ -45,14 +45,14 @@ The are several relationships between IFCs which may be used to reduce the numbe .. math:: :label: ifcsym1 - \sum_{\nu_{1},\dots,\nu_{n}}\Phi_{\nu_{1}\dots\nu_{n}}(L_{1}K_{1};\dots;L_{n}K_{n}) O_{\mu_{1}\nu_{1}}\cdots O_{\mu_{n}\nu_{n}} = \Phi_{\mu_{1}\dots\mu_{n}}(\ell_{1}\kappa_{1};\dots;\ell_{n}\kappa_{n}), + \sum_{\nu_{1},\dots,\nu_{n}}\Phi_{\nu_{1}\dots\nu_{n}}(L_{1}K_{1};\dots;L_{n}K_{n}) O_{\nu_{1}\mu_{1}}\cdots O_{\nu_{n}\mu_{n}} = \Phi_{\mu_{1}\dots\mu_{n}}(\ell_{1}\kappa_{1};\dots;\ell_{n}\kappa_{n}), where :math:`O` is the rotational matrix of the symmetry operation. Let :math:`N_{s}` be the number of symmetry operations, there are :math:`N_{s}` relationships between IFCs which may be used to find independent IFCs. .. Note:: - In the current implementation of *alm*, independent IFCs are searched in Cartesian coordinate where the matrix element :math:`O_{\mu\nu}` is 0 or :math:`\pm1` in all symmetry operations except for those of **hexagonal** (trigonal) lattice. Also, except for hexagonal (trigonal) systems, the product :math:`O_{\mu_{1}\nu_{1}}\cdots O_{\mu_{n}\nu_{n}}` in the left hand side of equation :eq:`ifcsym1` becomes non-zero only for a specific pair of :math:`\{\nu\}` (and becomes 0 for all other :math:`\{\nu\}`\ s). Therefore, let :math:`\{\nu^{\prime}\}` be such a pair of :math:`\{\nu\}`, the equation :eq:`ifcsym1` can be reduced to + In the current implementation of *alm*, independent IFCs are searched in Cartesian coordinate where the matrix element :math:`O_{\mu\nu}` is 0 or :math:`\pm1` in all symmetry operations except for those of **hexagonal** (trigonal) lattice. Also, except for hexagonal (trigonal) systems, the product :math:`O_{\nu_{1}\mu_{1}}\cdots O_{\nu_{n}\mu_{n}}` in the left hand side of equation :eq:`ifcsym1` becomes non-zero only for a specific pair of :math:`\{\nu\}` (and becomes 0 for all other :math:`\{\nu\}`\ s). Therefore, let :math:`\{\nu^{\prime}\}` be such a pair of :math:`\{\nu\}`, the equation :eq:`ifcsym1` can be reduced to .. math:: :label: ifcsym2 From 12e9e22096ee4b04e60e6b3f5e14b5ac9512c9f2 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Mon, 29 Jan 2018 13:35:58 +0900 Subject: [PATCH 30/33] Cleanup codes --- alm/constraint.cpp | 2 +- alm/constraint.h | 3 +- alm/fcs.h | 4 +- alm/fitting.cpp | 5 +- alm/memory.h | 2 +- anphon/dynamical.cpp | 116 +++++++++++++++++++++---------------------- 6 files changed, 65 insertions(+), 67 deletions(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 61c52d58..6a6c5617 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -1142,7 +1142,7 @@ void Constraint::rotational_invariance() memory->allocate(interaction_tmp, order + 2); if (order > 0) { - list_found_last = list_found; + list_found_last = list_found; nxyz = static_cast(pow(static_cast(3), order)); memory->allocate(xyzcomponent, nxyz, order); fcs->get_xyzcomponent(order, xyzcomponent); diff --git a/alm/constraint.h b/alm/constraint.h index 910bd3be..ba5c3b27 100644 --- a/alm/constraint.h +++ b/alm/constraint.h @@ -159,7 +159,7 @@ namespace ALM_NS void remove_redundant_rows(const int, std::vector &, const double tolerance = eps12); - // void remove_redundant_rows_integer(const int, std::vector> &); + // void remove_redundant_rows_integer(const int, std::vector> &); void rref(int, int, double **, int &, double tolerance = eps12); void rref(std::vector> &, const double tolerance = eps12); @@ -175,6 +175,5 @@ namespace ALM_NS { void dgetrf_(int *m, int *n, double *a, int *lda, int *ipiv, int *info); void sgetrf_(int *m, int *n, float *a, int *lda, int *ipiv, int *info); - } } diff --git a/alm/fcs.h b/alm/fcs.h index b74cc114..2eb69870 100644 --- a/alm/fcs.h +++ b/alm/fcs.h @@ -52,7 +52,7 @@ namespace ALM_NS a.elems.begin(), a.elems.end()); } - bool operator==(const FcProperty &a) const + bool operator==(const FcProperty &a) const { int n = elems.size(); int n_ = a.elems.size(); @@ -117,7 +117,7 @@ namespace std template <> struct hash { - std::size_t operator () (ALM_NS::FcProperty const &obj) const + std::size_t operator ()(ALM_NS::FcProperty const &obj) const { hash hasher; size_t seed = 0; diff --git a/alm/fitting.cpp b/alm/fitting.cpp index 272d772e..28fae7fa 100644 --- a/alm/fitting.cpp +++ b/alm/fitting.cpp @@ -1098,10 +1098,10 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, long ncycle; std::cout << " Calculation of matrix elements for direct fitting started ... "; - + ncycle = ndata_fit * nmulti; long natmin3 = 3 * static_cast(natmin); - + #ifdef _OPENMP #pragma omp parallel for private(j) #endif @@ -1236,7 +1236,6 @@ void Fitting::calc_matrix_elements_algebraic_constraint(const int M, memory->deallocate(amat_orig); memory->deallocate(amat_mod); } - } diff --git a/alm/memory.h b/alm/memory.h index 307ed217..b03fd92e 100644 --- a/alm/memory.h +++ b/alm/memory.h @@ -144,7 +144,7 @@ namespace ALM_NS // memsize calculator - + template unsigned long memsize_in_MB(const int size_of_one, const A n1) { diff --git a/anphon/dynamical.cpp b/anphon/dynamical.cpp index 6f79ab46..4699634f 100644 --- a/anphon/dynamical.cpp +++ b/anphon/dynamical.cpp @@ -906,95 +906,95 @@ void Dynamical::load_born(const unsigned int flag_symmborn) if (flag_symmborn) { - // Symmetrize Born effective charges. Necessary to avoid the violation of ASR - // particularly for NONANALYTIC=3 (Ewald summation). + // Symmetrize Born effective charges. Necessary to avoid the violation of ASR + // particularly for NONANALYTIC=3 (Ewald summation). - int isym, iat, iat_sym; - int m; - double ***born_sym; - double rot[3][3]; + int isym, iat, iat_sym; + int m; + double ***born_sym; + double rot[3][3]; - memory->allocate(born_sym, system->natmin, 3, 3); + memory->allocate(born_sym, system->natmin, 3, 3); - for (iat = 0; iat < system->natmin; ++iat) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - born_sym[iat][i][j] = 0.0; + for (iat = 0; iat < system->natmin; ++iat) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + born_sym[iat][i][j] = 0.0; + } } } - } - for (isym = 0; isym < symmetry->SymmListWithMap.size(); ++isym) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - rot[i][j] = symmetry->SymmListWithMap[isym].rot[3 * i + j]; + for (isym = 0; isym < symmetry->SymmListWithMap.size(); ++isym) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + rot[i][j] = symmetry->SymmListWithMap[isym].rot[3 * i + j]; + } } - } - for (iat = 0; iat < system->natmin; ++iat) { - iat_sym = symmetry->SymmListWithMap[isym].mapping[iat]; + for (iat = 0; iat < system->natmin; ++iat) { + iat_sym = symmetry->SymmListWithMap[isym].mapping[iat]; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - for (k = 0; k < 3; ++k) { - for (m = 0; m < 3; ++m) { - born_sym[iat_sym][i][j] += rot[i][k] * rot[j][m] * borncharge[iat][k][m]; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + for (m = 0; m < 3; ++m) { + born_sym[iat_sym][i][j] += rot[i][k] * rot[j][m] * borncharge[iat][k][m]; + } } } } } } - } - for (iat = 0; iat < system->natmin; ++iat) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - born_sym[iat][i][j] /= static_cast(symmetry->SymmListWithMap.size()); + for (iat = 0; iat < system->natmin; ++iat) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + born_sym[iat][i][j] /= static_cast(symmetry->SymmListWithMap.size()); + } } } - } - // Check if the Born effective charges given by the users satisfy the symmetry. + // Check if the Born effective charges given by the users satisfy the symmetry. - double diff_sym = 0.0; - for (iat = 0; iat < system->natmin; ++iat) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - diff_sym = std::max(diff_sym, std::abs(borncharge[iat][i][j] - born_sym[iat][i][j])); + double diff_sym = 0.0; + for (iat = 0; iat < system->natmin; ++iat) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + diff_sym = std::max(diff_sym, std::abs(borncharge[iat][i][j] - born_sym[iat][i][j])); + } } } - } - if (diff_sym > 0.5) { - std::cout << std::endl; - std::cout << " WARNING: Born effective charges are inconsistent with the crystal symmetry." << std::endl; - } + if (diff_sym > 0.5) { + std::cout << std::endl; + std::cout << " WARNING: Born effective charges are inconsistent with the crystal symmetry." << std::endl; + } - for (iat = 0; iat < system->natmin; ++iat) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - borncharge[iat][i][j] = born_sym[iat][i][j]; + for (iat = 0; iat < system->natmin; ++iat) { + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + borncharge[iat][i][j] = born_sym[iat][i][j]; + } } } - } - memory->deallocate(born_sym); + memory->deallocate(born_sym); - if (diff_sym > eps8 || res > eps10) { - std::cout << std::endl; - std::cout << " Symmetrized Born effective charge tensor in Cartesian coordinate." << std::endl; - for (i = 0; i < system->natmin; ++i) { - std::cout << " Atom" << std::setw(5) << i + 1 << "(" - << std::setw(3) << system->symbol_kd[system->kd[system->map_p2s[i][0]]] << ") :" << std::endl; + if (diff_sym > eps8 || res > eps10) { + std::cout << std::endl; + std::cout << " Symmetrized Born effective charge tensor in Cartesian coordinate." << std::endl; + for (i = 0; i < system->natmin; ++i) { + std::cout << " Atom" << std::setw(5) << i + 1 << "(" + << std::setw(3) << system->symbol_kd[system->kd[system->map_p2s[i][0]]] << ") :" << std::endl; - for (j = 0; j < 3; ++j) { - for (k = 0; k < 3; ++k) { - std::cout << std::setw(15) << borncharge[i][j][k]; + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + std::cout << std::setw(15) << borncharge[i][j][k]; + } + std::cout << std::endl; } - std::cout << std::endl; } } } - } std::cout << std::scientific; } From 3984adb786cb32eb3d066042d0b4d1fa146ac9a2 Mon Sep 17 00:00:00 2001 From: Terumasa TADANO Date: Mon, 29 Jan 2018 13:38:24 +0900 Subject: [PATCH 31/33] Use cend and cbegin --- alm/constraint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alm/constraint.cpp b/alm/constraint.cpp index 61c52d58..1d7ed2b7 100644 --- a/alm/constraint.cpp +++ b/alm/constraint.cpp @@ -846,7 +846,7 @@ void Constraint::translational_invariance() list_found.clear(); - for (auto p = fcs->fc_table[order].begin(); p != fcs->fc_table[order].end(); ++p) { + for (auto p = fcs->fc_table[order].cbegin(); p != fcs->fc_table[order].cend(); ++p) { for (i = 0; i < order + 2; ++i) { ind[i] = (*p).elems[i]; } From 226b236729b4d59e7e3bc107901434ad5f424ebc Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Mon, 29 Jan 2018 22:08:54 +0900 Subject: [PATCH 32/33] Add description of new tags BCONNECT & BORNSYM --- docs/source/input/inputanphon.rst | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/source/input/inputanphon.rst b/docs/source/input/inputanphon.rst index f5488398..ebd938cf 100644 --- a/docs/source/input/inputanphon.rst +++ b/docs/source/input/inputanphon.rst @@ -114,7 +114,6 @@ List of input variables === ======================================================= 0 Symmetry operations won’t be saved in “SYMM_INFO_PRIM” - 1 Symmetry operations will be saved in “SYMM_INFO_PRIM” === ======================================================= @@ -157,6 +156,18 @@ List of input variables ```` +* BORNSYM-tag = 0 | 1 + + === ================================================================= + 0 Do not symmetrize Born effective charges + 1 Symmetrize Born effective charges by using point group symmetry + === ================================================================= + + :Default: 0 + :Type: Integer + +```` + * TMIN, TMAX, DT-tags : Temperature range and its stride in units of Kelvin :Default: ``TMIN = 0``, ``TMAX = 1000``, ``DT = 10`` @@ -193,6 +204,25 @@ List of input variables ```` +* BCONNECT-tag = 0 | 1 | 2 + + === =================================================================================== + 0 | Phonon band is saved without change (sorted in order of energy) + + 1 | Phonon band is connected by using the similarity of eigenvectors. + + 2 | Same as ``BCONNECT=1``. In addition, information of the connectivity is + | saved as ``PREFIX.connection``. + === =================================================================================== + + :Default: 0 + :Type: Integer + :Description: The algorithm for connecting a band structure is described here_. + + .. _here : https://www.slideshare.net/TakeshiNishimatsu/two-efficient-algorithms-for-drawing-accurate-and-beautiful-phonon-dispersion + +```` + * CLASSICAL-tag = 0 | 1 === ======================================================= From 7b63113f1b88a9b71152a1dd775a198d739eeacc Mon Sep 17 00:00:00 2001 From: Terumasa Tadano Date: Mon, 29 Jan 2018 22:27:11 +0900 Subject: [PATCH 33/33] change version as 1.0.2 --- docs/source/conf.py | 2 +- include/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index e4076b56..67eb28ed 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -62,7 +62,7 @@ # The short X.Y version. version = '1.0' # The full version, including alpha/beta/rc tags. -release = '1.0.0' +release = '1.0.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/include/version.h b/include/version.h index cae9d288..866d08e6 100644 --- a/include/version.h +++ b/include/version.h @@ -12,4 +12,4 @@ #include -static const std::string ALAMODE_VERSION = "1.0.0"; +static const std::string ALAMODE_VERSION = "1.0.2";