first commit, Readme.html更新して、git管理することにした。

This commit is contained in:
2023-05-26 20:13:05 +09:00
commit ce85e3907f
26 changed files with 158505 additions and 0 deletions
+176
View File
@@ -0,0 +1,176 @@
#include "dump2analysis.h"
/* DOCUMENT */
/* -m msd */
/* lammpstrjから指定した原子の平均二乗変位(MSD)を時間シフトしながら計算する */
/* 原子タイプで指定しても最初のステップのidで原子を選択する */
/* --shfitと--tauを小さくすればMSDの統計が稼げる。ただしシフトが小さすぎるMSDが変化する。 */
/* --shiftでMSDが変わらないようパラメータを調整する。 */
/* 教科書Pを参照 */
/* A原子(-a, -x, -s)を指定する。 */
/* --shiftはMSDを計算する時にシフトさせるステップ default:1 */
/* --tauはMSDを計算する時間ステップ範囲。-1でMDの全ステップでMSDを計算する default:-1 */
/* --dtはMDの時間ステップでの時間(fs単位) default:1.0 */
void ErrorMSD(){
printf("Required arguments atoms A\n");
printf("(-a, -x, -s) atom A\n");
printf("------------------------------------------------------------\n");
printf("Optional arguments for MSD analysis:\n");
printf("--shift time shift for MSD [1]\n");
printf("--tau time period for MSD (-1: all steps [-1]\n");
printf("--dt time period for one step (fs) [1.0]\n");
printf("------------------------------------------------------------\n");
printf("Example:\n");
printf("dump2analysis -m msd -x Li --dt 1.2 --tau 2500 --shift 100 -i hoge.lammpstrj -o hoge.msd\n");
exit(0);
}
void OutputMSD(PARAM *p, double **msd, ATOMS *a, int step){
int i;
double t;
FILE *f;
f = fopen(p->outfile, "w");
fprintf(f, "# Atomic list: ");
for (i=0; i<a->atoms; i++) fprintf(f, "%s(%d) ", a->elem[i], a->id[i]);
fprintf(f, "\n");
fprintf(f, "# TAU: %d\n", TAU);
fprintf(f, "# TAU_SHIFT: %d\n", TAU_SHIFT);
fprintf(f, "# total TAU step: %d\n", step);
fprintf(f, "# atoms: %d\n", a->atoms);
fprintf(f, "# %12s ", "time/fs");
fprintf(f, "%14s ", "msd/Ang.2");
fprintf(f, "%14s ", "a/Ang.2");
fprintf(f, "%14s ", "b/Ang.2");
fprintf(f, "%14s ", "c/Ang.2");
fprintf(f, "\n");
for (i=0; i<TAU; i++){
t = i * (double)DT;
fprintf(f, "%14lf ", t);
fprintf(f, "%14e ", msd[0][i]);
fprintf(f, "%14e ", msd[1][i]);
fprintf(f, "%14e ", msd[2][i]);
fprintf(f, "%14e ", msd[3][i]);
fprintf(f, "\n");
}
fclose(f);
}
void EstimateMSD(PARAM *param){
int i, j, k, p, step_counter=0;
FILE *f;
HEAD *head;
double A[3][3];
ATOMS a;
double **xx, **yy, **zz;
double **msd; /* r, a, b, c */
double xp, yp, zp;
double r, sum[4], dx, dy, dz;
if (ArgCheckInputOutput(param) != 0) ErrorMSD();
SetAtomsSteps(param);
if (CheckArgAtomSelect(param) != 1) ErrorMSD();
/* 選択元素が変わるとおかしくなるので元素選択は全てid */
SetIDfromElemTtype(param);
Allocate(&a, param->Aid[0]-1);
head = malloc(sizeof(HEAD) * param->steps);
f = fopen(param->infile, "r");
/* -1の場合は全ステップでMSDを計算する */
if (TAU == -1) {
TAU = param->steps;
TAU_SHIFT = param->steps;
}
/* steps * atoms * (x, y, z)のメモリ取得 */
xx = malloc(sizeof(double*) * param->steps);
yy = malloc(sizeof(double*) * param->steps);
zz = malloc(sizeof(double*) * param->steps);
for(i=0; i<param->steps; i++){
xx[i] = malloc(sizeof(double) * a.atoms);
yy[i] = malloc(sizeof(double) * a.atoms);
zz[i] = malloc(sizeof(double) * a.atoms);
}
/* 分率座標のデータを全ステップで取得する */
printf("Loading data...\n");
fflush(stdout);
for (i=0; i<param->steps; i++){
GetData(f, param, &head[i], &a, NULL, NULL);
/* xx, yy, zzは分率座標 */
for (j=0; j<a.atoms; j++){
xx[i][j] = a.x[j];
yy[i][j] = a.y[j];
zz[i][j] = a.z[j];
}
}
/* 分率座標のwarapを解く */
Unwrap(param->steps, a.atoms, xx, yy, zz);
/* msdの計算 r, a, b, c*/
/* メモリ確保と初期化 */
msd = malloc(sizeof(double*) * 4);
for(i=0; i<4; i++) msd[i] = malloc(sizeof(double) * TAU);
for (k=0; k<4; k++)
for (i=0; i<TAU; i++) msd[k][i] = 0.0;
for (p=0; p+TAU <= param->steps; p=p+TAU_SHIFT){
printf("MSD step range: from %d to %d\n", p, p+TAU);
fflush(stdout);
for (i=0; i<TAU; i++){
for (k=0; k<4; k++) sum[k] = 0.0;
for (j=0; j<a.atoms; j++){
dx = xx[p+i][j] - xx[p][j];
dy = yy[p+i][j] - yy[p][j];
dz = zz[p+i][j] - zz[p][j];
/* nptのための処理。正しいか検討すること */
A[0][0] = (head[p+i].A[0][0] + head[p].A[0][0])*0.5;
A[0][1] = (head[p+i].A[0][1] + head[p].A[0][1])*0.5;
A[0][2] = (head[p+i].A[0][2] + head[p].A[0][2])*0.5;
A[1][0] = (head[p+i].A[1][0] + head[p].A[1][0])*0.5;
A[1][1] = (head[p+i].A[1][1] + head[p].A[1][1])*0.5;
A[1][2] = (head[p+i].A[1][2] + head[p].A[1][2])*0.5;
A[2][0] = (head[p+i].A[2][0] + head[p].A[2][0])*0.5;
A[2][1] = (head[p+i].A[2][1] + head[p].A[2][1])*0.5;
A[2][2] = (head[p+i].A[2][2] + head[p].A[2][2])*0.5;
xp = dx*A[0][0] + dy*A[1][0] + dz*A[2][0];
yp = dx*A[0][1] + dy*A[1][1] + dz*A[2][1];
zp = dx*A[0][2] + dy*A[1][2] + dz*A[2][2];
r = pow(xp, 2) + pow(yp, 2) + pow(zp, 2);
sum[0] = sum[0] + r;
sum[1] = sum[1] + dx*dx*head[p+i].a*head[p+i].a;
sum[2] = sum[2] + dy*dy*head[p+i].b*head[p+i].b;
sum[3] = sum[3] + dz*dz*head[p+i].c*head[p+i].c;
}
msd[0][i] = msd[0][i] + sum[0]/(double)a.atoms;
msd[1][i] = msd[1][i] + sum[1]/(double)a.atoms;
msd[2][i] = msd[2][i] + sum[2]/(double)a.atoms;
msd[3][i] = msd[3][i] + sum[3]/(double)a.atoms;
}
step_counter++;
}
if (step_counter == 0){
printf("--tau is too long, can not calculate MSD!!!\n");
exit(0);
}
for (k=0; k<4; k++)
for (i=0; i<TAU; i++) msd[k][i] = msd[k][i]/(double)step_counter;
OutputMSD(param, msd, &a, step_counter);
free(head);
for(i=0; i<param->steps; i++){
free(xx[i]);
free(yy[i]);
free(zz[i]);
}
free(xx);
free(yy);
free(zz);
for(i=0; i<4; i++) free(msd[i]);
free(msd);
}