8#ifndef _AFLOW_PFLOW_CPP_
9#define _AFLOW_PFLOW_CPP_
34#include "flow/aflow_ivasp.h"
35#include "flow/aflow_pflow.h"
36#include "structure/aflow_xatom.h"
37#include "structure/aflow_xstructure.h"
46using std::stringstream;
73 sstr.BringInCompact();
111 xoo = sstr.lattice(1);
113 yoo = sstr.lattice(2);
115 zoo = sstr.lattice(3);
117 xyo = sstr.lattice(1) + sstr.lattice(2);
119 xzo = sstr.lattice(1) + sstr.lattice(3);
121 yzo = sstr.lattice(2) + sstr.lattice(3);
123 xyz = sstr.lattice(1) + sstr.lattice(2) + sstr.lattice(3);
133 for (
size_t iat = 0; iat < sstr.atoms.size(); iat++) {
134 for (
int i = -1; i <= 1; i++) {
135 for (
int j = -1; j <= 1; j++) {
136 for (
int k = -1; k <= 1; k++) {
137 rat = sstr.atoms.at(iat).cpos + ((double) i) * sstr.lattice(1) + ((double) j) * sstr.lattice(2) + ((double) k) * sstr.lattice(3);
138 projxoo = scalar_product(rat, xoo) / axoo / axoo;
139 projyoo = scalar_product(rat, yoo) / ayoo / ayoo;
140 projzoo = scalar_product(rat, zoo) / azoo / azoo;
141 projxyo = scalar_product(rat, xyo) / axyo / axyo;
142 projxzo = scalar_product(rat, xzo) / axzo / axzo;
143 projyzo = scalar_product(rat, yzo) / ayzo / ayzo;
144 projxyz = scalar_product(rat, xyz) / axyz / axyz;
145 if ((projxoo > -0.5 && projxoo <= 0.5) && (projyoo > -0.5 && projyoo <= 0.5) && (projzoo > -0.5 && projzoo <= 0.5) && (projxyo > -0.5 && projxyo <= 0.5) && (projxzo > -0.5 && projxzo <= 0.5) &&
146 (projyzo > -0.5 && projyzo <= 0.5) && (projxyz > -0.5 && projxyz <= 0.5)) {
147 sstr.atoms.at(iat).cpos(1) = rat(1);
148 sstr.atoms.at(iat).cpos(2) = rat(2);
149 sstr.atoms.at(iat).cpos(3) = rat(3);
157 sstr.atoms.at(iat).fpos =
C2F(sstr.lattice, sstr.atoms.at(iat).cpos);
169 for (
size_t iat = 0; iat < a.atoms.size(); iat++) {
170 mom1 = mom1 + a.atoms[iat].cpos;
172 if (!a.atoms.empty()) {
173 mom1 = ((double) a.scale / ((double) a.atoms.size())) * mom1;
191 dmom1 = mom1_new - mom1_old;
193 for (
size_t iat = 0; iat < sstr.atoms.size(); iat++) {
194 sstr.atoms[iat].cpos = sstr.scale * sstr.atoms[iat].cpos;
195 sstr.atoms[iat].cpos = sstr.atoms[iat].cpos + dmom1;
196 sstr.atoms[iat].cpos = sstr.atoms[iat].cpos / sstr.scale;
197 sstr.atoms[iat].fpos =
C2F(sstr.lattice, sstr.atoms[iat].cpos);
208 diff = atom.cpos - atom.corigin;
229 _atom out_at = in_at;
231 GetUnitCellRep(cpos, p_cell0, ijk, lattice,
true);
232 out_at.fpos =
C2F(lattice, cpos);
243 name = KBIN::VASP_PseudoPotential_CleanName(name);
249 double scatt_fact = 0.0;
250 for (
size_t iat = 0; iat < vatom_name.size(); iat++) {
251 if (name == vatom_name[iat] || name == vatom_symbol[iat]) {
252 scatt_fact = vatom_xray_scatt[iat];
301 for (
int i = 1; i <= 3; i++) {
302 rlat(1, i) = rlat1(i);
304 for (
int i = 1; i <= 3; i++) {
305 rlat(2, i) = rlat2(i);
307 for (
int i = 1; i <= 3; i++) {
308 rlat(3, i) = rlat3(i);
332 _atom
SetCpos(
const _atom& a,
const vector<double>& in_cpos) {
333 assert(in_cpos.size() == 3);
336 b.cpos(1) = in_cpos.at(0);
337 b.cpos(2) = in_cpos.at(1);
338 b.cpos(3) = in_cpos.at(2);
347 _atom
SetFpos(
const _atom& a,
const vector<double>& in_fpos) {
348 assert(in_fpos.size() == 3);
351 b.fpos(1) = in_fpos.at(0);
352 b.fpos(2) = in_fpos.at(1);
353 b.fpos(3) = in_fpos.at(2);
364 vector<double> vc(3, 0.0);
365 for (
int ic = 0; ic < 3; ic++) {
366 for (
int jc = 0; jc < 3; jc++) {
367 vc[ic] = vc[ic] + vf[jc] * lat[jc][ic];
380 vector<double> vf(3, 0.0);
390 _atom
SetName(
const _atom& a,
const string& in_name) {
402 _atom
SetType(
const _atom& a,
const int in_type) {
414 _atom
SetNum(
const _atom& a,
const int in_num) {
427 const int num_atoms = str.atoms.size();
430 for (
int i = 0; i < num_atoms; i++) {
431 for (
int j = 0; j < 3; j++) {
432 fpos[i][j] = str.atoms.at(i).fpos(j + 1);
444 const int num_atoms = str.atoms.size();
447 for (
int i = 0; i < num_atoms; i++) {
448 for (
int j = 0; j < 3; j++) {
449 cpos[i][j] = str.atoms.at(i).cpos(j + 1);
514 const int in_coord_flag) {
515 assert(in_coord_flag == 0 || in_coord_flag == 1);
519 if (in_coord_flag == 0) {
520 for (
size_t i = 0; i < in_pos.
size(); i++) {
522 for (
int j = 1; j <= 3; j++) {
523 atom.fpos(j) = in_pos[i][j - 1];
525 atom.cpos =
F2C(b.lattice, atom.fpos);
526 b.atoms.push_back(atom);
529 if (in_coord_flag == 1) {
530 for (
size_t i = 0; i < in_pos.
size(); i++) {
532 for (
int j = 1; j <= 3; j++) {
533 atom.cpos(j) = in_pos[i][j - 1];
535 atom.fpos =
C2F(b.lattice, atom.cpos);
536 b.atoms.push_back(atom);
549 const int in_coord_flag) {
550 assert(in_coord_flag == 0 || in_coord_flag == 1);
554 if (in_coord_flag == 0) {
555 for (
size_t i = 0; i < in_pos.
size(); i++) {
556 atom = a.atoms.at(i);
557 for (
int j = 1; j <= 3; j++) {
558 atom.fpos(j) = in_pos[i][j - 1];
560 atom.cpos =
F2C(b.lattice, atom.fpos);
561 b.atoms.push_back(atom);
564 if (in_coord_flag == 1) {
565 for (
size_t i = 0; i < in_pos.
size(); i++) {
566 atom = a.atoms.at(i);
567 for (
int j = 1; j <= 3; j++) {
568 atom.cpos(j) = in_pos[i][j - 1];
570 atom.fpos =
C2F(b.lattice, atom.cpos);
571 b.atoms.push_back(atom);
584 if (in.size() == a.num_each_type.size()) {
587 for (
size_t iat = 0; iat < b.num_each_type.size(); iat++) {
588 b.atoms.at(iat).name = in.at(b.atoms.at(iat).type);
589 if (!b.atoms.at(iat).name.empty()) {
590 b.atoms.at(iat).name_is_given =
true;
591 b.atoms.at(iat).CleanName();
597 if (in.size() == a.atoms.size()) {
598 for (
size_t iat = 0; iat < b.atoms.size(); iat++) {
599 b.atoms[iat].name = in[iat];
600 b.atoms[iat].name_is_given =
true;
601 b.atoms[iat].CleanName();
606 stringstream message;
607 message <<
"Must specify as many names as types/bases: in.size()=" << in.size();
608 message <<
" =a.num_each_type.size()=" << a.num_each_type.size();
609 message <<
" =a.atoms.size()=" << a.atoms.size();
620 if (in.size() == a.num_each_type.size()) {
622 for (
size_t iat = 0; iat < b.num_each_type.size(); iat++) {
623 b.atoms.at(iat).name_is_given = in.at(b.atoms.at(iat).type);
627 if (in.size() == a.atoms.size()) {
628 for (
size_t iat = 0; iat < b.atoms.size(); iat++) {
629 b.atoms[iat].name_is_given = in[iat];
633 stringstream message;
634 message <<
"Must specify as many names as types/bases: in.size()=" << in.size();
635 message <<
" =a.num_each_type.size()=" << a.num_each_type.size();
636 message <<
" =a.atoms.size()=" << a.atoms.size();
645 xstructure
SetOrigin(
const xstructure& a,
const vector<double>& in_origin) {
646 const xstructure b(a);
647 for (
uint i = 1; i <= 3; i++) {
648 b.origin[i] = in_origin.at(i - 1);
653 const xstructure b(a);
654 for (
uint i = 1; i <= 3; i++) {
655 b.origin[i] = in_origin[i];
667 bool VVequal(
const vector<double>& a,
const vector<double>& b) {
668 const double tol = 1e-15;
669 const int size = std::min((
int) a.size(), (
int) b.size());
670 for (
int i = 0; i < size; i++) {
677 bool VVequal(
const vector<int>& a,
const vector<int>& b) {
678 const double tol = 1e-15;
679 const int size = std::min((
int) a.size(), (
int) b.size());
680 for (
int i = 0; i < size; i++) {
688 bool VVequal(
const deque<double>& a,
const deque<double>& b) {
689 const double tol = 1e-15;
690 const int size = std::min((
int) a.size(), (
int) b.size());
691 for (
int i = 0; i < size; i++) {
698 bool VVequal(
const deque<int>& a,
const deque<int>& b) {
699 const double tol = 1e-15;
700 const int size = std::min((
int) a.size(), (
int) b.size());
701 for (
int i = 0; i < size; i++) {
719 vector<double>
SmoothFunc(
const vector<double>& func,
const double& sigma) {
723 const int nx = func.size();
724 const int range = (int) (5.0 * sigma);
726 vector<double>
norm(nx, 0.0);
730 for (
int ix = 0; ix < nx; ix++) {
731 for (
int i = -range; i <= range; i++) {
732 if ((ix + i) >= 0 && (ix + i) < nx) {
733 wt[ix][i + range] =
Normal((
double) (ix + i),
double(ix), sigma);
734 norm[ix] =
norm[ix] + wt[ix][i + range];
739 for (
int ix = 0; ix < nx; ix++) {
740 for (
int i = -range; i <= range; i++) {
741 wt[ix][i + range] = wt[ix][i + range] /
norm[ix];
745 vector<double> sfunc(nx, 0.0);
747 for (
int ix = 0; ix < nx; ix++) {
749 for (
int i = -range; i <= range; i++) {
750 if ((ix + i) > 0 && (ix + i) < nx) {
751 sf += wt[ix][i + range] * func[ix + i];
763double Normal(
const double& x,
const double& mu,
const double& sigma) {
764 const double tol = 1e-12;
766 if (std::abs(sigma) < tol) {
767 if (std::abs(x - mu) < tol) {
773 const double arg = -(x - mu) * (x - mu) / (2 * sigma * sigma);
774 return exp(arg) / (sqrt(
TWOPI) * sigma);
783 for (
size_t i = 0; i < mat.
size(); i++) {
784 for (
size_t j = 0; j < mat[i].
size(); j++) {
785 mat[i][j] = (double) value;
789 void VVset(vector<vector<int>>& mat,
const int& value) {
790 for (
size_t i = 0; i < mat.size(); i++) {
791 for (
size_t j = 0; j < mat[i].size(); j++) {
792 mat[i][j] = (int) value;
805 double norm(
const vector<double>& v) {
807 for (
size_t i = 0; i < v.size(); i++) {
808 sum = sum + v[i] * v[i];
824 double getcos(
const vector<double>& a,
const vector<double>& b) {
826 const uint size = std::min((
uint) a.size(), (
uint) b.size());
827 for (
uint i = 0; i < size; i++) {
828 sum = sum + a[i] * b[i];
832 assert(na > 0.0 && nb > 0.0);
833 sum = sum / (na * nb);
886 vector<double> old = abc_angles;
887 vector<double> newv = abc_angles;
889 if (old[1] > old[0]) {
897 if (old[2] > old[0]) {
905 if (old[2] > old[1]) {
922 void Vout(
const vector<double>& a, ostream& out) {
923 for (
size_t i = 0; i < a.size(); i++) {
928 void Vout(
const vector<int>& a, ostream& out) {
929 for (
size_t i = 0; i < a.size(); i++) {
934 void Vout(
const vector<string>& a, ostream& out) {
935 for (
size_t i = 0; i < a.size(); i++) {
949 for (
size_t i = 0; i < m.
size(); i++) {
950 for (
size_t j = 0; j < m[i].
size(); j++) {
951 out << m[i][j] <<
" ";
956 void Mout(
const vector<vector<double>>& m, ostream& out) {
957 for (
size_t i = 0; i < m.size(); i++) {
958 for (
size_t j = 0; j < m[i].size(); j++) {
959 out << m[i][j] <<
" ";
971 vector<double>
SVprod(
const double& s,
const vector<double>& b) {
972 const int size = b.size();
973 vector<double> prod(size);
974 for (
int i = 0; i < size; i++) {
979 vector<int>
SVprod(
const int& s,
const vector<int>& b) {
980 const int size = b.size();
981 vector<int> prod(size);
982 for (
int i = 0; i < size; i++) {
994 vector<double>
VVsum(
const vector<double>& a,
const vector<double>& b) {
995 const int size = std::min(a.size(), b.size());
996 vector<double> c(size);
997 for (
int i = 0; i < size; i++) {
1002 vector<double>
VVsum(
const vector<double>& a,
const vector<int>& b) {
1003 const int size = std::min(a.size(), b.size());
1004 vector<double> c(size);
1005 for (
int i = 0; i < size; i++) {
1017 vector<double>
VVdiff(
const vector<double>& a,
const vector<double>& b) {
1018 const int size = std::min(a.size(), b.size());
1019 vector<double> c(size);
1020 for (
int i = 0; i < size; i++) {
1033 double VVprod(
const vector<double>& a,
const vector<double>& b) {
1034 const int size = std::min(a.size(), b.size());
1036 for (
int i = 0; i < size; i++) {
1037 c = c + a[i] * b[i];
1041 double VVprod(
const vector<double>& a,
const vector<int>& b) {
1042 const int size = std::min(a.size(), b.size());
1044 for (
int i = 0; i < size; i++) {
1045 c = c + a[i] * b[i];
1061 const vector<double> v(M, 0.0);
1063 for (
uint i = 0; i < M; i++) {
1064 for (
uint j = 0; j < M; j++) {
1066 for (
uint k = 0; k < N; k++) {
1067 sum = sum + a[i][k] * b[k][j];
1086 vector<double> u(M, 0.0);
1087 for (
uint i = 0; i < M; i++) {
1089 for (
uint j = 0; j < N; j++) {
1090 sum = sum + A[i][j] * v[j];
1108 vector<double> u(M, 0.0);
1109 for (
uint i = 0; i < N; i++) {
1111 for (
uint j = 0; j < M; j++) {
1112 sum = sum + v[j] * A[j][i];
1121 vector<double> u(M, 0.0);
1122 for (
uint i = 0; i < N; i++) {
1124 for (
uint j = 0; j < M; j++) {
1125 sum = sum + v[j] * A[j][i];
1139 vector<double>
VVcross(
const vector<double>& a,
const vector<double>& b) {
1140 if (a.size() != 3 || b.size() != 3) {
1143 vector<double> u(3);
1144 u[0] = a[1] * b[2] - a[2] * b[1];
1145 u[1] = -(a[0] * b[2] - a[2] * b[0]);
1146 u[2] = a[0] * b[1] - a[1] * b[0];
1157 double VVdot(
const vector<double>& a,
const vector<double>& b) {
1159 const int size = std::min(a.size(), b.size());
1160 for (
int i = 0; i < size; i++) {
1161 sum = sum + a[i] * b[i];
1173 return a.atoms.size();
1184 void SetSpline(
const vector<double>& x,
const vector<double>& y,
const double& yp1,
const double& ypn, vector<double>& y2) {
1191 const int n = x.size();
1193 vector<double> u(n - 1);
1194 y2 = vector<double>(n, 0.0);
1196 if (yp1 > 0.99e30) {
1200 u[0] = (3.0 / (x[2] - x[1])) * ((y[1] - y[0]) / (x[1] - x[0]) - yp1);
1202 for (i = 1; i <= n - 2; i++) {
1203 sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]);
1204 p = sig * y2[i - 1] + 2.0;
1205 y2[i] = (sig - 1.0) / p;
1206 u[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]);
1207 u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
1209 if (ypn > 0.99e30) {
1213 un = (3.0 / (x[n - 1] - x[n - 2])) * (ypn - (y[n - 1] - y[n - 2]) / (x[n - 1] - x[n - 2]));
1215 y2[n - 1] = (un - qn * u[n - 2]) / (qn * y2[n - 2] + 1.0);
1216 for (k = n - 2; k >= 0; k--) {
1217 y2[k] = y2[k] * y2[k + 1] + u[k];
1230 void GetSplineInt(
const vector<double>& xa,
const vector<double>& ya, vector<double>& y2a,
const double& x,
double& y) {
1237 const int n = xa.size();
1241 while (khi - klo > 1) {
1242 k = (khi + klo) >> 1;
1249 h = xa[khi] - xa[klo];
1253 a = (xa[khi] - x) / h;
1254 b = (x - xa[klo]) / h;
1255 y = a * ya[klo] + b * ya[khi] + ((a * a * a - a) * y2a[klo] + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0;
1265 void PrintSpline(
const vector<double>& x,
const vector<double>& y,
const int& npts, ostream& outf) {
1266 outf.setf(std::ios::left, std::ios::adjustfield);
1267 outf.setf(std::ios::fixed, std::ios::floatfield);
1268 outf <<
"******************** Initial Data ********************" << endl;
1269 const int ndat = x.size();
1270 for (
int id = 0;
id < ndat;
id++) {
1271 outf << x[id] <<
" " << y[id] <<
" " <<
"INPUT" << endl;
1273 outf <<
"******************** Cubic Spline Interpolated Points ********************" << endl;
1275 outf << x[0] <<
" " << y[0] <<
" " <<
"INTERPOLATED" << endl;
1277 const double yp1 = 0.0;
1278 const double ypn = 0.0;
1281 const double xrange = x[ndat - 1] - x[0];
1282 const double dx = xrange / (double) (npts - 1);
1283 for (
int ip = 0; ip < npts; ip++) {
1284 const double xp = x[0] + (double) ip * dx;
1287 outf << xp <<
" " << yp <<
" " <<
"INTERPOLATED" << endl;
vector< utype > clear(vector< utype > &v)
xvector< double > F2C(const double &scale, const xmatrix< double > &lattice, const xvector< double > &fpos)
xvector< double > C2F(const double &scale, const xmatrix< double > &lattice, const xvector< double > &cpos)
double Normal(const double &x, const double &mu, const double &sigma)
double GetXrayScattFactor(const string &_name, double lambda, bool clean)
xmatrix< double > GetLat(const xstructure &a)
int Nint(const double &x)
xstructure SetLat(const xstructure &a, const xmatrix< double > &in_lat)
xstructure WignerSeitz(const xstructure &a)
int SignNoZero(const double &x)
xvector< double > GetCDispFromOrigin(const _atom &atom)
xstructure SetMom1(const xstructure &a, const xvector< double > &mom1_new)
double GetDistFromOrigin(const _atom &atom)
int Sign(const double &x)
xvector< double > GetMom1(const xstructure &a)
_atom ConvertAtomToLat(const _atom &in_at, const xmatrix< double > &lattice)
xstructure PutInCell(const xstructure &a)
xstructure PutInCompact(const xstructure &a)
double Normal(const double &x, const double &mu, const double &sigma)
utype scalar_product(const xvector< utype > &a, const xvector< utype > &b)
xvector< utype > vector_product(const xvector< utype > &a, const xvector< utype > &b)
xmatrix< utype > sign(const xmatrix< utype > &a)
utype abs(const xcomplex< utype > &x)
xvector< utype > vector2xvector(const std::vector< utype > &, int lrows=1) __xprototype
xmatrix< utype > nint(const xmatrix< utype > &a)
vector< utype > xvector2vector(const xvector< utype > &xvec)
matrix< utype > xmatrix2matrix(const xmatrix< utype > &_xmatrix)
xmatrix< utype > matrix2xmatrix(const matrix< utype > &_matrix)
aurostd::matrix< double > GetFpos(const xstructure &str)
_atom SetName(const _atom &a, const string &in_name)
double VVprod(const vector< double > &a, const vector< double > &b)
xmatrix< double > RecipLat(const xmatrix< double > &lat)
double GetScale(const xstructure &a)
void GetSplineInt(const vector< double > &xa, const vector< double > &ya, vector< double > &y2a, const double &x, double &y)
void Vout(const vector< double > &a, ostream &out)
vector< double > SVprod(const double &s, const vector< double > &b)
double VVdot(const vector< double > &a, const vector< double > &b)
aurostd::matrix< double > MMmult(const aurostd::matrix< double > &a, const aurostd::matrix< double > &b)
void PrintSpline(const vector< double > &x, const vector< double > &y, const int &npts, ostream &outf)
void Mout(const aurostd::matrix< double > &m, ostream &out)
double getcos(const vector< double > &a, const vector< double > &b)
vector< double > VVdiff(const vector< double > &a, const vector< double > &b)
double norm(const vector< double > &v)
xstructure SetLat(const xstructure &a, const aurostd::matrix< double > &in_lat)
vector< double > vecC2F(const aurostd::matrix< double > &lat, const vector< double > &vc)
_atom SetNum(const _atom &a, const int in_num)
xstructure AddAllAtomPos(const xstructure &a, const aurostd::matrix< double > &in_pos, const int in_coord_flag)
xstructure SetAllAtomPos(const xstructure &a, const aurostd::matrix< double > &in_pos, const int in_coord_flag)
aurostd::matrix< double > GetScaledLat(const xstructure &a)
void SetSpline(const vector< double > &x, const vector< double > &y, const double &yp1, const double &ypn, vector< double > &y2)
_atom SetFpos(const _atom &a, const vector< double > &in_fpos)
xstructure SetAllAtomNames(const xstructure &a, const vector< string > &in_names)
_atom SetCpos(const _atom &a, const vector< double > &in_cpos)
void VVset(aurostd::matrix< double > &mat, const double &value)
vector< double > MVmult(const aurostd::matrix< double > &A, const vector< double > &v)
_atom SetType(const _atom &a, const int in_type)
vector< double > VVcross(const vector< double > &a, const vector< double > &b)
vector< double > SmoothFunc(const vector< double > &func, const double &sigma)
xstructure SetOrigin(const xstructure &a, const vector< double > &in_origin)
double GetSignedVol(const xmatrix< double > &lat)
vector< double > VVsum(const vector< double > &a, const vector< double > &b)
vector< double > vecF2C(const aurostd::matrix< double > &lat, const vector< double > &vf)
aurostd::matrix< double > GetLat(const xstructure &a)
vector< double > VMmult(const vector< double > &v, const aurostd::matrix< double > &A)
int GetNumAtoms(const xstructure &a)
vector< double > Getabc_angles(const aurostd::matrix< double > &lat)
double GetVol(const xmatrix< double > &lat)
vector< double > Sort_abc_angles(const vector< double > &abc_angles)
bool VVequal(const vector< double > &a, const vector< double > &b)
xstructure SetNamesWereGiven(const xstructure &a, const vector< int > &in_names_were_given)
aurostd::matrix< double > GetCpos(const xstructure &str)