Files
2022-07-15 18:44:51 +09:00

195 lines
5.5 KiB
C

#include "dump2sq.h"
void SetMatrix(HEAD *head){
double a, b, c;
double alpha, beta, gamma;
head->lmax = head->lx;
if (head->lmax < head->ly) head->lmax = head->ly;
if (head->lmax < head->lz) head->lmax = head->lz;
head->lmin = head->lx;
if (head->lmin > head->ly) head->lmin = head->ly;
if (head->lmin > head->lz) head->lmin = head->lz;
a = head->lx;
b = head->ly;
c = head->lz;
alpha = head->alpha * M_PI/180.0;
beta = head->beta * M_PI/180.0;
gamma = head->gamma * M_PI/180.0;
head->M[0][0] = a;
head->M[0][1] = 0;
head->M[0][2] = 0;
head->M[1][0] = b*cos(gamma);
head->M[1][1] = b*sin(gamma);
head->M[1][2] = 0;
head->M[2][0] = c*cos(beta);
head->M[2][1] = c*(cos(alpha)-cos(beta)*cos(gamma))/sin(gamma);
head->M[2][2] = c*sqrt(1+2*cos(alpha)*cos(beta)*cos(gamma)
- cos(alpha)*cos(alpha)
- cos(beta)*cos(beta)
- cos(gamma)*cos(gamma)) /sin(gamma);
head->M[2][2] = c*sqrt(1+2*cos(alpha)*cos(beta)*cos(gamma)
- cos(alpha)*cos(alpha)
- cos(beta)*cos(beta)
- cos(gamma)*cos(gamma)) /sin(gamma);
head->volume = head->M[0][0] * head->M[1][1] * head->M[2][2];
head->rho = head->atoms / head->volume;
/* 逆行列の計算 */
double det_A;
det_A = head->volume;
head->M_[0][0] = (head->M[1][1]*head->M[2][2] - head->M[1][2]*head->M[2][1])/det_A;
head->M_[1][0] = (head->M[1][2]*head->M[2][0] - head->M[1][0]*head->M[2][2])/det_A;
head->M_[2][0] = (head->M[1][0]*head->M[2][1] - head->M[1][1]*head->M[2][0])/det_A;
head->M_[0][1] = 0.0;
head->M_[1][1] = (head->M[0][0]*head->M[2][2] - head->M[0][2]*head->M[2][0])/det_A;
head->M_[2][1] = (head->M[0][1]*head->M[2][0] - head->M[0][0]*head->M[2][1])/det_A;
head->M_[0][2] = 0.0;
head->M_[1][2] = 0.0;
head->M_[2][2] = (head->M[0][0]*head->M[1][1] - head->M[0][1]*head->M[1][0])/det_A;
}
void ToFractionalCoord(HEAD *head, DATA *data){
int i;
double x, y, z;
for (i=0; i<head->atoms; i++){
x = data[i].x;
y = data[i].y;
z = data[i].z;
data[i].x = x*head->M_[0][0] + y*head->M_[1][0] + z*head->M_[2][0];
data[i].y = x*head->M_[0][1] + y*head->M_[1][1] + z*head->M_[2][1];
data[i].z = x*head->M_[0][2] + y*head->M_[1][2] + z*head->M_[2][2];
data[i].x = data[i].x - floor(data[i].x);
data[i].y = data[i].y - floor(data[i].y);
data[i].z = data[i].z - floor(data[i].z);
}
}
/* femteckのfort.10用 */
int ReadHeadXYZ(FILE *fp, HEAD *head){
char buf[1024];
int chk;
/* ITEM: TIMESTEP */
if(fgets(buf, 1024, fp)==NULL) return 1;
chk = sscanf(buf, "%d", &head->atoms);
if(fgets(buf, 1024, fp)==NULL) return 1;
chk = sscanf(buf, "Step %d %lf %lf %lf %lf %lf %lf",
&head->step,
&head->lx, &head->ly, &head->lz,
&head->alpha, &head->beta, &head->gamma);
if (chk == 4){
head->alpha = 90.0;
head->beta = 90.0;
head->gamma = 90.0;
}
SetMatrix(head);
return 0;
}
/* femteckのfort.10用 */
int ReadDataXYZ(FILE *fp, HEAD *head, DATA *data)
{
int i;
char buf[1024];
for(i=0; i<head->atoms; i++){
if(fgets(buf, sizeof(buf), fp)==NULL) return 1;
sscanf(buf, "%s %lf %lf %lf",
data[i].elem, &data[i].x, &data[i].y, &data[i].z);
}
ToFractionalCoord(head, data);
return 0;
}
int ReadHeadLammpstrj(FILE *fp, HEAD *head){
char buf[1024];
int chk;
double a, b, c;
double ly, lz;
double xlo, xhi, xy;
double ylo, yhi, xz;
double zlo, zhi, yz;
double x_low=0.0, x_high=0.0;
double y_low=0.0, y_high=0.0;
/* ITEM: TIMESTEP */
if(fgets(buf, 1024, fp)==NULL) return 1;
if(fgets(buf, 1024, fp)==NULL) return 1;
/* ITEM: NUMBER OF ATOMS */
if(fgets(buf, 1024, fp)==NULL) return 1;
if(fgets(buf, 1024, fp)==NULL) return 1;
chk = sscanf(buf, "%d", &head->atoms);
if (chk != 1) return 1;
/* ITEM: BOX BOUNDS pp pp pp */
if(fgets(buf, 1024, fp)==NULL) return 1;
if(fgets(buf, 1024, fp)==NULL) return 1;
chk = sscanf(buf, "%lf %lf %lf", &xlo, &xhi, &xy);
if(fgets(buf, 1024, fp)==NULL) return 1;
chk = sscanf(buf, "%lf %lf %lf", &ylo, &yhi, &xz);
if(fgets(buf, 1024, fp)==NULL) return 1;
chk = sscanf(buf, "%lf %lf %lf", &zlo, &zhi, &yz);
if (chk == 3){ /* triclinic */
/* x */
if (x_low> xy) x_low = xy;
if (x_low > xz) x_low = xz;
if (x_low > (xy+xz)) x_low = xy+xz;
if (x_high < xy) x_high = xy;
if (x_high < xz) x_high = xz;
if (x_high < (xy+xz)) x_high = xy+xz;
xlo = xlo - x_low;
xhi = xhi - x_high;
a = xhi - xlo;
/* y */
if (y_low > yz) y_low = yz;
if (y_high < yz) y_high = yz;
ylo = ylo - y_low;
yhi = yhi - y_high;
ly = yhi - ylo;
b = sqrt(ly*ly + xy*xy);
/* z */
lz = zhi - zlo;
c = sqrt(lz*lz + xz*xz + yz*yz);
/* angle */
head->alpha = acos((yz*ly+xy*xz)/ (b*c)) * 180.0/M_PI;
head->beta = acos(xz/c) * 180.0/M_PI;
head->gamma = acos(xy/b) * 180.0/M_PI;
head->lx = a;
head->ly = b;
head->lz = c;
}
else{
head->alpha = 90;
head->beta = 90;
head->gamma = 90;
head->lx = xhi - xlo;
head->ly = yhi - ylo;
head->lz = zhi - zlo;
}
SetMatrix(head);
return 0;
}
int ReadDataLammpstrj(FILE *fp, HEAD *head, DATA *data)
{
int i;
char buf[1024];
if(fgets(buf, sizeof(buf), fp)==NULL) return 1;
for(i=0; i<head->atoms; i++){
if(fgets(buf, sizeof(buf), fp)==NULL) return 1;
sscanf(buf, "%d %d %s %lf %lf %lf",
&data[i].id, &data[i].type,
data[i].elem,
&data[i].x, &data[i].y, &data[i].z);
}
ToFractionalCoord(head, data);
return 0;
}