From 2d562a1946322ae5b70bdce180321f32adbeab62 Mon Sep 17 00:00:00 2001 From: hackbard Date: Mon, 18 Dec 2006 09:30:22 +0000 Subject: [PATCH 01/16] foo --- Makefile | 3 ++- moldyn.c | 42 +++++++++++++++++++++++++++++++++++++++--- sic.c | 38 +++++++++++++++++++------------------- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 42ff2bd..39457f7 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,9 @@ CC=gcc-3.4 #CC=gcc CFLAGS=-Wall CFLAGS+=-O3 -CFLAGS+=-g CFLAGS+=-ffloat-store +CFLAGS+=-g +CFLAGS+=-DDEBUG LDFLAGS=-lm OBJS=visual/visual.o random/random.o diff --git a/moldyn.c b/moldyn.c index db91859..faa6b7c 100644 --- a/moldyn.c +++ b/moldyn.c @@ -541,13 +541,13 @@ int scale_volume(t_moldyn *moldyn) { } /* just a guess so far ... */ - v=sqrt(virial.xx*virial.xx+virial.yy*virial.yy+virial.zz+virial.zz); + v=virial.xx+virial.yy+virial.zz; printf("%f\n",v); /* get pressure from virial */ - moldyn->p=moldyn->count*K_BOLTZMANN*moldyn->t-ONE_THIRD*v; + moldyn->p=moldyn->count*K_BOLTZMANN*moldyn->t+ONE_THIRD*v; moldyn->p/=moldyn->volume; -printf("%f\n",moldyn->p/(ATM)); +printf("%f | %f\n",moldyn->p/(ATM),moldyn->p_ref/ATM); /* scale factor */ if(moldyn->pt_scale&P_SCALE_BERENDSEN) @@ -1427,6 +1427,15 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { /* add forces of 2bp (ij, ji) contribution * dVij = dVji and we sum up both: no 1/2) */ v3_add(&(ai->f),&(ai->f),&force); + + /* virial */ + ai->virial.xx-=force.x*dist_ij.x; + ai->virial.yy-=force.y*dist_ij.y; + ai->virial.zz-=force.z*dist_ij.z; + ai->virial.xy-=force.x*dist_ij.y; + ai->virial.xz-=force.x*dist_ij.z; + ai->virial.yz-=force.y*dist_ij.z; + #ifdef DEBUG if(ai==&(moldyn->atom[0])) { printf("dVij, dVji (2bp) contrib:\n"); @@ -1526,6 +1535,15 @@ int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { /* add force */ v3_add(&(ai->f),&(ai->f),&force); + + /* virial */ + ai->virial.xx-=force.x*dist_ij->x; + ai->virial.yy-=force.y*dist_ij->y; + ai->virial.zz-=force.z*dist_ij->z; + ai->virial.xy-=force.x*dist_ij->y; + ai->virial.xz-=force.x*dist_ij->z; + ai->virial.yz-=force.y*dist_ij->z; + #ifdef DEBUG if(ai==&(moldyn->atom[0])) { printf("dVij (3bp) contrib:\n"); @@ -1562,6 +1580,15 @@ if(ai==&(moldyn->atom[0])) { /* add force */ v3_add(&(ai->f),&(ai->f),&force); + + /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ + ai->virial.xx+=force.x*dist_ij->x; + ai->virial.yy+=force.y*dist_ij->y; + ai->virial.zz+=force.z*dist_ij->z; + ai->virial.xy+=force.x*dist_ij->y; + ai->virial.xz+=force.x*dist_ij->z; + ai->virial.yz+=force.y*dist_ij->z; + #ifdef DEBUG if(ai==&(moldyn->atom[0])) { printf("dVji (3bp) contrib:\n"); @@ -1830,6 +1857,15 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { v3_scale(&temp2,&temp2,tmp*B*exp(-mu*d_jk)*f_c_jk*0.5); v3_add(&(ai->f),&(ai->f),&temp2); /* -1 skipped in f_a calc ^ */ /* scaled with 0.5 ^ */ + + /* virial */ + ai->virial.xx-=temp2.x*dist_jk.x; + ai->virial.yy-=temp2.y*dist_jk.y; + ai->virial.zz-=temp2.z*dist_jk.z; + ai->virial.xy-=temp2.x*dist_jk.y; + ai->virial.xz-=temp2.x*dist_jk.z; + ai->virial.yz-=temp2.y*dist_jk.z; + #ifdef DEBUG if(ai==&(moldyn->atom[0])) { printf("dVjk (3bp) contrib:\n"); diff --git a/sic.c b/sic.c index c4355b3..aabb79c 100644 --- a/sic.c +++ b/sic.c @@ -112,26 +112,26 @@ int main(int argc,char **argv) { /* create the lattice / place atoms */ printf("[sic] creating atoms\n"); - //create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, - // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - // 0,5,5,5); - //moldyn_bc_check(&md); + create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, + ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, + 0,5,5,5); + moldyn_bc_check(&md); /* testing configuration */ - r.x=2.8/2; v.x=0; - r.y=0; v.y=0; - r.z=0; v.z=0; - add_atom(&md,SI,M_SI,0, - ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP,//|ATOM_ATTR_HB, + //r.x=2.8/2; v.x=0; + //r.y=0; v.y=0; + //r.z=0; v.z=0; + //add_atom(&md,SI,M_SI,0, + // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, // ATOM_ATTR_2BP, - &r,&v); - r.x=-2.8/2; v.x=0; - r.y=0; v.y=0; - r.z=0; v.z=0; - add_atom(&md,SI,M_SI,0, - ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP,//|ATOM_ATTR_HB, + // &r,&v); + //r.x=-2.8/2; v.x=0; + //r.y=0; v.y=0; + //r.z=0; v.z=0; + //add_atom(&md,SI,M_SI,0, + // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, // ATOM_ATTR_2BP, - &r,&v); + // &r,&v); /* setting a nearest neighbour distance for the moldyn checks */ set_nn_dist(&md,0.25*sqrt(3.0)*LC_SI); /* diamond ! */ @@ -153,7 +153,7 @@ int main(int argc,char **argv) { printf("[sic] set p/t scaling\n"); //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0, // T_SCALE_BERENDSEN,100.0); - //set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); + set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); /* initial thermal fluctuations of particles (in equilibrium) */ printf("[sic] thermal init\n"); @@ -161,13 +161,13 @@ int main(int argc,char **argv) { /* create the simulation schedule */ printf("[sic] adding schedule\n"); - moldyn_add_schedule(&md,10000,.1); + moldyn_add_schedule(&md,100,1.0); /* activate logging */ printf("[sic] activate logging\n"); moldyn_set_log_dir(&md,argv[1]); moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); - moldyn_set_log(&md,VISUAL_STEP,20); + moldyn_set_log(&md,VISUAL_STEP,1); /* * let's do the actual md algorithm now -- 2.20.1 From 115ab83cedba54af2d165b8900781b98c5326b55 Mon Sep 17 00:00:00 2001 From: hackbard Date: Thu, 28 Dec 2006 14:15:13 +0000 Subject: [PATCH 02/16] bugfix dg of dV_ji,jk --- moldyn.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++--------- moldyn.h | 1 + 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/moldyn.c b/moldyn.c index faa6b7c..c21f59f 100644 --- a/moldyn.c +++ b/moldyn.c @@ -1129,6 +1129,9 @@ int potential_force_calc(t_moldyn *moldyn) { } #ifdef DEBUG printf("\n\n"); +#endif +#ifdef VDEBUG +printf("\n\n"); #endif return 0; @@ -1376,6 +1379,7 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { /* save for use in 3bp */ exchange->d_ij=d_ij; + exchange->d_ij2=d_ij2; exchange->dist_ij=dist_ij; /* more constants */ @@ -1443,6 +1447,14 @@ if(ai==&(moldyn->atom[0])) { printf("%f | %f\n",force.y,ai->f.y); printf("%f | %f\n",force.z,ai->f.z); } +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij, dVji (2bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij.x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij.y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij.z,ai->virial.zz); +} #endif /* energy 2bp contribution (ij, ji) is 0.5 f_r f_c ... */ @@ -1551,6 +1563,14 @@ if(ai==&(moldyn->atom[0])) { printf("%f | %f\n",force.y,ai->f.y); printf("%f | %f\n",force.z,ai->f.z); } +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij (3bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); +} #endif /* add energy of 3bp sum */ @@ -1596,6 +1616,14 @@ if(ai==&(moldyn->atom[0])) { printf("%f | %f\n",force.y,ai->f.y); printf("%f | %f\n",force.z,ai->f.z); } +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVji (3bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); +} #endif return 0; @@ -1610,9 +1638,9 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { t_3dvec dist_ij,dist_ik,dist_jk; t_3dvec temp1,temp2; t_3dvec *dzeta; - double R,S,s_r; + double R,S,S2,s_r; double B,mu; - double d_ij,d_ik,d_jk; + double d_ij,d_ik,d_jk,d_ij2,d_ik2,d_jk2; double rr,dd; double f_c,df_c; double f_c_ik,df_c_ik,arg; @@ -1658,6 +1686,7 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { /* dist_ij, d_ij - this is < S_ij ! */ dist_ij=exchange->dist_ij; d_ij=exchange->d_ij; + d_ij2=exchange->d_ij2; /* f_c_ij, df_c_ij (same for ji) */ f_c=exchange->f_c; @@ -1672,21 +1701,26 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { /* dist_ik, d_ik */ v3_sub(&dist_ik,&(ak->r),&(ai->r)); if(bc) check_per_bound(moldyn,&dist_ik); - d_ik=v3_norm(&dist_ik); + d_ik2=v3_absolute_square(&dist_ik); /* ik constants */ brand=ai->brand; if(brand==ak->brand) { R=params->R[brand]; S=params->S[brand]; + S2=params->S2[brand]; } else { R=params->Rmixed; S=params->Smixed; + S2=params->S2mixed; } /* zeta_ij/dzeta_ij contribution only for d_ik < S */ - if(d_ikn_i); @@ -1704,8 +1738,8 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { /* d_costheta */ tmp=1.0/dd; - d_costheta1=cos_theta/(d_ij*d_ij)-tmp; - d_costheta2=cos_theta/(d_ik*d_ik)-tmp; + d_costheta1=cos_theta/d_ij2-tmp; + d_costheta2=cos_theta/d_ik2-tmp; /* some usefull values */ h_cos=(h-cos_theta); @@ -1757,13 +1791,14 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { /* dist_jk, d_jk */ v3_sub(&dist_jk,&(ak->r),&(aj->r)); if(bc) check_per_bound(moldyn,&dist_jk); - d_jk=v3_norm(&dist_jk); + d_jk2=v3_absolute_square(&dist_jk); /* jk constants */ brand=aj->brand; if(brand==ak->brand) { R=params->R[brand]; S=params->S[brand]; + S2=params->S2[brand]; B=params->B[brand]; mu=params->mu[brand]; chi=1.0; @@ -1771,13 +1806,17 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { else { R=params->Rmixed; S=params->Smixed; + S2=params->S2mixed; B=params->Bmixed; mu=params->mu_m; chi=params->chi; } /* zeta_ji/dzeta_ji contribution only for d_jk < S_jk */ - if(d_jkn_j); @@ -1795,7 +1834,7 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { /* d_costheta */ d_costheta1=1.0/dd; - d_costheta2=cos_theta/(d_ij*d_ij); + d_costheta2=cos_theta/d_ij2; /* some usefull values */ h_cos=(h-cos_theta); @@ -1805,10 +1844,11 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { /* g(cos_theta) */ g=1.0+c2d2-frac; - /* d_costheta_ij and dg(cos_theta) - needed in any case! */ + /* d_costheta_jik and dg(cos_theta) - needed in any case! */ v3_scale(&temp1,&dist_jk,d_costheta1); v3_scale(&temp2,&dist_ij,-d_costheta2); /* ji -> ij => -1 */ - v3_add(&temp1,&temp1,&temp2); + //v3_add(&temp1,&temp1,&temp2); + v3_sub(&temp1,&temp1,&temp2); /* there is a minus! */ v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ /* store dg in temp2 and use it for dVjk later */ @@ -1873,6 +1913,14 @@ if(ai==&(moldyn->atom[0])) { printf("%f | %f\n",temp2.y,ai->f.y); printf("%f | %f\n",temp2.z,ai->f.z); } +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVjk (3bp) contrib:\n"); + printf("%f | %f\n",temp2.x*dist_jk.x,ai->virial.xx); + printf("%f | %f\n",temp2.y*dist_jk.y,ai->virial.yy); + printf("%f | %f\n",temp2.z*dist_jk.z,ai->virial.zz); +} #endif } diff --git a/moldyn.h b/moldyn.h index dd94b0e..23b5100 100644 --- a/moldyn.h +++ b/moldyn.h @@ -195,6 +195,7 @@ typedef struct s_tersoff_exchange { double f_a,df_a; t_3dvec dist_ij; + double d_ij2; double d_ij; double chi; -- 2.20.1 From 15b4727e1137600f8f46af027aefd2b5c7a56420 Mon Sep 17 00:00:00 2001 From: hackbard Date: Fri, 12 Jan 2007 19:35:12 +0000 Subject: [PATCH 03/16] still full of bugs ... --- Makefile | 3 +- moldyn.c | 149 +++++++++++++++++++++++++++++++++++++++++++++---------- moldyn.h | 11 +++- sic.c | 51 ++++++++++--------- 4 files changed, 162 insertions(+), 52 deletions(-) diff --git a/Makefile b/Makefile index 39457f7..c51f8bd 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ CFLAGS=-Wall CFLAGS+=-O3 CFLAGS+=-ffloat-store CFLAGS+=-g -CFLAGS+=-DDEBUG +#CFLAGS+=-DDEBUG +#CFLAGS+=-DVDEBUG LDFLAGS=-lm OBJS=visual/visual.o random/random.o diff --git a/moldyn.c b/moldyn.c index c21f59f..d33de02 100644 --- a/moldyn.c +++ b/moldyn.c @@ -460,6 +460,28 @@ int thermal_init(t_moldyn *moldyn,u8 equi_init) { return 0; } +double temperature_calc(t_moldyn *moldyn) { + + double double_ekin; + int i; + t_atom *atom; + + atom=moldyn->atom; + + for(i=0;icount;i++) + double_ekin+=atom[i].mass*v3_absolute_square(&(atom[i].v)); + + /* kinetic energy = 3/2 N k_B T */ + moldyn->t=double_ekin/(3.0*K_BOLTZMANN*moldyn->count); + + return moldyn->t; +} + +double get_temperature(t_moldyn *moldyn) { + + return moldyn->t; +} + int scale_velocity(t_moldyn *moldyn,u8 equi_init) { int i; @@ -478,10 +500,11 @@ int scale_velocity(t_moldyn *moldyn,u8 equi_init) { count=0; for(i=0;icount;i++) { if((equi_init&TRUE)||(atom[i].attr&ATOM_ATTR_HB)) { - e+=0.5*atom[i].mass*v3_absolute_square(&(atom[i].v)); + e+=atom[i].mass*v3_absolute_square(&(atom[i].v)); count+=1; } } + e*=0.5; if(count!=0) moldyn->t=e/(1.5*count*K_BOLTZMANN); else return 0; /* no atoms involved in scaling! */ @@ -515,6 +538,34 @@ int scale_velocity(t_moldyn *moldyn,u8 equi_init) { return 0; } +double pressure_calc(t_moldyn *moldyn) { + + int i; + t_atom *atom; + double p1,p2,p=0; + + for(i=0;icount;i++) { + + + } + + p1=(moldyn->count*K_BOLTZMANN*moldyn->t-ONE_THIRD*moldyn->vt1); + p1/=moldyn->volume; + + p2=(moldyn->count*K_BOLTZMANN*moldyn->t-ONE_THIRD*moldyn->vt2); + p2/=moldyn->volume; + + printf("compare pressures: %f %f\n",p1/ATM,p2/ATM); + + return moldyn->p; +} + +double get_pressure(t_moldyn *moldyn) { + + return moldyn->p; + +} + int scale_volume(t_moldyn *moldyn) { t_atom *atom; @@ -592,11 +643,6 @@ double get_e_kin(t_moldyn *moldyn) { return moldyn->ekin; } -double get_e_pot(t_moldyn *moldyn) { - - return moldyn->energy; -} - double update_e_kin(t_moldyn *moldyn) { return(get_e_kin(moldyn)); @@ -659,6 +705,9 @@ int link_cell_init(t_moldyn *moldyn) { lc->cells=lc->nx*lc->ny*lc->nz; lc->subcell=malloc(lc->cells*sizeof(t_list)); + if(lc->cells<27) + printf("[moldyn] FATAL: less then 27 subcells!\n"); + printf("[moldyn] initializing linked cells (%d)\n",lc->cells); for(i=0;icells;i++) @@ -885,13 +934,21 @@ int moldyn_integrate(t_moldyn *moldyn) { scale_volume(moldyn); /* check for log & visualization */ +//double ax; +//double ao; +//double av; if(e) { if(!(i%e)) +//ao=sqrt(0.1/M_SI); +//ax=((0.28-0.25)*sqrt(3)*LC_SI/2)*cos(ao*i); +//av=ao*(0.28-0.25)*sqrt(3)*LC_SI/2*sin(ao*i); + update_e_kin(moldyn); dprintf(moldyn->efd, "%f %f %f %f\n", - moldyn->time,update_e_kin(moldyn), + moldyn->time,moldyn->ekin, moldyn->energy, get_total_energy(moldyn)); +//moldyn->atom[0].r.x,ax,av*av*M_SI,0.1*ax*ax,av*av*M_SI+0.1*ax*ax); } if(m) { if(!(i%m)) { @@ -946,7 +1003,7 @@ int moldyn_integrate(t_moldyn *moldyn) { int velocity_verlet(t_moldyn *moldyn) { int i,count; - double tau,tau_square; + double tau,tau_square,h; t_3dvec delta; t_atom *atom; @@ -957,14 +1014,15 @@ int velocity_verlet(t_moldyn *moldyn) { for(i=0;ienergy=0.0; + + moldyn->vt2=0.0; /* get energy and force of every atom */ for(i=0;ixy=0.0; virial->xz=0.0; virial->yz=0.0; + moldyn->vt1=0.0; /* reset site energy */ itom[i].e=0.0; @@ -1134,6 +1195,30 @@ printf("\n\n"); printf("\n\n"); #endif + moldyn->vt2=0.0; + for(i=0;ivt2-=v3_scalar_product(&(itom[i].r),&(itom[i].f)); + +printf("compare: vt1: %f vt2: %f\n",moldyn->vt1,moldyn->vt2); + +pressure_calc(moldyn); + + return 0; +} + +/* + * virial calculation + */ + +inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) { + + a->virial.xx-=f->x*d->x; + a->virial.yy-=f->y*d->y; + a->virial.zz-=f->z*d->z; + a->virial.xy-=f->x*d->y; + a->virial.xz-=f->x*d->z; + a->virial.yz-=f->y*d->z; + return 0; } @@ -1179,23 +1264,29 @@ int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { t_ho_params *params; t_3dvec force,distance; - double d; + double d,f; double sc,equi_dist; params=moldyn->pot2b_params; sc=params->spring_constant; equi_dist=params->equilibrium_distance; + if(air),&(ai->r)); if(bc) check_per_bound(moldyn,&distance); d=v3_norm(&distance); if(d<=moldyn->cutoff) { - /* energy is 1/2 (d-d0)^2, but we will add this twice ... */ - moldyn->energy+=(0.25*sc*(d-equi_dist)*(d-equi_dist)); + moldyn->energy+=(0.5*sc*(d-equi_dist)*(d-equi_dist)); /* f = -grad E; grad r_ij = -1 1/r_ij distance */ - v3_scale(&force,&distance,sc*(1.0-(equi_dist/d))); + f=sc*(1.0-equi_dist/d); + v3_scale(&force,&distance,f); v3_add(&(ai->f),&(ai->f),&force); + virial_calc(ai,&force,&distance); + virial_calc(aj,&force,&distance); /* f and d signe switched */ + v3_scale(&force,&distance,-f); + v3_add(&(aj->f),&(aj->f),&force); } return 0; @@ -1215,6 +1306,8 @@ int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { sig6=params->sigma6; sig12=params->sigma12; + if(air),&(ai->r)); if(bc) check_per_bound(moldyn,&distance); d=v3_absolute_square(&distance); /* 1/r^2 */ @@ -1223,16 +1316,20 @@ int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { h2=d*d; /* 1/r^4 */ h2*=d; /* 1/r^6 */ h1=h2*h2; /* 1/r^12 */ - /* energy is eps*..., but we will add this twice ... */ - moldyn->energy+=0.5*eps*(sig12*h1-sig6*h2); + moldyn->energy+=(eps*(sig12*h1-sig6*h2)-params->uc); h2*=d; /* 1/r^8 */ h1*=d; /* 1/r^14 */ h2*=6*sig6; h1*=12*sig12; d=+h1-h2; d*=eps; + v3_scale(&force,&distance,d); + v3_add(&(aj->f),&(aj->f),&force); v3_scale(&force,&distance,-1.0*d); /* f = - grad E */ v3_add(&(ai->f),&(ai->f),&force); + virial_calc(ai,&force,&distance); + virial_calc(aj,&force,&distance); /* f and d signe switched */ + moldyn->vt1-=v3_scalar_product(&force,&distance); } return 0; @@ -1526,7 +1623,6 @@ int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { zeta=exchange->zeta_ij; if(zeta==0.0) { moldyn->debug++; /* just for debugging ... */ - db=0.0; b=chi; v3_scale(&force,dist_ij,df_a*b*f_c); } @@ -1602,12 +1698,13 @@ if(ai==&(moldyn->atom[0])) { v3_add(&(ai->f),&(ai->f),&force); /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ - ai->virial.xx+=force.x*dist_ij->x; - ai->virial.yy+=force.y*dist_ij->y; - ai->virial.zz+=force.z*dist_ij->z; - ai->virial.xy+=force.x*dist_ij->y; - ai->virial.xz+=force.x*dist_ij->z; - ai->virial.yz+=force.y*dist_ij->z; +// TEST ... with a minus instead + ai->virial.xx-=force.x*dist_ij->x; + ai->virial.yy-=force.y*dist_ij->y; + ai->virial.zz-=force.z*dist_ij->z; + ai->virial.xy-=force.x*dist_ij->y; + ai->virial.xz-=force.x*dist_ij->z; + ai->virial.yz-=force.y*dist_ij->z; #ifdef DEBUG if(ai==&(moldyn->atom[0])) { diff --git a/moldyn.h b/moldyn.h index 23b5100..c5cc064 100644 --- a/moldyn.h +++ b/moldyn.h @@ -82,6 +82,7 @@ typedef struct s_moldyn { t_3dvec dim; /* dimensions of the simulation volume */ double volume; /* volume of sim cell (dim.x*dim.y*dim.z) */ + double vt1,vt2; /* potential force function and parameter pointers */ int (*func1b)(struct s_moldyn *moldyn,t_atom *ai); @@ -183,6 +184,7 @@ typedef struct s_lj_params { double sigma6; double sigma12; double epsilon4; + double uc; } t_lj_params; /* @@ -401,11 +403,15 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr, int destroy_atoms(t_moldyn *moldyn); int thermal_init(t_moldyn *moldyn,u8 equi_init); +double temperature_calc(t_moldyn *moldyn); +double get_temperature(t_moldyn *moldyn); int scale_velocity(t_moldyn *moldyn,u8 equi_init); +double pressure_calc(t_moldyn *moldyn); +double get_pressure(t_moldyn *moldyn); int scale_volume(t_moldyn *moldyn); double get_e_kin(t_moldyn *moldyn); -double get_e_pot(t_moldyn *moldyn); +double update_e_kin(t_moldyn *moldyn); double get_total_energy(t_moldyn *moldyn); t_3dvec get_total_p(t_moldyn *moldyn); @@ -423,9 +429,10 @@ int moldyn_integrate(t_moldyn *moldyn); int velocity_verlet(t_moldyn *moldyn); int potential_force_calc(t_moldyn *moldyn); +inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) + __attribute__((always_inline)); inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) __attribute__((always_inline)); -int check_per_bound(t_moldyn *moldyn,t_3dvec *a); int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); int tersoff_mult_complete_params(t_tersoff_mult_params *p); diff --git a/sic.c b/sic.c index aabb79c..e2e8626 100644 --- a/sic.c +++ b/sic.c @@ -46,11 +46,17 @@ int main(int argc,char **argv) { /* choose potential */ printf("[sic] selecting potential\n"); - set_potential1b(&md,tersoff_mult_1bp,&tp); - set_potential2b(&md,tersoff_mult_2bp,&tp); - set_potential2b_post(&md,tersoff_mult_post_2bp,&tp); - set_potential3b(&md,tersoff_mult_3bp,&tp); - //set_potential2b(&md,lennard_jones,&lj); + //set_potential1b(&md,tersoff_mult_1bp,&tp); + //set_potential2b(&md,tersoff_mult_2bp,&tp); + //set_potential2b_post(&md,tersoff_mult_post_2bp,&tp); + //set_potential3b(&md,tersoff_mult_3bp,&tp); + set_potential2b(&md,lennard_jones,&lj); + //set_potential2b(&md,harmonic_oscillator,&ho); + + /* cutoff radius */ + printf("[sic] setting cutoff radius\n"); + //set_cutoff(&md,TM_S_SI); + set_cutoff(&md,3*LC_SI); /* * potential parameters @@ -61,10 +67,11 @@ int main(int argc,char **argv) { lj.sigma6*=lj.sigma6; lj.sigma12=lj.sigma6*lj.sigma6; lj.epsilon4=4.0*LJ_EPSILON_SI; + lj.uc=lj.epsilon4*(lj.sigma12/pow(md.cutoff,12.0)-lj.sigma6/pow(md.cutoff,6)); /* harmonic oscillator */ ho.equilibrium_distance=0.25*sqrt(3.0)*LC_SI; - ho.spring_constant=1; + ho.spring_constant=.1; /* * tersoff mult potential parameters for SiC @@ -97,14 +104,9 @@ int main(int argc,char **argv) { tersoff_mult_complete_params(&tp); - /* cutoff radius */ - printf("[sic] setting cutoff radius\n"); - set_cutoff(&md,TM_S_SI); - //set_cutoff(&md,2*LC_SI); - /* set (initial) dimensions of simulation volume */ printf("[sic] setting dimensions\n"); - set_dim(&md,5*LC_SI,5*LC_SI,5*LC_SI,TRUE); + set_dim(&md,10*LC_SI,10*LC_SI,10*LC_SI,TRUE); /* set periodic boundary conditions in all directions */ printf("[sic] setting periodic boundary conditions\n"); @@ -113,24 +115,26 @@ int main(int argc,char **argv) { /* create the lattice / place atoms */ printf("[sic] creating atoms\n"); create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, - ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - 0,5,5,5); + // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, + ATOM_ATTR_2BP|ATOM_ATTR_HB, + 0,10,10,10); moldyn_bc_check(&md); /* testing configuration */ - //r.x=2.8/2; v.x=0; + //r.x=0.28*sqrt(3)*LC_SI/2; v.x=0; + //r.x=1.75*LC_SI; v.x=-0.01; //r.y=0; v.y=0; //r.z=0; v.z=0; //add_atom(&md,SI,M_SI,0, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - // ATOM_ATTR_2BP, + // ATOM_ATTR_2BP|ATOM_ATTR_HB, // &r,&v); - //r.x=-2.8/2; v.x=0; + //r.x=-r.x; v.x=-v.x; //r.y=0; v.y=0; //r.z=0; v.z=0; //add_atom(&md,SI,M_SI,0, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - // ATOM_ATTR_2BP, + // ATOM_ATTR_2BP|ATOM_ATTR_HB, // &r,&v); /* setting a nearest neighbour distance for the moldyn checks */ @@ -153,21 +157,22 @@ int main(int argc,char **argv) { printf("[sic] set p/t scaling\n"); //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0, // T_SCALE_BERENDSEN,100.0); - set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); + //set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); + //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0,0,0); /* initial thermal fluctuations of particles (in equilibrium) */ printf("[sic] thermal init\n"); - //thermal_init(&md,TRUE); + thermal_init(&md,TRUE); /* create the simulation schedule */ printf("[sic] adding schedule\n"); - moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,10001,1.0); /* activate logging */ printf("[sic] activate logging\n"); moldyn_set_log_dir(&md,argv[1]); - moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); - moldyn_set_log(&md,VISUAL_STEP,1); + moldyn_set_log(&md,LOG_TOTAL_ENERGY,10); + moldyn_set_log(&md,VISUAL_STEP,100); /* * let's do the actual md algorithm now -- 2.20.1 From 9f6af2cd82a72451741b68ca333f94c6c1d2eec5 Mon Sep 17 00:00:00 2001 From: hackbard Date: Mon, 15 Jan 2007 16:04:15 +0000 Subject: [PATCH 04/16] cleaning + set hook function --- moldyn.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++----- moldyn.h | 6 ++++-- run | 2 +- sic.c | 59 ++++++++++++++++++++++++++++---------------------------- 4 files changed, 85 insertions(+), 38 deletions(-) diff --git a/moldyn.c b/moldyn.c index d33de02..9db5cd9 100644 --- a/moldyn.c +++ b/moldyn.c @@ -19,6 +19,8 @@ int moldyn_init(t_moldyn *moldyn,int argc,char **argv) { + printf("[moldyn] init\n"); + memset(moldyn,0,sizeof(t_moldyn)); rand_init(&(moldyn->random),NULL,1); @@ -30,6 +32,7 @@ int moldyn_init(t_moldyn *moldyn,int argc,char **argv) { int moldyn_shutdown(t_moldyn *moldyn) { printf("[moldyn] shutdown\n"); + moldyn_log_shutdown(moldyn); link_cell_shutdown(moldyn); rand_close(&(moldyn->random)); @@ -40,12 +43,16 @@ int moldyn_shutdown(t_moldyn *moldyn) { int set_int_alg(t_moldyn *moldyn,u8 algo) { + printf("[moldyn] integration algorithm: "); + switch(algo) { case MOLDYN_INTEGRATE_VERLET: moldyn->integrate=velocity_verlet; + printf("velocity verlet\n"); break; default: printf("unknown integration algorithm: %02x\n",algo); + printf("unknown\n"); return -1; } @@ -56,6 +63,8 @@ int set_cutoff(t_moldyn *moldyn,double cutoff) { moldyn->cutoff=cutoff; + printf("[moldyn] cutoff [A]: %f\n",moldyn->cutoff); + return 0; } @@ -63,6 +72,8 @@ int set_temperature(t_moldyn *moldyn,double t_ref) { moldyn->t_ref=t_ref; + printf("[moldyn] temperature: %f\n",moldyn->t_ref); + return 0; } @@ -70,6 +81,8 @@ int set_pressure(t_moldyn *moldyn,double p_ref) { moldyn->p_ref=p_ref; + printf("[moldyn] pressure: %f\n",moldyn->p_ref); + return 0; } @@ -79,6 +92,18 @@ int set_pt_scale(t_moldyn *moldyn,u8 ptype,double ptc,u8 ttype,double ttc) { moldyn->t_tc=ttc; moldyn->p_tc=ptc; + printf("[moldyn] p/t scaling:\n"); + + printf(" p: %s",ptype?"yes":"no "); + if(ptype) + printf(" | type: %02x | factor: %f",ptype,ptc); + printf("\n"); + + printf(" t: %s",ttype?"yes":"no "); + if(ttype) + printf(" | type: %02x | factor: %f",ttype,ttc); + printf("\n"); + return 0; } @@ -101,7 +126,7 @@ int set_dim(t_moldyn *moldyn,double x,double y,double z,u8 visualize) { printf(" y: %f\n",moldyn->dim.y); printf(" z: %f\n",moldyn->dim.z); printf(" volume: %f\n",moldyn->volume); - printf(" visualize simulation box: %s\n",visualize?"on":"off"); + printf(" visualize simulation box: %s\n",visualize?"yes":"no"); return 0; } @@ -115,6 +140,8 @@ int set_nn_dist(t_moldyn *moldyn,double dist) { int set_pbc(t_moldyn *moldyn,u8 x,u8 y,u8 z) { + printf("[moldyn] periodic boundary conditions:\n"); + if(x) moldyn->status|=MOLDYN_STAT_PBX; @@ -124,6 +151,10 @@ int set_pbc(t_moldyn *moldyn,u8 x,u8 y,u8 z) { if(z) moldyn->status|=MOLDYN_STAT_PBZ; + printf(" x: %s\n",x?"yes":"no"); + printf(" y: %s\n",y?"yes":"no"); + printf(" z: %s\n",z?"yes":"no"); + return 0; } @@ -171,6 +202,8 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { char filename[128]; int ret; + printf("[moldyn] set log: "); + switch(type) { case LOG_TOTAL_ENERGY: moldyn->ewrite=timer; @@ -183,6 +216,7 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { return moldyn->efd; } dprintf(moldyn->efd,"# total energy log file\n"); + printf("total energy (%d)\n",timer); break; case LOG_TOTAL_MOMENTUM: moldyn->mwrite=timer; @@ -195,9 +229,11 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { return moldyn->mfd; } dprintf(moldyn->efd,"# total momentum log file\n"); + printf("total momentum (%d)\n",timer); break; case SAVE_STEP: moldyn->swrite=timer; + printf("save file (%d)\n",timer); break; case VISUAL_STEP: moldyn->vwrite=timer; @@ -206,9 +242,10 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { printf("[moldyn] visual init failure\n"); return ret; } + printf("visual file (%d)\n",timer); break; default: - printf("[moldyn] unknown log mechanism: %02x\n",type); + printf("unknown log type: %02x\n",type); return -1; } @@ -429,6 +466,8 @@ int thermal_init(t_moldyn *moldyn,u8 equi_init) { atom=moldyn->atom; random=&(moldyn->random); + printf("[moldyn] thermal init (equi init: %s)\n",equi_init?"yes":"no"); + /* gaussian distribution of velocities */ v3_zero(&p_total); for(i=0;icount;i++) { @@ -846,10 +885,14 @@ int moldyn_add_schedule(t_moldyn *moldyn,int runs,double tau) { schedule->tau=ptr; schedule->tau[count-1]=tau; + printf("[moldyn] schedule added:\n"); + printf(" number: %d | runs: %d | tau: %f\n",count-1,runs,tau); + + return 0; } -int moldyn_set_schedule_hook(t_moldyn *moldyn,void *hook,void *hook_params) { +int moldyn_set_schedule_hook(t_moldyn *moldyn,set_hook hook,void *hook_params) { moldyn->schedule.hook=hook; moldyn->schedule.hook_params=hook_params; @@ -912,6 +955,9 @@ int moldyn_integrate(t_moldyn *moldyn) { /* debugging, ignore */ moldyn->debug=0; + /* tell the world */ + printf("[moldyn] integration start, go get a coffee ...\n"); + /* executing the schedule */ for(sched->count=0;sched->counttotal_sched;sched->count++) { @@ -1199,9 +1245,9 @@ printf("\n\n"); for(i=0;ivt2-=v3_scalar_product(&(itom[i].r),&(itom[i].f)); -printf("compare: vt1: %f vt2: %f\n",moldyn->vt1,moldyn->vt2); +//printf("compare: vt1: %f vt2: %f\n",moldyn->vt1,moldyn->vt2); -pressure_calc(moldyn); +//pressure_calc(moldyn); return 0; } diff --git a/moldyn.h b/moldyn.h index c5cc064..8254568 100644 --- a/moldyn.h +++ b/moldyn.h @@ -71,7 +71,7 @@ typedef struct s_moldyn_schedule { int total_sched; int *runs; double *tau; - int (*hook)(void *moldyn,void *hook); + int (*hook)(void *moldyn,void *hook_params); void *hook_params; } t_moldyn_schedule; @@ -422,8 +422,10 @@ int link_cell_update(t_moldyn *moldyn); int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,t_list *cell); int link_cell_shutdown(t_moldyn *moldyn); +typedef int (*set_hook)(void *,void *); + int moldyn_add_schedule(t_moldyn *moldyn,int runs,double tau); -int moldyn_set_schedule_hook(t_moldyn *moldyn,void *hook,void *hook_params); +int moldyn_set_schedule_hook(t_moldyn *moldyn,set_hook hook,void *hook_params); int moldyn_integrate(t_moldyn *moldyn); int velocity_verlet(t_moldyn *moldyn); diff --git a/run b/run index 5a3a768..5a20df0 100755 --- a/run +++ b/run @@ -1,4 +1,4 @@ -mkdir -p saves video +[ ! -d $1 ] && mkdir $1 ./clean $1 ./sic $@ if [ "$?" == "0" ]; then diff --git a/sic.c b/sic.c index e2e8626..a890270 100644 --- a/sic.c +++ b/sic.c @@ -11,6 +11,18 @@ #include "posic.h" +int hook(void *moldyn,void *hook_params) { + + t_moldyn *md; + + md=moldyn; + + /* decrease temperature in every hook */ + set_temperature(md,md->t_ref-100.0); + + return 0; +} + int main(int argc,char **argv) { /* check argv */ @@ -27,25 +39,16 @@ int main(int argc,char **argv) { t_ho_params ho; t_tersoff_mult_params tp; - /* misc parameters */ - double tau; - /* testing location & velocity vector */ t_3dvec r,v; - /* values */ - tau=1.0e-15; /* delta t = 1 fs */ - /* initialize moldyn */ - printf("[sic] moldyn init\n"); moldyn_init(&md,argc,argv); /* choose integration algorithm */ - printf("[sic] setting integration algorithm\n"); set_int_alg(&md,MOLDYN_INTEGRATE_VERLET); /* choose potential */ - printf("[sic] selecting potential\n"); //set_potential1b(&md,tersoff_mult_1bp,&tp); //set_potential2b(&md,tersoff_mult_2bp,&tp); //set_potential2b_post(&md,tersoff_mult_post_2bp,&tp); @@ -54,9 +57,8 @@ int main(int argc,char **argv) { //set_potential2b(&md,harmonic_oscillator,&ho); /* cutoff radius */ - printf("[sic] setting cutoff radius\n"); //set_cutoff(&md,TM_S_SI); - set_cutoff(&md,3*LC_SI); + set_cutoff(&md,2*LC_SI); /* * potential parameters @@ -105,19 +107,16 @@ int main(int argc,char **argv) { tersoff_mult_complete_params(&tp); /* set (initial) dimensions of simulation volume */ - printf("[sic] setting dimensions\n"); - set_dim(&md,10*LC_SI,10*LC_SI,10*LC_SI,TRUE); + set_dim(&md,6*LC_SI,6*LC_SI,6*LC_SI,TRUE); /* set periodic boundary conditions in all directions */ - printf("[sic] setting periodic boundary conditions\n"); set_pbc(&md,TRUE,TRUE,TRUE); /* create the lattice / place atoms */ - printf("[sic] creating atoms\n"); create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, ATOM_ATTR_2BP|ATOM_ATTR_HB, - 0,10,10,10); + 0,6,6,6); moldyn_bc_check(&md); /* testing configuration */ @@ -141,7 +140,6 @@ int main(int argc,char **argv) { set_nn_dist(&md,0.25*sqrt(3.0)*LC_SI); /* diamond ! */ /* set temperature */ - printf("[sic] setting temperature -> %f\n",273+atof(argv[2])); //set_temperature(&md,273.0+1410.0); //set_temperature(&md,273.0+450.0); //set_temperature(&md,273.0); @@ -150,42 +148,43 @@ int main(int argc,char **argv) { set_temperature(&md,atof(argv[2])+273.0); /* set pressure */ - printf("[sic] setting pressure\n"); set_pressure(&md,ATM); /* set p/t scaling */ - printf("[sic] set p/t scaling\n"); //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0, // T_SCALE_BERENDSEN,100.0); - //set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); + set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0,0,0); /* initial thermal fluctuations of particles (in equilibrium) */ - printf("[sic] thermal init\n"); thermal_init(&md,TRUE); /* create the simulation schedule */ - printf("[sic] adding schedule\n"); - moldyn_add_schedule(&md,10001,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,100,1.0); + + /* schedule hook function */ + moldyn_set_schedule_hook(&md,&hook,NULL); /* activate logging */ - printf("[sic] activate logging\n"); moldyn_set_log_dir(&md,argv[1]); - moldyn_set_log(&md,LOG_TOTAL_ENERGY,10); - moldyn_set_log(&md,VISUAL_STEP,100); + moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); + moldyn_set_log(&md,VISUAL_STEP,10); /* * let's do the actual md algorithm now * * integration of newtons equations */ - - printf("[sic] integration start, go get a coffee ...\n"); moldyn_integrate(&md); /* close */ - - printf("[sic] shutdown\n"); moldyn_shutdown(&md); return 0; -- 2.20.1 From fb951c04e522e4637618bf622fc67194c2a7b15f Mon Sep 17 00:00:00 2001 From: hackbard Date: Wed, 17 Jan 2007 17:33:16 +0000 Subject: [PATCH 05/16] ... --- clean | 3 +- moldyn.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++--------- moldyn.h | 7 +- sic.c | 29 +++++---- 4 files changed, 185 insertions(+), 44 deletions(-) diff --git a/clean b/clean index ca57788..1f359db 100755 --- a/clean +++ b/clean @@ -1 +1,2 @@ -rm -f $1/* > /dev/null 2>&1 +rm -rf $1 +mkdir -p $1 diff --git a/moldyn.c b/moldyn.c index 9db5cd9..94d596e 100644 --- a/moldyn.c +++ b/moldyn.c @@ -121,12 +121,15 @@ int set_dim(t_moldyn *moldyn,double x,double y,double z,u8 visualize) { moldyn->vis.dim.z=z; } + moldyn->dv=0.0001*moldyn->volume; + printf("[moldyn] dimensions in A and A^3 respectively:\n"); printf(" x: %f\n",moldyn->dim.x); printf(" y: %f\n",moldyn->dim.y); printf(" z: %f\n",moldyn->dim.z); printf(" volume: %f\n",moldyn->volume); printf(" visualize simulation box: %s\n",visualize?"yes":"no"); + printf(" delta volume (pressure calc): %f\n",moldyn->dv); return 0; } @@ -279,6 +282,7 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, count=moldyn->count; /* how many atoms do we expect */ + if(type==CUBIC) new*=1; if(type==FCC) new*=4; if(type==DIAMOND) new*=8; @@ -294,6 +298,9 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, v3_zero(&origin); switch(type) { + case CUBIC: + ret=cubic_init(a,b,c,atom,&origin); + break; case FCC: ret=fcc_init(a,b,c,lc,atom,&origin); break; @@ -329,6 +336,15 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, return ret; } +/* cubic init */ +int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { + + int count; + t_3dvec r + +HIER WEITER ! +} + /* fcc lattice init */ int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { @@ -507,6 +523,7 @@ double temperature_calc(t_moldyn *moldyn) { atom=moldyn->atom; + double_ekin=0; for(i=0;icount;i++) double_ekin+=atom[i].mass*v3_absolute_square(&(atom[i].v)); @@ -577,34 +594,153 @@ int scale_velocity(t_moldyn *moldyn,u8 equi_init) { return 0; } +double ideal_gas_law_pressure(t_moldyn *moldyn) { + + double p; + + p=moldyn->count*moldyn->t*K_BOLTZMANN/moldyn->volume; +printf("temp = %f => ideal gas law pressure: %f\n",moldyn->t,p/ATM); + + return p; +} + double pressure_calc(t_moldyn *moldyn) { int i; - t_atom *atom; - double p1,p2,p=0; - - for(i=0;icount;i++) { - + double p1,p; + double v,h; + t_virial *virial; + v=0.0; + for(i=0;icount;i++) { + virial=&(moldyn->atom[i].virial); + v+=(virial->xx+virial->yy+virial->zz); } + h=moldyn->count*K_BOLTZMANN*moldyn->t; + + p=(h-ONE_THIRD*v); + p/=moldyn->volume; + p1=(moldyn->count*K_BOLTZMANN*moldyn->t-ONE_THIRD*moldyn->vt1); p1/=moldyn->volume; - p2=(moldyn->count*K_BOLTZMANN*moldyn->t-ONE_THIRD*moldyn->vt2); - p2/=moldyn->volume; + printf("debug: vt1=%f v=%f nkt=%f\n",moldyn->vt1,v,h); - printf("compare pressures: %f %f\n",p1/ATM,p2/ATM); + printf("compare pressures: %f %f %f\n",p1/ATM,p/ATM,h/moldyn->volume/ATM); return moldyn->p; } +double thermodynamic_pressure_calc(t_moldyn *moldyn) { + + t_3dvec dim,*tp; + double u,p; + double scale; + t_atom *store; + + tp=&(moldyn->tp); + store=malloc(moldyn->count*sizeof(t_atom)); + if(store==NULL) { + printf("[moldyn] allocating store mem failed\n"); + return -1; + } + + /* save unscaled potential energy + atom/dim configuration */ + u=moldyn->energy; + memcpy(store,moldyn->atom,moldyn->count*sizeof(t_atom)); + dim=moldyn->dim; + + /* derivative with respect to x direction */ + scale=1.0+moldyn->dv/(moldyn->dim.y*moldyn->dim.z); + scale_dim(moldyn,scale,TRUE,0,0); + scale_atoms(moldyn,scale,TRUE,0,0); + potential_force_calc(moldyn); + tp->x=(moldyn->energy-u)/moldyn->dv; + p=tp->x*tp->x; + + /* restore atomic configuration + dim */ + memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); + moldyn->dim=dim; + + /* derivative with respect to y direction */ + scale=1.0+moldyn->dv/(moldyn->dim.x*moldyn->dim.z); + scale_dim(moldyn,scale,0,TRUE,0); + scale_atoms(moldyn,scale,0,TRUE,0); + potential_force_calc(moldyn); + tp->y=(moldyn->energy-u)/moldyn->dv; + p+=tp->y*tp->y; + + /* restore atomic configuration + dim */ + memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); + moldyn->dim=dim; + + /* derivative with respect to z direction */ + scale=1.0+moldyn->dv/(moldyn->dim.x*moldyn->dim.y); + scale_dim(moldyn,scale,0,0,TRUE); + scale_atoms(moldyn,scale,0,0,TRUE); + potential_force_calc(moldyn); + tp->z=(moldyn->energy-u)/moldyn->dv; + p+=tp->z*tp->z; + + /* restore atomic configuration + dim */ + memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); + moldyn->dim=dim; + + printf("dU/dV komp addiert = %f\n",(tp->x+tp->y+tp->z)/ATM); + + scale=1.0+pow(moldyn->dv/moldyn->volume,ONE_THIRD); + + scale_dim(moldyn,scale,1,1,1); + scale_dim(moldyn,scale,1,1,1); + potential_force_calc(moldyn); + + printf("dU/dV einfach = %f\n",(moldyn->energy-u)/moldyn->dv/ATM); + + /* restore atomic configuration + dim */ + memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); + moldyn->dim=dim; + + /* restore energy */ + moldyn->energy=u; + + return sqrt(p); +} + double get_pressure(t_moldyn *moldyn) { return moldyn->p; } +int scale_dim(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z) { + + t_3dvec *dim; + + dim=&(moldyn->dim); + + if(x) dim->x*=scale; + if(y) dim->y*=scale; + if(z) dim->z*=scale; + + return 0; +} + +int scale_atoms(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z) { + + int i; + t_3dvec *r; + + for(i=0;icount;i++) { + r=&(moldyn->atom[i].r); + if(x) r->x*=scale; + if(y) r->y*=scale; + if(z) r->z*=scale; + } + + return 0; +} + int scale_volume(t_moldyn *moldyn) { t_atom *atom; @@ -979,22 +1115,17 @@ int moldyn_integrate(t_moldyn *moldyn) { if(moldyn->pt_scale&(P_SCALE_BERENDSEN|P_SCALE_DIRECT)) scale_volume(moldyn); +printf("-> %f\n",thermodynamic_pressure_calc(moldyn)/ATM); + /* check for log & visualization */ -//double ax; -//double ao; -//double av; if(e) { if(!(i%e)) -//ao=sqrt(0.1/M_SI); -//ax=((0.28-0.25)*sqrt(3)*LC_SI/2)*cos(ao*i); -//av=ao*(0.28-0.25)*sqrt(3)*LC_SI/2*sin(ao*i); update_e_kin(moldyn); dprintf(moldyn->efd, "%f %f %f %f\n", moldyn->time,moldyn->ekin, moldyn->energy, get_total_energy(moldyn)); -//moldyn->atom[0].r.x,ax,av*av*M_SI,0.1*ax*ax,av*av*M_SI+0.1*ax*ax); } if(m) { if(!(i%m)) { @@ -1115,27 +1246,32 @@ int potential_force_calc(t_moldyn *moldyn) { /* reset energy */ moldyn->energy=0.0; - moldyn->vt2=0.0; - - /* get energy and force of every atom */ + /* reset virial */ + moldyn->vt1=0.0; + + /* reset force, site energy and virial of every atom */ for(i=0;ixx=0.0; virial->yy=0.0; virial->zz=0.0; virial->xy=0.0; virial->xz=0.0; virial->yz=0.0; - moldyn->vt1=0.0; - + /* reset site energy */ itom[i].e=0.0; + } + + /* get energy,force and virial of every atom */ + for(i=0;ifunc1b(moldyn,&(itom[i])); @@ -1241,13 +1377,9 @@ printf("\n\n"); printf("\n\n"); #endif - moldyn->vt2=0.0; - for(i=0;ivt2-=v3_scalar_product(&(itom[i].r),&(itom[i].f)); - -//printf("compare: vt1: %f vt2: %f\n",moldyn->vt1,moldyn->vt2); - -//pressure_calc(moldyn); +temperature_calc(moldyn); +pressure_calc(moldyn); +ideal_gas_law_pressure(moldyn); return 0; } diff --git a/moldyn.h b/moldyn.h index 8254568..c910d7f 100644 --- a/moldyn.h +++ b/moldyn.h @@ -105,7 +105,9 @@ typedef struct s_moldyn { double t; /* actual temperature */ double p_ref; /* reference pressure */ - double p; /* actual pressure */ + double p; /* actual pressure (computed by virial) */ + t_3dvec tp; /* thermodynamic pressure dU/dV */ + double dv; /* dV for thermodynamic pressure calc */ /* pressure and temperature control (velocity/volume scaling) */ /* (t_tc in units of tau, p_tc in units of tau * isoth. compressib.) */ @@ -407,8 +409,11 @@ double temperature_calc(t_moldyn *moldyn); double get_temperature(t_moldyn *moldyn); int scale_velocity(t_moldyn *moldyn,u8 equi_init); double pressure_calc(t_moldyn *moldyn); +double thermodynamic_pressure_calc(t_moldyn *moldyn); double get_pressure(t_moldyn *moldyn); int scale_volume(t_moldyn *moldyn); +int scale_dim(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z); +int scale_atoms(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z); double get_e_kin(t_moldyn *moldyn); double update_e_kin(t_moldyn *moldyn); diff --git a/sic.c b/sic.c index a890270..5cfbb03 100644 --- a/sic.c +++ b/sic.c @@ -17,8 +17,16 @@ int hook(void *moldyn,void *hook_params) { md=moldyn; - /* decrease temperature in every hook */ - set_temperature(md,md->t_ref-100.0); + /* switch to direct scaling in first hook */ + if(md->schedule.count==0) + set_pt_scale(md,0,0,T_SCALE_BERENDSEN,100.0); + /* switch off temp scaling in second hook */ + if(md->schedule.count==1) + set_pt_scale(md,0,0,0,0); + + + //set_temperature(md,md->t_ref-100.0); + return 0; } @@ -153,29 +161,24 @@ int main(int argc,char **argv) { /* set p/t scaling */ //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0, // T_SCALE_BERENDSEN,100.0); - set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0); + set_pt_scale(&md,0,0,T_SCALE_DIRECT,1.0); //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0,0,0); /* initial thermal fluctuations of particles (in equilibrium) */ thermal_init(&md,TRUE); /* create the simulation schedule */ - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); - moldyn_add_schedule(&md,100,1.0); + moldyn_add_schedule(&md,1001,3.0); + moldyn_add_schedule(&md,501,1.0); + moldyn_add_schedule(&md,501,1.0); /* schedule hook function */ moldyn_set_schedule_hook(&md,&hook,NULL); /* activate logging */ moldyn_set_log_dir(&md,argv[1]); - moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); - moldyn_set_log(&md,VISUAL_STEP,10); + moldyn_set_log(&md,LOG_TOTAL_ENERGY,5); + moldyn_set_log(&md,VISUAL_STEP,50); /* * let's do the actual md algorithm now -- 2.20.1 From f3e4193447ac49a8953515910d4b4e6ce2c7608b Mon Sep 17 00:00:00 2001 From: hackbard Date: Tue, 23 Jan 2007 16:36:18 +0000 Subject: [PATCH 06/16] added report system, still messing around with virial pressure --- clean | 2 +- moldyn.c | 160 +++++++++++++++++++++++++++++++++++------------- moldyn.h | 15 +++-- report/report.h | 64 +++++++++++++++++++ sic.c | 27 ++++---- visual/visual.c | 2 +- 6 files changed, 209 insertions(+), 61 deletions(-) create mode 100644 report/report.h diff --git a/clean b/clean index 1f359db..e702e9e 100755 --- a/clean +++ b/clean @@ -1,2 +1,2 @@ -rm -rf $1 +rm -rf $1/* mkdir -p $1 diff --git a/moldyn.c b/moldyn.c index 94d596e..817a727 100644 --- a/moldyn.c +++ b/moldyn.c @@ -121,7 +121,7 @@ int set_dim(t_moldyn *moldyn,double x,double y,double z,u8 visualize) { moldyn->vis.dim.z=z; } - moldyn->dv=0.0001*moldyn->volume; + moldyn->dv=0.000001*moldyn->volume; printf("[moldyn] dimensions in A and A^3 respectively:\n"); printf(" x: %f\n",moldyn->dim.x); @@ -199,6 +199,14 @@ int moldyn_set_log_dir(t_moldyn *moldyn,char *dir) { return 0; } + +int moldyn_set_report(t_moldyn *moldyn,char *author,char *title) { + + strncpy(moldyn->rauthor,author,63); + strncpy(moldyn->rtitle,title,63); + + return 0; +} int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { @@ -247,6 +255,28 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { } printf("visual file (%d)\n",timer); break; + case CREATE_REPORT: + snprintf(filename,127,"%s/report.tex",moldyn->vlsdir); + moldyn->rfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->rfd<0) { + perror("[moldyn] report fd open"); + return moldyn->rfd; + } + snprintf(filename,127,"%s/plot.scr",moldyn->vlsdir); + moldyn->pfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->pfd<0) { + perror("[moldyn] plot fd open"); + return moldyn->pfd; + } + dprintf(moldyn->rfd,report_start, + moldyn->rauthor,moldyn->rtitle); + dprintf(moldyn->pfd,plot_script); + close(moldyn->pfd); + break; default: printf("unknown log type: %02x\n",type); return -1; @@ -257,9 +287,23 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { int moldyn_log_shutdown(t_moldyn *moldyn) { + char sc[256]; + printf("[moldyn] log shutdown\n"); if(moldyn->efd) close(moldyn->efd); if(moldyn->mfd) close(moldyn->mfd); + if(moldyn->rfd) { + dprintf(moldyn->rfd,report_end); + close(moldyn->rfd); + snprintf(sc,255,"cd %s && gnuplot plot.scr",moldyn->vlsdir); + system(sc); + snprintf(sc,255,"cd %s && pdflatex report",moldyn->vlsdir); + system(sc); + snprintf(sc,255,"cd %s && pdflatex report",moldyn->vlsdir); + system(sc); + snprintf(sc,255,"cd %s && dvipdf report",moldyn->vlsdir); + system(sc); + } if(&(moldyn->vis)) visual_tini(&(moldyn->vis)); return 0; @@ -299,10 +343,10 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, switch(type) { case CUBIC: - ret=cubic_init(a,b,c,atom,&origin); + ret=cubic_init(a,b,c,lc,atom,NULL); break; case FCC: - ret=fcc_init(a,b,c,lc,atom,&origin); + ret=fcc_init(a,b,c,lc,atom,NULL); break; case DIAMOND: ret=diamond_init(a,b,c,lc,atom,&origin); @@ -340,9 +384,38 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { int count; - t_3dvec r + t_3dvec r; + int i,j,k; + t_3dvec o; + + count=0; + if(origin) + v3_copy(&o,origin); + else + v3_zero(&o); -HIER WEITER ! + r.x=o.x; + for(i=0;icount*moldyn->t*K_BOLTZMANN/moldyn->volume; -printf("temp = %f => ideal gas law pressure: %f\n",moldyn->t,p/ATM); return p; } @@ -607,8 +679,7 @@ printf("temp = %f => ideal gas law pressure: %f\n",moldyn->t,p/ATM); double pressure_calc(t_moldyn *moldyn) { int i; - double p1,p; - double v,h; + double v; t_virial *virial; v=0.0; @@ -616,18 +687,11 @@ double pressure_calc(t_moldyn *moldyn) { virial=&(moldyn->atom[i].virial); v+=(virial->xx+virial->yy+virial->zz); } + v*=ONE_THIRD; +printf("kieck mal: %f %f %f\n",v,moldyn->count*K_BOLTZMANN*moldyn->t,v/moldyn->count); - h=moldyn->count*K_BOLTZMANN*moldyn->t; - - p=(h-ONE_THIRD*v); - p/=moldyn->volume; - - p1=(moldyn->count*K_BOLTZMANN*moldyn->t-ONE_THIRD*moldyn->vt1); - p1/=moldyn->volume; - - printf("debug: vt1=%f v=%f nkt=%f\n",moldyn->vt1,v,h); - - printf("compare pressures: %f %f %f\n",p1/ATM,p/ATM,h/moldyn->volume/ATM); + moldyn->p=moldyn->count*K_BOLTZMANN*moldyn->t+v; + moldyn->p/=moldyn->volume; return moldyn->p; } @@ -655,6 +719,8 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { scale=1.0+moldyn->dv/(moldyn->dim.y*moldyn->dim.z); scale_dim(moldyn,scale,TRUE,0,0); scale_atoms(moldyn,scale,TRUE,0,0); + link_cell_shutdown(moldyn); + link_cell_init(moldyn); potential_force_calc(moldyn); tp->x=(moldyn->energy-u)/moldyn->dv; p=tp->x*tp->x; @@ -667,6 +733,8 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { scale=1.0+moldyn->dv/(moldyn->dim.x*moldyn->dim.z); scale_dim(moldyn,scale,0,TRUE,0); scale_atoms(moldyn,scale,0,TRUE,0); + link_cell_shutdown(moldyn); + link_cell_init(moldyn); potential_force_calc(moldyn); tp->y=(moldyn->energy-u)/moldyn->dv; p+=tp->y*tp->y; @@ -679,6 +747,8 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { scale=1.0+moldyn->dv/(moldyn->dim.x*moldyn->dim.y); scale_dim(moldyn,scale,0,0,TRUE); scale_atoms(moldyn,scale,0,0,TRUE); + link_cell_shutdown(moldyn); + link_cell_init(moldyn); potential_force_calc(moldyn); tp->z=(moldyn->energy-u)/moldyn->dv; p+=tp->z*tp->z; @@ -687,15 +757,19 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); moldyn->dim=dim; - printf("dU/dV komp addiert = %f\n",(tp->x+tp->y+tp->z)/ATM); + printf("dU/dV komp addiert = %f %f %f\n",tp->x,tp->y,tp->z); scale=1.0+pow(moldyn->dv/moldyn->volume,ONE_THIRD); +printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); scale_dim(moldyn,scale,1,1,1); - scale_dim(moldyn,scale,1,1,1); + scale_atoms(moldyn,scale,1,1,1); + link_cell_shutdown(moldyn); + link_cell_init(moldyn); potential_force_calc(moldyn); +printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); - printf("dU/dV einfach = %f\n",(moldyn->energy-u)/moldyn->dv/ATM); + printf("dU/dV einfach = %f\n",((moldyn->energy-u)/moldyn->dv)/ATM); /* restore atomic configuration + dim */ memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); @@ -704,6 +778,9 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { /* restore energy */ moldyn->energy=u; + link_cell_shutdown(moldyn); + link_cell_init(moldyn); + return sqrt(p); } @@ -1054,6 +1131,7 @@ int moldyn_integrate(t_moldyn *moldyn) { int fd; char dir[128]; double ds; + double energy_scale; sched=&(moldyn->schedule); atom=moldyn->atom; @@ -1071,6 +1149,9 @@ int moldyn_integrate(t_moldyn *moldyn) { moldyn->tau_square=moldyn->tau*moldyn->tau; moldyn->cutoff_square=moldyn->cutoff*moldyn->cutoff; + /* energy scaling factor */ + energy_scale=moldyn->count*EV; + /* calculate initial forces */ potential_force_calc(moldyn); @@ -1115,7 +1196,9 @@ int moldyn_integrate(t_moldyn *moldyn) { if(moldyn->pt_scale&(P_SCALE_BERENDSEN|P_SCALE_DIRECT)) scale_volume(moldyn); -printf("-> %f\n",thermodynamic_pressure_calc(moldyn)/ATM); + temperature_calc(moldyn); + pressure_calc(moldyn); + //thermodynamic_pressure_calc(moldyn); /* check for log & visualization */ if(e) { @@ -1123,9 +1206,9 @@ printf("-> %f\n",thermodynamic_pressure_calc(moldyn)/ATM); update_e_kin(moldyn); dprintf(moldyn->efd, "%f %f %f %f\n", - moldyn->time,moldyn->ekin, - moldyn->energy, - get_total_energy(moldyn)); + moldyn->time,moldyn->ekin/energy_scale, + moldyn->energy/energy_scale, + get_total_energy(moldyn)/energy_scale); } if(m) { if(!(i%m)) { @@ -1152,8 +1235,8 @@ printf("-> %f\n",thermodynamic_pressure_calc(moldyn)/ATM); if(!(i%v)) { visual_atoms(&(moldyn->vis),moldyn->time, moldyn->atom,moldyn->count); - printf("\rsched: %d, steps: %d, debug: %d", - sched->count,i,moldyn->debug); + printf("\rsched: %d, steps: %d, debug: %f | %f", + sched->count,i,moldyn->p/ATM,moldyn->debug/ATM); fflush(stdout); } } @@ -1246,9 +1329,6 @@ int potential_force_calc(t_moldyn *moldyn) { /* reset energy */ moldyn->energy=0.0; - /* reset virial */ - moldyn->vt1=0.0; - /* reset force, site energy and virial of every atom */ for(i=0;ivirial.xx-=f->x*d->x; - a->virial.yy-=f->y*d->y; - a->virial.zz-=f->z*d->z; - a->virial.xy-=f->x*d->y; - a->virial.xz-=f->x*d->z; - a->virial.yz-=f->y*d->z; + a->virial.xx+=f->x*d->x; + a->virial.yy+=f->y*d->y; + a->virial.zz+=f->z*d->z; + a->virial.xy+=f->x*d->y; + a->virial.xz+=f->x*d->z; + a->virial.yz+=f->y*d->z; return 0; } @@ -1507,7 +1584,6 @@ int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { v3_add(&(ai->f),&(ai->f),&force); virial_calc(ai,&force,&distance); virial_calc(aj,&force,&distance); /* f and d signe switched */ - moldyn->vt1-=v3_scalar_product(&force,&distance); } return 0; diff --git a/moldyn.h b/moldyn.h index c910d7f..7329099 100644 --- a/moldyn.h +++ b/moldyn.h @@ -12,6 +12,7 @@ #include "random/random.h" #include "list/list.h" +#include "report/report.h" /* * @@ -82,7 +83,6 @@ typedef struct s_moldyn { t_3dvec dim; /* dimensions of the simulation volume */ double volume; /* volume of sim cell (dim.x*dim.y*dim.z) */ - double vt1,vt2; /* potential force function and parameter pointers */ int (*func1b)(struct s_moldyn *moldyn,t_atom *ai); @@ -139,6 +139,10 @@ typedef struct s_moldyn { int mfd; /* fd for momentum log */ unsigned int vwrite; /* how often to visualize atom information */ unsigned int swrite; /* how often to create a save file */ + int rfd; /* report file descriptor */ + char rtitle[64]; /* report title */ + char rauthor[64]; /* report author */ + int pfd; /* gnuplot script file descriptor */ u8 status; /* general moldyn properties */ @@ -162,7 +166,6 @@ typedef struct s_moldyn { #define P_SCALE_BERENDSEN 0x04 /* berendsen p control */ #define P_SCALE_DIRECT 0x08 /* direct p control */ - /* * * potential parameter structures @@ -307,6 +310,7 @@ typedef struct s_tersoff_mult_params { #define LOG_TOTAL_MOMENTUM 0x02 #define SAVE_STEP 0x04 #define VISUAL_STEP 0x08 +#define CREATE_REPORT 0x10 #define TRUE 1 #define FALSE 0 @@ -361,8 +365,9 @@ typedef struct s_tersoff_mult_params { * lattice constants */ -#define FCC 0x01 -#define DIAMOND 0x02 +#define CUBIC 0x01 +#define FCC 0x02 +#define DIAMOND 0x04 /* @@ -393,11 +398,13 @@ int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func,void *params); int set_potential3b(t_moldyn *moldyn,pf_func3b func,void *params); int moldyn_set_log_dir(t_moldyn *moldyn,char *dir); +int moldyn_set_report(t_moldyn *moldyn,char *author,char *title); int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer); int moldyn_log_shutdown(t_moldyn *moldyn); int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, u8 attr,u8 brand,int a,int b,int c); +int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin); int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin); int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin); int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr, diff --git a/report/report.h b/report/report.h new file mode 100644 index 0000000..7fd3180 --- /dev/null +++ b/report/report.h @@ -0,0 +1,64 @@ +/* + * report.h - header file of the report subsystem + * + * author: Frank Zirkelbach + * + */ + +#ifndef REPORT_H +#define REPORT_H + +static char report_start[]="\ +\\pdfoutput=0\n\ +\\documentclass[a4paper,11pt]{report}\n\ +\\usepackage[activate]{pdfcprot}\n\ +\\usepackage{verbatim}\n\ +\\usepackage{a4}\n\ +\\usepackage{a4wide}\n\ +\\usepackage[english,german]{babel}\n\ +\\usepackage[latin1]{inputenc}\n\ +\\usepackage[T1]{fontenc}\n\ +\\usepackage{amsmath}\n\ +\\usepackage{ae}\n\ +\\usepackage{aecompl}\n\ +\\usepackage[dvips]{graphicx}\n\ +\\graphicspath{{./}}\n\ +\\usepackage{color}\n\ +\\usepackage{pstricks}\n\ +\\usepackage{pst-node}\n\ +\\usepackage{rotating}\n\ +\\selectlanguage{english}\n\ +\\author{%s}\n\ +\\title{%s}\n\ +\\begin{document}\n\ +\\maketitle\n\ +"; + +static char report_end[]="\ +\\begin{figure}[!h]\n\ +\\begin{center}\n\ +\\includegraphics[width=10cm]{energy.eps}\n\ +\\caption{Kinetic, potential and total energy over time}\n\ +\\end{center}\n\ +\\end{figure}\n\ +\\end{document}\n\ +"; + +static char plot_script[]="\ +set autoscale \n\ +unset log \n\ +unset label \n\ +set xtic auto \n\ +set ytic auto \n\ +set title 'Energy vs. time' \n\ +set xlabel 'Time [fs]' \n\ +set ylabel 'Energy [eV]' \n\ +plot \"energy\" using 1:2 title 'Kinetic energy' with lines , \"energy\" using 1:3 title 'Potential energy' with lines , \"energy\" using 1:4 title 'Total energy' with lines \n\ +#set size 1.0, 0.6 \n\ +set terminal postscript eps enhanced color dashed lw 1 'Helvetica' 14 \n\ +set output 'energy.eps' \n\ +replot\ +"; + + +#endif diff --git a/sic.c b/sic.c index 5cfbb03..b5d4596 100644 --- a/sic.c +++ b/sic.c @@ -24,10 +24,8 @@ int hook(void *moldyn,void *hook_params) { if(md->schedule.count==1) set_pt_scale(md,0,0,0,0); - //set_temperature(md,md->t_ref-100.0); - return 0; } @@ -66,7 +64,7 @@ int main(int argc,char **argv) { /* cutoff radius */ //set_cutoff(&md,TM_S_SI); - set_cutoff(&md,2*LC_SI); + set_cutoff(&md,2*LC_SI*0.5*sqrt(1.5)); /* * potential parameters @@ -115,16 +113,17 @@ int main(int argc,char **argv) { tersoff_mult_complete_params(&tp); /* set (initial) dimensions of simulation volume */ - set_dim(&md,6*LC_SI,6*LC_SI,6*LC_SI,TRUE); + set_dim(&md,8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),TRUE); /* set periodic boundary conditions in all directions */ set_pbc(&md,TRUE,TRUE,TRUE); /* create the lattice / place atoms */ - create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, + create_lattice(&md,FCC,LC_SI*0.5*sqrt(1.5),SI,M_SI, + //create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, ATOM_ATTR_2BP|ATOM_ATTR_HB, - 0,6,6,6); + 0,8,8,8); moldyn_bc_check(&md); /* testing configuration */ @@ -161,24 +160,26 @@ int main(int argc,char **argv) { /* set p/t scaling */ //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0, // T_SCALE_BERENDSEN,100.0); - set_pt_scale(&md,0,0,T_SCALE_DIRECT,1.0); + //set_pt_scale(&md,0,0,T_SCALE_DIRECT,1.0); //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0,0,0); /* initial thermal fluctuations of particles (in equilibrium) */ thermal_init(&md,TRUE); /* create the simulation schedule */ - moldyn_add_schedule(&md,1001,3.0); - moldyn_add_schedule(&md,501,1.0); - moldyn_add_schedule(&md,501,1.0); + moldyn_add_schedule(&md,1001,1.0); + //moldyn_add_schedule(&md,501,1.0); + //moldyn_add_schedule(&md,501,1.0); /* schedule hook function */ - moldyn_set_schedule_hook(&md,&hook,NULL); + //moldyn_set_schedule_hook(&md,&hook,NULL); /* activate logging */ moldyn_set_log_dir(&md,argv[1]); - moldyn_set_log(&md,LOG_TOTAL_ENERGY,5); - moldyn_set_log(&md,VISUAL_STEP,50); + moldyn_set_report(&md,"Frank Zirkelbach","Test 1"); + moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); + moldyn_set_log(&md,VISUAL_STEP,10); + moldyn_set_log(&md,CREATE_REPORT,0); /* * let's do the actual md algorithm now diff --git a/visual/visual.c b/visual/visual.c index a6fda4f..a76c608 100644 --- a/visual/visual.c +++ b/visual/visual.c @@ -87,7 +87,7 @@ int visual_atoms(t_visual *v,double time,t_atom *atom,int n) { /* script file update */ dprintf(v->fd,"load xyz %s\n",file); - dprintf(v->fd,"spacefill 270\n"); + dprintf(v->fd,"spacefill 100\n"); dprintf(v->fd,"rotate x 100\n"); dprintf(v->fd,"rotate y 10\n"); dprintf(v->fd,"set ambient 20\n"); -- 2.20.1 From 4871747c5c848e5881bea7949a41ceb589263841 Mon Sep 17 00:00:00 2001 From: hackbard Date: Wed, 24 Jan 2007 17:47:05 +0000 Subject: [PATCH 07/16] still pressure (+ fixes with cubic lattce and ho potential ...) --- moldyn.c | 33 +++++++++++++++------------------ moldyn.h | 2 -- report/report.h | 11 ++++------- sic.c | 18 +++++++++++------- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/moldyn.c b/moldyn.c index 817a727..f564075 100644 --- a/moldyn.c +++ b/moldyn.c @@ -16,6 +16,7 @@ #include #include "moldyn.h" +#include "report/report.h" int moldyn_init(t_moldyn *moldyn,int argc,char **argv) { @@ -590,18 +591,9 @@ int thermal_init(t_moldyn *moldyn,u8 equi_init) { double temperature_calc(t_moldyn *moldyn) { - double double_ekin; - int i; - t_atom *atom; - - atom=moldyn->atom; - - double_ekin=0; - for(i=0;icount;i++) - double_ekin+=atom[i].mass*v3_absolute_square(&(atom[i].v)); + /* assume up to date kinetic energy, which is 3/2 N k_B T */ - /* kinetic energy = 3/2 N k_B T */ - moldyn->t=double_ekin/(3.0*K_BOLTZMANN*moldyn->count); + moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count); return moldyn->t; } @@ -682,16 +674,21 @@ double pressure_calc(t_moldyn *moldyn) { double v; t_virial *virial; + /* + * P = 1/(3V) sum_i ( p_i^2 / 2m + f_i r_i ) + * + * virial = f_i r_i + */ + v=0.0; for(i=0;icount;i++) { virial=&(moldyn->atom[i].virial); v+=(virial->xx+virial->yy+virial->zz); } - v*=ONE_THIRD; -printf("kieck mal: %f %f %f\n",v,moldyn->count*K_BOLTZMANN*moldyn->t,v/moldyn->count); - moldyn->p=moldyn->count*K_BOLTZMANN*moldyn->t+v; - moldyn->p/=moldyn->volume; + /* assume up to date kinetic energy */ + moldyn->p=2.0*moldyn->ekin+v; + moldyn->p/=(3.0*moldyn->volume); return moldyn->p; } @@ -1196,6 +1193,7 @@ int moldyn_integrate(t_moldyn *moldyn) { if(moldyn->pt_scale&(P_SCALE_BERENDSEN|P_SCALE_DIRECT)) scale_volume(moldyn); + update_e_kin(moldyn); temperature_calc(moldyn); pressure_calc(moldyn); //thermodynamic_pressure_calc(moldyn); @@ -1203,7 +1201,6 @@ int moldyn_integrate(t_moldyn *moldyn) { /* check for log & visualization */ if(e) { if(!(i%e)) - update_e_kin(moldyn); dprintf(moldyn->efd, "%f %f %f %f\n", moldyn->time,moldyn->ekin/energy_scale, @@ -1236,7 +1233,7 @@ int moldyn_integrate(t_moldyn *moldyn) { visual_atoms(&(moldyn->vis),moldyn->time, moldyn->atom,moldyn->count); printf("\rsched: %d, steps: %d, debug: %f | %f", - sched->count,i,moldyn->p/ATM,moldyn->debug/ATM); + sched->count,i,moldyn->p/ATM,moldyn->p/ATM); fflush(stdout); } } @@ -1580,7 +1577,7 @@ int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { d*=eps; v3_scale(&force,&distance,d); v3_add(&(aj->f),&(aj->f),&force); - v3_scale(&force,&distance,-1.0*d); /* f = - grad E */ + v3_scale(&force,&force,-1.0); /* f = - grad E */ v3_add(&(ai->f),&(ai->f),&force); virial_calc(ai,&force,&distance); virial_calc(aj,&force,&distance); /* f and d signe switched */ diff --git a/moldyn.h b/moldyn.h index 7329099..69cee96 100644 --- a/moldyn.h +++ b/moldyn.h @@ -12,8 +12,6 @@ #include "random/random.h" #include "list/list.h" -#include "report/report.h" - /* * * datatypes diff --git a/report/report.h b/report/report.h index 7fd3180..3868515 100644 --- a/report/report.h +++ b/report/report.h @@ -37,7 +37,7 @@ static char report_start[]="\ static char report_end[]="\ \\begin{figure}[!h]\n\ \\begin{center}\n\ -\\includegraphics[width=10cm]{energy.eps}\n\ +\\includegraphics[width=16cm]{energy.eps}\n\ \\caption{Kinetic, potential and total energy over time}\n\ \\end{center}\n\ \\end{figure}\n\ @@ -50,15 +50,12 @@ unset log \n\ unset label \n\ set xtic auto \n\ set ytic auto \n\ -set title 'Energy vs. time' \n\ +set title 'Energy per atom vs. time' \n\ set xlabel 'Time [fs]' \n\ -set ylabel 'Energy [eV]' \n\ -plot \"energy\" using 1:2 title 'Kinetic energy' with lines , \"energy\" using 1:3 title 'Potential energy' with lines , \"energy\" using 1:4 title 'Total energy' with lines \n\ -#set size 1.0, 0.6 \n\ +set ylabel 'Energy per atom [eV]' \n\ set terminal postscript eps enhanced color dashed lw 1 'Helvetica' 14 \n\ set output 'energy.eps' \n\ -replot\ +plot \"energy\" using 1:2 title 'Kinetic energy' with lines , \"energy\" using 1:3 title 'Potential energy' with lines , \"energy\" using 1:4 title 'Total energy' with lines\ "; - #endif diff --git a/sic.c b/sic.c index b5d4596..999d860 100644 --- a/sic.c +++ b/sic.c @@ -59,12 +59,13 @@ int main(int argc,char **argv) { //set_potential2b(&md,tersoff_mult_2bp,&tp); //set_potential2b_post(&md,tersoff_mult_post_2bp,&tp); //set_potential3b(&md,tersoff_mult_3bp,&tp); - set_potential2b(&md,lennard_jones,&lj); - //set_potential2b(&md,harmonic_oscillator,&ho); + //set_potential2b(&md,lennard_jones,&lj); + set_potential2b(&md,harmonic_oscillator,&ho); /* cutoff radius */ //set_cutoff(&md,TM_S_SI); - set_cutoff(&md,2*LC_SI*0.5*sqrt(1.5)); + //set_cutoff(&md,2*LC_SI*0.5*sqrt(1.5)); + set_cutoff(&md,1.1*LC_SI); /* * potential parameters @@ -78,7 +79,8 @@ int main(int argc,char **argv) { lj.uc=lj.epsilon4*(lj.sigma12/pow(md.cutoff,12.0)-lj.sigma6/pow(md.cutoff,6)); /* harmonic oscillator */ - ho.equilibrium_distance=0.25*sqrt(3.0)*LC_SI; + //ho.equilibrium_distance=0.25*sqrt(3.0)*LC_SI; + ho.equilibrium_distance=LC_SI; ho.spring_constant=.1; /* @@ -113,13 +115,14 @@ int main(int argc,char **argv) { tersoff_mult_complete_params(&tp); /* set (initial) dimensions of simulation volume */ - set_dim(&md,8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),TRUE); + //set_dim(&md,8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),TRUE); + set_dim(&md,8*LC_SI,8*LC_SI,8*LC_SI,TRUE); /* set periodic boundary conditions in all directions */ set_pbc(&md,TRUE,TRUE,TRUE); /* create the lattice / place atoms */ - create_lattice(&md,FCC,LC_SI*0.5*sqrt(1.5),SI,M_SI, + create_lattice(&md,CUBIC,LC_SI,SI,M_SI, //create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, ATOM_ATTR_2BP|ATOM_ATTR_HB, @@ -144,7 +147,8 @@ int main(int argc,char **argv) { // &r,&v); /* setting a nearest neighbour distance for the moldyn checks */ - set_nn_dist(&md,0.25*sqrt(3.0)*LC_SI); /* diamond ! */ + //set_nn_dist(&md,0.25*sqrt(3.0)*LC_SI); /* diamond ! */ + set_nn_dist(&md,LC_SI); /* set temperature */ //set_temperature(&md,273.0+1410.0); -- 2.20.1 From c0ddf2bdd8067456f39f6b63fe2261624ebde6b7 Mon Sep 17 00:00:00 2001 From: hackbard Date: Thu, 25 Jan 2007 17:52:03 +0000 Subject: [PATCH 08/16] nur foo ... --- moldyn.c | 13 +++++++++---- moldyn.h | 9 +++++---- sic.c | 18 +++++++++--------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/moldyn.c b/moldyn.c index f564075..881f0b6 100644 --- a/moldyn.c +++ b/moldyn.c @@ -344,7 +344,10 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, switch(type) { case CUBIC: - ret=cubic_init(a,b,c,lc,atom,NULL); + origin.x=0.5*lc; + origin.y=0.5*lc; + origin.z=0.5*lc; + ret=cubic_init(a,b,c,lc,atom,&origin); break; case FCC: ret=fcc_init(a,b,c,lc,atom,NULL); @@ -399,8 +402,8 @@ int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { for(i=0;icount*EV; +printf("debug: %f\n",moldyn->atom[0].f.x); /* calculate initial forces */ potential_force_calc(moldyn); +printf("debug: %f\n",moldyn->atom[0].f.x); /* some stupid checks before we actually start calculating bullshit */ if(moldyn->cutoff>0.5*moldyn->dim.x) @@ -1232,8 +1237,8 @@ int moldyn_integrate(t_moldyn *moldyn) { if(!(i%v)) { visual_atoms(&(moldyn->vis),moldyn->time, moldyn->atom,moldyn->count); - printf("\rsched: %d, steps: %d, debug: %f | %f", - sched->count,i,moldyn->p/ATM,moldyn->p/ATM); + printf("\rsched: %d, steps: %d, debug: %f", + sched->count,i,moldyn->p/ATM); fflush(stdout); } } diff --git a/moldyn.h b/moldyn.h index 69cee96..0dbc1f9 100644 --- a/moldyn.h +++ b/moldyn.h @@ -146,7 +146,7 @@ typedef struct s_moldyn { t_random random; /* random interface */ - int debug; /* debugging stuff, ignore */ + double debug; /* debugging stuff, ignore */ } t_moldyn; #define MOLDYN_STAT_PBX 0x01 /* periodic boudaries in x */ @@ -235,7 +235,7 @@ typedef struct s_tersoff_exchange { t_3dvec dzeta_ji; } t_tersoff_exchange; -/* tersoff multi (2!) potential parameters */ +/* tersoff mult (2!) potential parameters */ typedef struct s_tersoff_mult_params { double S[2]; /* tersoff cutoff radii */ double S2[2]; /* tersoff cutoff radii squared */ @@ -290,7 +290,7 @@ typedef struct s_tersoff_mult_params { #define KILOGRAM (1.0/AMU) /* amu */ #define NEWTON (METER*KILOGRAM/(SECOND*SECOND)) /* A amu / fs^2 */ #define PASCAL (NEWTON/(METER*METER)) /* N / A^2 */ -#define ATM (1.0133e5*PASCAL) /* N / A^2 */ +#define ATM ((1.0133e5*PASCAL)) /* N / A^2 */ #define MOLDYN_TEMP 273.0 #define MOLDYN_TAU 1.0 @@ -330,7 +330,8 @@ typedef struct s_tersoff_mult_params { #define LC_SI (0.543105e-9*METER) /* A */ #define M_SI 28.08553 /* amu */ -#define LJ_SIGMA_SI ((0.25*sqrt(3.0)*LC_SI)/1.122462) /* A */ +//#define LJ_SIGMA_SI ((0.25*sqrt(3.0)*LC_SI)/1.122462) /* A */ +#define LJ_SIGMA_SI (LC_SI/1.122462) /* A */ #define LJ_EPSILON_SI (2.1678*EV) /* NA */ #define TM_R_SI (2.7e-10*METER) /* A */ diff --git a/sic.c b/sic.c index 999d860..7e1249c 100644 --- a/sic.c +++ b/sic.c @@ -59,13 +59,13 @@ int main(int argc,char **argv) { //set_potential2b(&md,tersoff_mult_2bp,&tp); //set_potential2b_post(&md,tersoff_mult_post_2bp,&tp); //set_potential3b(&md,tersoff_mult_3bp,&tp); - //set_potential2b(&md,lennard_jones,&lj); - set_potential2b(&md,harmonic_oscillator,&ho); + set_potential2b(&md,lennard_jones,&lj); + //set_potential2b(&md,harmonic_oscillator,&ho); /* cutoff radius */ //set_cutoff(&md,TM_S_SI); //set_cutoff(&md,2*LC_SI*0.5*sqrt(1.5)); - set_cutoff(&md,1.1*LC_SI); + set_cutoff(&md,2.0*LC_SI); /* * potential parameters @@ -81,7 +81,7 @@ int main(int argc,char **argv) { /* harmonic oscillator */ //ho.equilibrium_distance=0.25*sqrt(3.0)*LC_SI; ho.equilibrium_distance=LC_SI; - ho.spring_constant=.1; + ho.spring_constant=LJ_EPSILON_SI; /* * tersoff mult potential parameters for SiC @@ -115,18 +115,18 @@ int main(int argc,char **argv) { tersoff_mult_complete_params(&tp); /* set (initial) dimensions of simulation volume */ - //set_dim(&md,8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),8*LC_SI*0.5*sqrt(1.5),TRUE); - set_dim(&md,8*LC_SI,8*LC_SI,8*LC_SI,TRUE); + set_dim(&md,6*LC_SI,6*LC_SI,6*LC_SI,TRUE); /* set periodic boundary conditions in all directions */ set_pbc(&md,TRUE,TRUE,TRUE); /* create the lattice / place atoms */ create_lattice(&md,CUBIC,LC_SI,SI,M_SI, + //create_lattice(&md,FCC,LC_SI,SI,M_SI, //create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, ATOM_ATTR_2BP|ATOM_ATTR_HB, - 0,8,8,8); + 0,6,6,6); moldyn_bc_check(&md); /* testing configuration */ @@ -171,7 +171,7 @@ int main(int argc,char **argv) { thermal_init(&md,TRUE); /* create the simulation schedule */ - moldyn_add_schedule(&md,1001,1.0); + moldyn_add_schedule(&md,100001,1.0); //moldyn_add_schedule(&md,501,1.0); //moldyn_add_schedule(&md,501,1.0); @@ -182,7 +182,7 @@ int main(int argc,char **argv) { moldyn_set_log_dir(&md,argv[1]); moldyn_set_report(&md,"Frank Zirkelbach","Test 1"); moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); - moldyn_set_log(&md,VISUAL_STEP,10); + moldyn_set_log(&md,VISUAL_STEP,1000); moldyn_set_log(&md,CREATE_REPORT,0); /* -- 2.20.1 From 91e4a00285261865ffce4b9553d153b562c80ee6 Mon Sep 17 00:00:00 2001 From: hackbard Date: Fri, 26 Jan 2007 15:36:19 +0000 Subject: [PATCH 09/16] pt scaling tests, though pressure estimation still a mess! --- moldyn.c | 118 ++++++++++++++++++++++-------------------------- moldyn.h | 5 +- sic.c | 19 ++------ visual/visual.c | 3 +- 4 files changed, 64 insertions(+), 81 deletions(-) diff --git a/moldyn.c b/moldyn.c index 881f0b6..0d5027c 100644 --- a/moldyn.c +++ b/moldyn.c @@ -73,7 +73,7 @@ int set_temperature(t_moldyn *moldyn,double t_ref) { moldyn->t_ref=t_ref; - printf("[moldyn] temperature: %f\n",moldyn->t_ref); + printf("[moldyn] temperature [K]: %f\n",moldyn->t_ref); return 0; } @@ -82,7 +82,7 @@ int set_pressure(t_moldyn *moldyn,double p_ref) { moldyn->p_ref=p_ref; - printf("[moldyn] pressure: %f\n",moldyn->p_ref); + printf("[moldyn] pressure [atm]: %f\n",moldyn->p_ref/ATM); return 0; } @@ -344,15 +344,18 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, switch(type) { case CUBIC: + set_nn_dist(moldyn,lc); origin.x=0.5*lc; origin.y=0.5*lc; origin.z=0.5*lc; ret=cubic_init(a,b,c,lc,atom,&origin); break; case FCC: + set_nn_dist(moldyn,0.5*sqrt(2.0)*lc); ret=fcc_init(a,b,c,lc,atom,NULL); break; case DIAMOND: + set_nn_dist(moldyn,0.25*sqrt(3.0)*lc); ret=diamond_init(a,b,c,lc,atom,&origin); break; default: @@ -720,7 +723,7 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { scale_dim(moldyn,scale,TRUE,0,0); scale_atoms(moldyn,scale,TRUE,0,0); link_cell_shutdown(moldyn); - link_cell_init(moldyn); + link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); tp->x=(moldyn->energy-u)/moldyn->dv; p=tp->x*tp->x; @@ -734,7 +737,7 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { scale_dim(moldyn,scale,0,TRUE,0); scale_atoms(moldyn,scale,0,TRUE,0); link_cell_shutdown(moldyn); - link_cell_init(moldyn); + link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); tp->y=(moldyn->energy-u)/moldyn->dv; p+=tp->y*tp->y; @@ -748,7 +751,7 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { scale_dim(moldyn,scale,0,0,TRUE); scale_atoms(moldyn,scale,0,0,TRUE); link_cell_shutdown(moldyn); - link_cell_init(moldyn); + link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); tp->z=(moldyn->energy-u)/moldyn->dv; p+=tp->z*tp->z; @@ -765,7 +768,7 @@ printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); scale_dim(moldyn,scale,1,1,1); scale_atoms(moldyn,scale,1,1,1); link_cell_shutdown(moldyn); - link_cell_init(moldyn); + link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); @@ -779,7 +782,7 @@ printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); moldyn->energy=u; link_cell_shutdown(moldyn); - link_cell_init(moldyn); + link_cell_init(moldyn,QUIET); return sqrt(p); } @@ -820,61 +823,48 @@ int scale_atoms(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z) { int scale_volume(t_moldyn *moldyn) { - t_atom *atom; t_3dvec *dim,*vdim; - double scale,v; - t_virial virial; + double scale; t_linkcell *lc; - int i; - atom=moldyn->atom; - dim=&(moldyn->dim); vdim=&(moldyn->vis.dim); + dim=&(moldyn->dim); lc=&(moldyn->lc); - memset(&virial,0,sizeof(t_virial)); + /* scaling factor */ + if(moldyn->pt_scale&P_SCALE_BERENDSEN) { + scale=1.0-(moldyn->p_ref-moldyn->p)/moldyn->p_tc; + scale=pow(scale,ONE_THIRD); + } + else { + scale=pow(moldyn->p/moldyn->p_ref,ONE_THIRD); + } +moldyn->debug=scale; - for(i=0;icount;i++) { - virial.xx+=atom[i].virial.xx; - virial.yy+=atom[i].virial.yy; - virial.zz+=atom[i].virial.zz; - virial.xy+=atom[i].virial.xy; - virial.xz+=atom[i].virial.xz; - virial.yz+=atom[i].virial.yz; + /* scale the atoms and dimensions */ + scale_atoms(moldyn,scale,TRUE,TRUE,TRUE); + scale_dim(moldyn,scale,TRUE,TRUE,TRUE); + + /* visualize dimensions */ + if(vdim->x!=0) { + vdim->x=dim->x; + vdim->y=dim->y; + vdim->z=dim->z; } - /* just a guess so far ... */ - v=virial.xx+virial.yy+virial.zz; - -printf("%f\n",v); - /* get pressure from virial */ - moldyn->p=moldyn->count*K_BOLTZMANN*moldyn->t+ONE_THIRD*v; - moldyn->p/=moldyn->volume; -printf("%f | %f\n",moldyn->p/(ATM),moldyn->p_ref/ATM); - - /* scale factor */ - if(moldyn->pt_scale&P_SCALE_BERENDSEN) - scale=3*sqrt(1-(moldyn->p_ref-moldyn->p)/moldyn->p_tc); - else - /* should actually never be used */ - scale=pow(moldyn->p/moldyn->p_ref,1.0/3.0); - -printf("scale = %f\n",scale); - /* actual scaling */ - dim->x*=scale; - dim->y*=scale; - dim->z*=scale; - if(vdim->x) vdim->x=dim->x; - if(vdim->y) vdim->y=dim->y; - if(vdim->z) vdim->z=dim->z; - moldyn->volume*=(scale*scale*scale); - - /* check whether we need a new linkcell init */ - if((dim->x/moldyn->cutoff!=lc->nx)|| - (dim->y/moldyn->cutoff!=lc->ny)|| - (dim->z/moldyn->cutoff!=lc->nx)) { + /* recalculate scaled volume */ + moldyn->volume=dim->x*dim->y*dim->z; + + /* adjust/reinit linkcell */ + if(((int)(dim->x/moldyn->cutoff)!=lc->nx)|| + ((int)(dim->y/moldyn->cutoff)!=lc->ny)|| + ((int)(dim->z/moldyn->cutoff)!=lc->nx)) { link_cell_shutdown(moldyn); - link_cell_init(moldyn); + link_cell_init(moldyn,QUIET); + } else { + lc->x*=scale; + lc->y*=scale; + lc->z*=scale; } return 0; @@ -939,7 +929,7 @@ double estimate_time_step(t_moldyn *moldyn,double nn_dist) { /* linked list / cell method */ -int link_cell_init(t_moldyn *moldyn) { +int link_cell_init(t_moldyn *moldyn,u8 vol) { t_linkcell *lc; int i; @@ -960,7 +950,7 @@ int link_cell_init(t_moldyn *moldyn) { if(lc->cells<27) printf("[moldyn] FATAL: less then 27 subcells!\n"); - printf("[moldyn] initializing linked cells (%d)\n",lc->cells); + if(vol) printf("[moldyn] initializing linked cells (%d)\n",lc->cells); for(i=0;icells;i++) list_init_f(&(lc->subcell[i])); @@ -1137,7 +1127,7 @@ int moldyn_integrate(t_moldyn *moldyn) { atom=moldyn->atom; /* initialize linked cell method */ - link_cell_init(moldyn); + link_cell_init(moldyn,VERBOSE); /* logging & visualization */ e=moldyn->ewrite; @@ -1152,10 +1142,8 @@ int moldyn_integrate(t_moldyn *moldyn) { /* energy scaling factor */ energy_scale=moldyn->count*EV; -printf("debug: %f\n",moldyn->atom[0].f.x); /* calculate initial forces */ potential_force_calc(moldyn); -printf("debug: %f\n",moldyn->atom[0].f.x); /* some stupid checks before we actually start calculating bullshit */ if(moldyn->cutoff>0.5*moldyn->dim.x) @@ -1192,17 +1180,18 @@ printf("debug: %f\n",moldyn->atom[0].f.x); /* integration step */ moldyn->integrate(moldyn); + /* calculate kinetic energy, temperature and pressure */ + update_e_kin(moldyn); + temperature_calc(moldyn); + pressure_calc(moldyn); + //thermodynamic_pressure_calc(moldyn); + /* p/t scaling */ if(moldyn->pt_scale&(T_SCALE_BERENDSEN|T_SCALE_DIRECT)) scale_velocity(moldyn,FALSE); if(moldyn->pt_scale&(P_SCALE_BERENDSEN|P_SCALE_DIRECT)) scale_volume(moldyn); - update_e_kin(moldyn); - temperature_calc(moldyn); - pressure_calc(moldyn); - //thermodynamic_pressure_calc(moldyn); - /* check for log & visualization */ if(e) { if(!(i%e)) @@ -1237,8 +1226,9 @@ printf("debug: %f\n",moldyn->atom[0].f.x); if(!(i%v)) { visual_atoms(&(moldyn->vis),moldyn->time, moldyn->atom,moldyn->count); - printf("\rsched: %d, steps: %d, debug: %f", - sched->count,i,moldyn->p/ATM); + printf("\rsched: %d, steps: %d, T: %f, P: %f V: %f", + sched->count,i, + moldyn->t,moldyn->p/ATM,moldyn->volume); fflush(stdout); } } diff --git a/moldyn.h b/moldyn.h index 0dbc1f9..f2ccdb5 100644 --- a/moldyn.h +++ b/moldyn.h @@ -313,6 +313,9 @@ typedef struct s_tersoff_mult_params { #define TRUE 1 #define FALSE 0 +#define VERBOSE 1 +#define QUIET 0 + /* * * phsical values / constants @@ -428,7 +431,7 @@ t_3dvec get_total_p(t_moldyn *moldyn); double estimate_time_step(t_moldyn *moldyn,double nn_dist); -int link_cell_init(t_moldyn *moldyn); +int link_cell_init(t_moldyn *moldyn,u8 vol); int link_cell_update(t_moldyn *moldyn); int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,t_list *cell); int link_cell_shutdown(t_moldyn *moldyn); diff --git a/sic.c b/sic.c index 7e1249c..2a2c7bc 100644 --- a/sic.c +++ b/sic.c @@ -146,26 +146,15 @@ int main(int argc,char **argv) { // ATOM_ATTR_2BP|ATOM_ATTR_HB, // &r,&v); - /* setting a nearest neighbour distance for the moldyn checks */ - //set_nn_dist(&md,0.25*sqrt(3.0)*LC_SI); /* diamond ! */ - set_nn_dist(&md,LC_SI); - - /* set temperature */ - //set_temperature(&md,273.0+1410.0); - //set_temperature(&md,273.0+450.0); - //set_temperature(&md,273.0); - //set_temperature(&md,1.0); - //set_temperature(&md,0.0); + /* set temperature & pressure */ set_temperature(&md,atof(argv[2])+273.0); - - /* set pressure */ set_pressure(&md,ATM); /* set p/t scaling */ - //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0, - // T_SCALE_BERENDSEN,100.0); + set_pt_scale(&md,P_SCALE_BERENDSEN,0.001, + T_SCALE_BERENDSEN,100.0); //set_pt_scale(&md,0,0,T_SCALE_DIRECT,1.0); - //set_pt_scale(&md,P_SCALE_BERENDSEN,100.0,0,0); + //set_pt_scale(&md,P_SCALE_BERENDSEN,0.001,0,0); /* initial thermal fluctuations of particles (in equilibrium) */ thermal_init(&md,TRUE); diff --git a/visual/visual.c b/visual/visual.c index a76c608..d6ce369 100644 --- a/visual/visual.c +++ b/visual/visual.c @@ -87,7 +87,8 @@ int visual_atoms(t_visual *v,double time,t_atom *atom,int n) { /* script file update */ dprintf(v->fd,"load xyz %s\n",file); - dprintf(v->fd,"spacefill 100\n"); + dprintf(v->fd,"spacefill\n"); + //dprintf(v->fd,"spacefill 100\n"); dprintf(v->fd,"rotate x 100\n"); dprintf(v->fd,"rotate y 10\n"); dprintf(v->fd,"set ambient 20\n"); -- 2.20.1 From cb177e7c208a85b45d77b09fcada23b62d0248b5 Mon Sep 17 00:00:00 2001 From: hackbard Date: Wed, 31 Jan 2007 16:35:26 +0000 Subject: [PATCH 10/16] create_lattice fixes, still virial probs ... --- moldyn.c | 85 +++++++++++++++++++++++-------------------------- moldyn.h | 3 +- report/report.h | 2 +- sic.c | 12 +++---- visual/visual.c | 3 +- 5 files changed, 49 insertions(+), 56 deletions(-) diff --git a/moldyn.c b/moldyn.c index 0d5027c..f6c3c81 100644 --- a/moldyn.c +++ b/moldyn.c @@ -339,22 +339,24 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, } moldyn->atom=ptr; atom=&(moldyn->atom[count]); - - v3_zero(&origin); + + /* no atoms on the boundaries (only reason: it looks better!) */ + origin.x=0.5*lc; + origin.y=0.5*lc; + origin.z=0.5*lc; switch(type) { case CUBIC: set_nn_dist(moldyn,lc); - origin.x=0.5*lc; - origin.y=0.5*lc; - origin.z=0.5*lc; ret=cubic_init(a,b,c,lc,atom,&origin); break; case FCC: + v3_scale(&origin,&origin,0.5); set_nn_dist(moldyn,0.5*sqrt(2.0)*lc); - ret=fcc_init(a,b,c,lc,atom,NULL); + ret=fcc_init(a,b,c,lc,atom,&origin); break; case DIAMOND: + v3_scale(&origin,&origin,0.25); set_nn_dist(moldyn,0.25*sqrt(3.0)*lc); ret=diamond_init(a,b,c,lc,atom,&origin); break; @@ -429,65 +431,55 @@ int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) { int count; - int i,j; + int i,j,k,l; t_3dvec o,r,n; t_3dvec basis[3]; - double help[3]; - double x,y,z; - - x=a*lc; - y=b*lc; - z=c*lc; - if(origin) v3_copy(&o,origin); - else v3_zero(&o); + count=0; + if(origin) + v3_copy(&o,origin); + else + v3_zero(&o); /* construct the basis */ - for(i=0;i<3;i++) { - for(j=0;j<3;j++) { - if(i!=j) help[j]=0.5*lc; - else help[j]=.0; - } - v3_set(&basis[i],help); - } + memset(basis,0,3*sizeof(t_3dvec)); + basis[0].x=0.5*lc; + basis[0].y=0.5*lc; + basis[1].x=0.5*lc; + basis[1].z=0.5*lc; + basis[2].y=0.5*lc; + basis[2].z=0.5*lc; - v3_zero(&r); - count=0; - /* fill up the room */ r.x=o.x; - while(r.xf),&(ai->f),&force); virial_calc(ai,&force,&distance); +if(force.x*distance.x<=0) printf("virial xx: %.15f -> %f %f %f\n",force.x*distance.x,distance.x,distance.y,distance.z); virial_calc(aj,&force,&distance); /* f and d signe switched */ } diff --git a/moldyn.h b/moldyn.h index f2ccdb5..3c53a86 100644 --- a/moldyn.h +++ b/moldyn.h @@ -334,7 +334,8 @@ typedef struct s_tersoff_mult_params { #define M_SI 28.08553 /* amu */ //#define LJ_SIGMA_SI ((0.25*sqrt(3.0)*LC_SI)/1.122462) /* A */ -#define LJ_SIGMA_SI (LC_SI/1.122462) /* A */ +//#define LJ_SIGMA_SI (LC_SI/1.122462) /* A */ +#define LJ_SIGMA_SI (0.5*sqrt(2.0)*LC_SI/1.122462) /* A */ #define LJ_EPSILON_SI (2.1678*EV) /* NA */ #define TM_R_SI (2.7e-10*METER) /* A */ diff --git a/report/report.h b/report/report.h index 3868515..e46ff2a 100644 --- a/report/report.h +++ b/report/report.h @@ -53,7 +53,7 @@ set ytic auto \n\ set title 'Energy per atom vs. time' \n\ set xlabel 'Time [fs]' \n\ set ylabel 'Energy per atom [eV]' \n\ -set terminal postscript eps enhanced color dashed lw 1 'Helvetica' 14 \n\ +set terminal postscript eps enhanced color solid lw 1 'Helvetica' 14 \n\ set output 'energy.eps' \n\ plot \"energy\" using 1:2 title 'Kinetic energy' with lines , \"energy\" using 1:3 title 'Potential energy' with lines , \"energy\" using 1:4 title 'Total energy' with lines\ "; diff --git a/sic.c b/sic.c index 2a2c7bc..f97ffe8 100644 --- a/sic.c +++ b/sic.c @@ -121,8 +121,8 @@ int main(int argc,char **argv) { set_pbc(&md,TRUE,TRUE,TRUE); /* create the lattice / place atoms */ - create_lattice(&md,CUBIC,LC_SI,SI,M_SI, - //create_lattice(&md,FCC,LC_SI,SI,M_SI, + //create_lattice(&md,CUBIC,LC_SI,SI,M_SI, + create_lattice(&md,FCC,LC_SI,SI,M_SI, //create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, ATOM_ATTR_2BP|ATOM_ATTR_HB, @@ -151,8 +151,8 @@ int main(int argc,char **argv) { set_pressure(&md,ATM); /* set p/t scaling */ - set_pt_scale(&md,P_SCALE_BERENDSEN,0.001, - T_SCALE_BERENDSEN,100.0); + //set_pt_scale(&md,P_SCALE_BERENDSEN,0.001, + // T_SCALE_BERENDSEN,100.0); //set_pt_scale(&md,0,0,T_SCALE_DIRECT,1.0); //set_pt_scale(&md,P_SCALE_BERENDSEN,0.001,0,0); @@ -160,7 +160,7 @@ int main(int argc,char **argv) { thermal_init(&md,TRUE); /* create the simulation schedule */ - moldyn_add_schedule(&md,100001,1.0); + moldyn_add_schedule(&md,101,1.0); //moldyn_add_schedule(&md,501,1.0); //moldyn_add_schedule(&md,501,1.0); @@ -171,7 +171,7 @@ int main(int argc,char **argv) { moldyn_set_log_dir(&md,argv[1]); moldyn_set_report(&md,"Frank Zirkelbach","Test 1"); moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); - moldyn_set_log(&md,VISUAL_STEP,1000); + moldyn_set_log(&md,VISUAL_STEP,1); moldyn_set_log(&md,CREATE_REPORT,0); /* diff --git a/visual/visual.c b/visual/visual.c index d6ce369..573ac4f 100644 --- a/visual/visual.c +++ b/visual/visual.c @@ -87,8 +87,7 @@ int visual_atoms(t_visual *v,double time,t_atom *atom,int n) { /* script file update */ dprintf(v->fd,"load xyz %s\n",file); - dprintf(v->fd,"spacefill\n"); - //dprintf(v->fd,"spacefill 100\n"); + dprintf(v->fd,"spacefill 200\n"); dprintf(v->fd,"rotate x 100\n"); dprintf(v->fd,"rotate y 10\n"); dprintf(v->fd,"set ambient 20\n"); -- 2.20.1 From caa3bc828974c35df2462fde737c31c0a618ee4e Mon Sep 17 00:00:00 2001 From: hackbard Date: Mon, 5 Mar 2007 09:01:53 +0000 Subject: [PATCH 11/16] new src file layout (warning: doesnt compile by now!) --- Makefile | 13 +- moldyn.c | 734 ------------------------------- potentials/harmonic_oscillator.c | 53 +++ potentials/lennard_jones.c | 60 +++ potentials/tersoff.c | 707 +++++++++++++++++++++++++++++ 5 files changed, 828 insertions(+), 739 deletions(-) create mode 100644 potentials/harmonic_oscillator.c create mode 100644 potentials/lennard_jones.c create mode 100644 potentials/tersoff.c diff --git a/Makefile b/Makefile index c51f8bd..37fafcc 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,16 @@ CFLAGS+=-g #CFLAGS+=-DVDEBUG LDFLAGS=-lm -OBJS=visual/visual.o random/random.o -OBJS+=moldyn.o +SOURCE=moldyn.c visual/visual.c random/random.c -all: clean sic +POT_SRC=potentials/tersoff.c potentials/lennard_jones.c +POT_SRC+= potentials/harmonic_oscillator.c -sic: $(OBJS) +all: sic + +sic: + $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE) $(POT_SRC) sic.c -o sic .PHONY:clean clean: - rm -f *.o sic */*.o + rm -f sic diff --git a/moldyn.c b/moldyn.c index f6c3c81..1ab88eb 100644 --- a/moldyn.c +++ b/moldyn.c @@ -1531,740 +1531,6 @@ int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { return 0; } -/* lennard jones potential & force for one sort of atoms */ - -int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { - - t_lj_params *params; - t_3dvec force,distance; - double d,h1,h2; - double eps,sig6,sig12; - - params=moldyn->pot2b_params; - eps=params->epsilon4; - sig6=params->sigma6; - sig12=params->sigma12; - - if(air),&(ai->r)); - if(bc) check_per_bound(moldyn,&distance); - d=v3_absolute_square(&distance); /* 1/r^2 */ - if(d<=moldyn->cutoff_square) { - d=1.0/d; /* 1/r^2 */ - h2=d*d; /* 1/r^4 */ - h2*=d; /* 1/r^6 */ - h1=h2*h2; /* 1/r^12 */ - moldyn->energy+=(eps*(sig12*h1-sig6*h2)-params->uc); - h2*=d; /* 1/r^8 */ - h1*=d; /* 1/r^14 */ - h2*=6*sig6; - h1*=12*sig12; - d=+h1-h2; - d*=eps; - v3_scale(&force,&distance,d); - v3_add(&(aj->f),&(aj->f),&force); - v3_scale(&force,&force,-1.0); /* f = - grad E */ - v3_add(&(ai->f),&(ai->f),&force); - virial_calc(ai,&force,&distance); -if(force.x*distance.x<=0) printf("virial xx: %.15f -> %f %f %f\n",force.x*distance.x,distance.x,distance.y,distance.z); - virial_calc(aj,&force,&distance); /* f and d signe switched */ - } - - return 0; -} - -/* - * tersoff potential & force for 2 sorts of atoms - */ - -/* create mixed terms from parameters and set them */ -int tersoff_mult_complete_params(t_tersoff_mult_params *p) { - - printf("[moldyn] tersoff parameter completion\n"); - p->S2[0]=p->S[0]*p->S[0]; - p->S2[1]=p->S[1]*p->S[1]; - p->Smixed=sqrt(p->S[0]*p->S[1]); - p->S2mixed=p->Smixed*p->Smixed; - p->Rmixed=sqrt(p->R[0]*p->R[1]); - p->Amixed=sqrt(p->A[0]*p->A[1]); - p->Bmixed=sqrt(p->B[0]*p->B[1]); - p->lambda_m=0.5*(p->lambda[0]+p->lambda[1]); - p->mu_m=0.5*(p->mu[0]+p->mu[1]); - - printf("[moldyn] tersoff mult parameter info:\n"); - printf(" S (A) | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed); - printf(" R (A) | %f | %f | %f\n",p->R[0],p->R[1],p->Rmixed); - printf(" A (eV) | %f | %f | %f\n",p->A[0]/EV,p->A[1]/EV,p->Amixed/EV); - printf(" B (eV) | %f | %f | %f\n",p->B[0]/EV,p->B[1]/EV,p->Bmixed/EV); - printf(" lambda | %f | %f | %f\n",p->lambda[0],p->lambda[1], - p->lambda_m); - printf(" mu | %f | %f | %f\n",p->mu[0],p->mu[1],p->mu_m); - printf(" beta | %.10f | %.10f\n",p->beta[0],p->beta[1]); - printf(" n | %f | %f\n",p->n[0],p->n[1]); - printf(" c | %f | %f\n",p->c[0],p->c[1]); - printf(" d | %f | %f\n",p->d[0],p->d[1]); - printf(" h | %f | %f\n",p->h[0],p->h[1]); - printf(" chi | %f \n",p->chi); - - return 0; -} - -/* tersoff 1 body part */ -int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) { - - int brand; - t_tersoff_mult_params *params; - t_tersoff_exchange *exchange; - - brand=ai->brand; - params=moldyn->pot1b_params; - exchange=&(params->exchange); - - /* - * simple: point constant parameters only depending on atom i to - * their right values - */ - - exchange->beta_i=&(params->beta[brand]); - exchange->n_i=&(params->n[brand]); - exchange->c_i=&(params->c[brand]); - exchange->d_i=&(params->d[brand]); - exchange->h_i=&(params->h[brand]); - - exchange->betaini=pow(*(exchange->beta_i),*(exchange->n_i)); - exchange->ci2=params->c[brand]*params->c[brand]; - exchange->di2=params->d[brand]*params->d[brand]; - exchange->ci2di2=exchange->ci2/exchange->di2; - - return 0; -} - -/* tersoff 2 body part */ -int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { - - t_tersoff_mult_params *params; - t_tersoff_exchange *exchange; - t_3dvec dist_ij,force; - double d_ij,d_ij2; - double A,B,R,S,S2,lambda,mu; - double f_r,df_r; - double f_c,df_c; - int brand; - double s_r; - double arg; - - params=moldyn->pot2b_params; - brand=aj->brand; - exchange=&(params->exchange); - - /* clear 3bp and 2bp post run */ - exchange->run3bp=0; - exchange->run2bp_post=0; - - /* reset S > r > R mark */ - exchange->d_ij_between_rs=0; - - /* - * calc of 2bp contribution of V_ij and dV_ij/ji - * - * for Vij and dV_ij we need: - * - f_c_ij, df_c_ij - * - f_r_ij, df_r_ij - * - * for dV_ji we need: - * - f_c_ji = f_c_ij, df_c_ji = df_c_ij - * - f_r_ji = f_r_ij; df_r_ji = df_r_ij - * - */ - - /* constants */ - if(brand==ai->brand) { - S=params->S[brand]; - S2=params->S2[brand]; - R=params->R[brand]; - A=params->A[brand]; - B=params->B[brand]; - lambda=params->lambda[brand]; - mu=params->mu[brand]; - exchange->chi=1.0; - } - else { - S=params->Smixed; - S2=params->S2mixed; - R=params->Rmixed; - A=params->Amixed; - B=params->Bmixed; - lambda=params->lambda_m; - mu=params->mu_m; - params->exchange.chi=params->chi; - } - - /* dist_ij, d_ij */ - v3_sub(&dist_ij,&(aj->r),&(ai->r)); - if(bc) check_per_bound(moldyn,&dist_ij); - d_ij2=v3_absolute_square(&dist_ij); - - /* if d_ij2 > S2 => no force & potential energy contribution */ - if(d_ij2>S2) - return 0; - - /* now we will need the distance */ - //d_ij=v3_norm(&dist_ij); - d_ij=sqrt(d_ij2); - - /* save for use in 3bp */ - exchange->d_ij=d_ij; - exchange->d_ij2=d_ij2; - exchange->dist_ij=dist_ij; - - /* more constants */ - exchange->beta_j=&(params->beta[brand]); - exchange->n_j=&(params->n[brand]); - exchange->c_j=&(params->c[brand]); - exchange->d_j=&(params->d[brand]); - exchange->h_j=&(params->h[brand]); - if(brand==ai->brand) { - exchange->betajnj=exchange->betaini; - exchange->cj2=exchange->ci2; - exchange->dj2=exchange->di2; - exchange->cj2dj2=exchange->ci2di2; - } - else { - exchange->betajnj=pow(*(exchange->beta_j),*(exchange->n_j)); - exchange->cj2=params->c[brand]*params->c[brand]; - exchange->dj2=params->d[brand]*params->d[brand]; - exchange->cj2dj2=exchange->cj2/exchange->dj2; - } - - /* f_r_ij = f_r_ji, df_r_ij = df_r_ji */ - f_r=A*exp(-lambda*d_ij); - df_r=lambda*f_r/d_ij; - - /* f_a, df_a calc (again, same for ij and ji) | save for later use! */ - exchange->f_a=-B*exp(-mu*d_ij); - exchange->df_a=mu*exchange->f_a/d_ij; - - /* f_c, df_c calc (again, same for ij and ji) */ - if(d_ij r > R */ - exchange->d_ij_between_rs=1; - } - - /* add forces of 2bp (ij, ji) contribution - * dVij = dVji and we sum up both: no 1/2) */ - v3_add(&(ai->f),&(ai->f),&force); - - /* virial */ - ai->virial.xx-=force.x*dist_ij.x; - ai->virial.yy-=force.y*dist_ij.y; - ai->virial.zz-=force.z*dist_ij.z; - ai->virial.xy-=force.x*dist_ij.y; - ai->virial.xz-=force.x*dist_ij.z; - ai->virial.yz-=force.y*dist_ij.z; - -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij, dVji (2bp) contrib:\n"); - printf("%f | %f\n",force.x,ai->f.x); - printf("%f | %f\n",force.y,ai->f.y); - printf("%f | %f\n",force.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij, dVji (2bp) contrib:\n"); - printf("%f | %f\n",force.x*dist_ij.x,ai->virial.xx); - printf("%f | %f\n",force.y*dist_ij.y,ai->virial.yy); - printf("%f | %f\n",force.z*dist_ij.z,ai->virial.zz); -} -#endif - - /* energy 2bp contribution (ij, ji) is 0.5 f_r f_c ... */ - moldyn->energy+=(0.5*f_r*f_c); - - /* save for use in 3bp */ - exchange->f_c=f_c; - exchange->df_c=df_c; - - /* enable the run of 3bp function and 2bp post processing */ - exchange->run3bp=1; - exchange->run2bp_post=1; - - /* reset 3bp sums */ - exchange->zeta_ij=0.0; - exchange->zeta_ji=0.0; - v3_zero(&(exchange->dzeta_ij)); - v3_zero(&(exchange->dzeta_ji)); - - return 0; -} - -/* tersoff 2 body post part */ - -int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { - - /* - * here we have to allow for the 3bp sums - * - * that is: - * - zeta_ij, dzeta_ij - * - zeta_ji, dzeta_ji - * - * to compute the 3bp contribution to: - * - Vij, dVij - * - dVji - * - */ - - t_tersoff_mult_params *params; - t_tersoff_exchange *exchange; - - t_3dvec force,temp; - t_3dvec *dist_ij; - double b,db,tmp; - double f_c,df_c,f_a,df_a; - double chi,ni,betaini,nj,betajnj; - double zeta; - - params=moldyn->pot2b_params; - exchange=&(params->exchange); - - /* we do not run if f_c_ij was detected to be 0! */ - if(!(exchange->run2bp_post)) - return 0; - - f_c=exchange->f_c; - df_c=exchange->df_c; - f_a=exchange->f_a; - df_a=exchange->df_a; - betaini=exchange->betaini; - betajnj=exchange->betajnj; - ni=*(exchange->n_i); - nj=*(exchange->n_j); - chi=exchange->chi; - dist_ij=&(exchange->dist_ij); - - /* Vij and dVij */ - zeta=exchange->zeta_ij; - if(zeta==0.0) { - moldyn->debug++; /* just for debugging ... */ - b=chi; - v3_scale(&force,dist_ij,df_a*b*f_c); - } - else { - tmp=betaini*pow(zeta,ni-1.0); /* beta^n * zeta^n-1 */ - b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ - db=chi*pow(b,-1.0/(2*ni)-1); /* x(...)^(-1/2n - 1) */ - b=db*b; /* b_ij */ - db*=-0.5*tmp; /* db_ij */ - v3_scale(&force,&(exchange->dzeta_ij),f_a*db); - v3_scale(&temp,dist_ij,df_a*b); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,f_c); - } - v3_scale(&temp,dist_ij,df_c*b*f_a); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,-0.5); - - /* add force */ - v3_add(&(ai->f),&(ai->f),&force); - - /* virial */ - ai->virial.xx-=force.x*dist_ij->x; - ai->virial.yy-=force.y*dist_ij->y; - ai->virial.zz-=force.z*dist_ij->z; - ai->virial.xy-=force.x*dist_ij->y; - ai->virial.xz-=force.x*dist_ij->z; - ai->virial.yz-=force.y*dist_ij->z; - -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij (3bp) contrib:\n"); - printf("%f | %f\n",force.x,ai->f.x); - printf("%f | %f\n",force.y,ai->f.y); - printf("%f | %f\n",force.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij (3bp) contrib:\n"); - printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); - printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); - printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); -} -#endif - - /* add energy of 3bp sum */ - moldyn->energy+=(0.5*f_c*b*f_a); - - /* dVji */ - zeta=exchange->zeta_ji; - if(zeta==0.0) { - moldyn->debug++; - b=chi; - v3_scale(&force,dist_ij,df_a*b*f_c); - } - else { - tmp=betajnj*pow(zeta,nj-1.0); /* beta^n * zeta^n-1 */ - b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ - db=chi*pow(b,-1.0/(2*nj)-1); /* x(...)^(-1/2n - 1) */ - b=db*b; /* b_ij */ - db*=-0.5*tmp; /* db_ij */ - v3_scale(&force,&(exchange->dzeta_ji),f_a*db); - v3_scale(&temp,dist_ij,df_a*b); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,f_c); - } - v3_scale(&temp,dist_ij,df_c*b*f_a); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,-0.5); - - /* add force */ - v3_add(&(ai->f),&(ai->f),&force); - - /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ -// TEST ... with a minus instead - ai->virial.xx-=force.x*dist_ij->x; - ai->virial.yy-=force.y*dist_ij->y; - ai->virial.zz-=force.z*dist_ij->z; - ai->virial.xy-=force.x*dist_ij->y; - ai->virial.xz-=force.x*dist_ij->z; - ai->virial.yz-=force.y*dist_ij->z; - -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVji (3bp) contrib:\n"); - printf("%f | %f\n",force.x,ai->f.x); - printf("%f | %f\n",force.y,ai->f.y); - printf("%f | %f\n",force.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVji (3bp) contrib:\n"); - printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); - printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); - printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); -} -#endif - - return 0; -} - -/* tersoff 3 body part */ - -int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { - - t_tersoff_mult_params *params; - t_tersoff_exchange *exchange; - t_3dvec dist_ij,dist_ik,dist_jk; - t_3dvec temp1,temp2; - t_3dvec *dzeta; - double R,S,S2,s_r; - double B,mu; - double d_ij,d_ik,d_jk,d_ij2,d_ik2,d_jk2; - double rr,dd; - double f_c,df_c; - double f_c_ik,df_c_ik,arg; - double f_c_jk; - double n,c,d,h; - double c2,d2,c2d2; - double cos_theta,d_costheta1,d_costheta2; - double h_cos,d2_h_cos2; - double frac,g,zeta,chi; - double tmp; - int brand; - - params=moldyn->pot3b_params; - exchange=&(params->exchange); - - if(!(exchange->run3bp)) - return 0; - - /* - * calc of 3bp contribution of V_ij and dV_ij/ji/jk & - * 2bp contribution of dV_jk - * - * for Vij and dV_ij we still need: - * - b_ij, db_ij (zeta_ij) - * - f_c_ik, df_c_ik, constants_i, cos_theta_ijk, d_costheta_ijk - * - * for dV_ji we still need: - * - b_ji, db_ji (zeta_ji) - * - f_c_jk, d_c_jk, constants_j, cos_theta_jik, d_costheta_jik - * - * for dV_jk we need: - * - f_c_jk - * - f_a_jk - * - db_jk (zeta_jk) - * - f_c_ji, df_c_ji, constants_j, cos_theta_jki, d_costheta_jki - * - */ - - /* - * get exchange data - */ - - /* dist_ij, d_ij - this is < S_ij ! */ - dist_ij=exchange->dist_ij; - d_ij=exchange->d_ij; - d_ij2=exchange->d_ij2; - - /* f_c_ij, df_c_ij (same for ji) */ - f_c=exchange->f_c; - df_c=exchange->df_c; - - /* - * calculate unknown values now ... - */ - - /* V_ij and dV_ij stuff (in b_ij there is f_c_ik) */ - - /* dist_ik, d_ik */ - v3_sub(&dist_ik,&(ak->r),&(ai->r)); - if(bc) check_per_bound(moldyn,&dist_ik); - d_ik2=v3_absolute_square(&dist_ik); - - /* ik constants */ - brand=ai->brand; - if(brand==ak->brand) { - R=params->R[brand]; - S=params->S[brand]; - S2=params->S2[brand]; - } - else { - R=params->Rmixed; - S=params->Smixed; - S2=params->S2mixed; - } - - /* zeta_ij/dzeta_ij contribution only for d_ik < S */ - if(d_ik2n_i); - c=*(exchange->c_i); - d=*(exchange->d_i); - h=*(exchange->h_i); - c2=exchange->ci2; - d2=exchange->di2; - c2d2=exchange->ci2di2; - - /* cosine of theta_ijk by scalaproduct */ - rr=v3_scalar_product(&dist_ij,&dist_ik); - dd=d_ij*d_ik; - cos_theta=rr/dd; - - /* d_costheta */ - tmp=1.0/dd; - d_costheta1=cos_theta/d_ij2-tmp; - d_costheta2=cos_theta/d_ik2-tmp; - - /* some usefull values */ - h_cos=(h-cos_theta); - d2_h_cos2=d2+(h_cos*h_cos); - frac=c2/(d2_h_cos2); - - /* g(cos_theta) */ - g=1.0+c2d2-frac; - - /* d_costheta_ij and dg(cos_theta) - needed in any case! */ - v3_scale(&temp1,&dist_ij,d_costheta1); - v3_scale(&temp2,&dist_ik,d_costheta2); - v3_add(&temp1,&temp1,&temp2); - v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ - - /* f_c_ik & df_c_ik + {d,}zeta contribution */ - dzeta=&(exchange->dzeta_ij); - if(d_ik f_c_ik=1.0; - // => df_c_ik=0.0; of course we do not set this! - - /* zeta_ij */ - exchange->zeta_ij+=g; - - /* dzeta_ij */ - v3_add(dzeta,dzeta,&temp1); - } - else { - /* {d,}f_c_ik */ - s_r=S-R; - arg=M_PI*(d_ik-R)/s_r; - f_c_ik=0.5+0.5*cos(arg); - df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik)); - - /* zeta_ij */ - exchange->zeta_ij+=f_c_ik*g; - - /* dzeta_ij */ - v3_scale(&temp1,&temp1,f_c_ik); - v3_scale(&temp2,&dist_ik,g*df_c_ik); - v3_add(&temp1,&temp1,&temp2); - v3_add(dzeta,dzeta,&temp1); - } - } - - /* dV_ji stuff (in b_ji there is f_c_jk) + dV_jk stuff! */ - - /* dist_jk, d_jk */ - v3_sub(&dist_jk,&(ak->r),&(aj->r)); - if(bc) check_per_bound(moldyn,&dist_jk); - d_jk2=v3_absolute_square(&dist_jk); - - /* jk constants */ - brand=aj->brand; - if(brand==ak->brand) { - R=params->R[brand]; - S=params->S[brand]; - S2=params->S2[brand]; - B=params->B[brand]; - mu=params->mu[brand]; - chi=1.0; - } - else { - R=params->Rmixed; - S=params->Smixed; - S2=params->S2mixed; - B=params->Bmixed; - mu=params->mu_m; - chi=params->chi; - } - - /* zeta_ji/dzeta_ji contribution only for d_jk < S_jk */ - if(d_jk2n_j); - c=*(exchange->c_j); - d=*(exchange->d_j); - h=*(exchange->h_j); - c2=exchange->cj2; - d2=exchange->dj2; - c2d2=exchange->cj2dj2; - - /* cosine of theta_jik by scalaproduct */ - rr=-v3_scalar_product(&dist_ij,&dist_jk); /* -1, as ij -> ji */ - dd=d_ij*d_jk; - cos_theta=rr/dd; - - /* d_costheta */ - d_costheta1=1.0/dd; - d_costheta2=cos_theta/d_ij2; - - /* some usefull values */ - h_cos=(h-cos_theta); - d2_h_cos2=d2+(h_cos*h_cos); - frac=c2/(d2_h_cos2); - - /* g(cos_theta) */ - g=1.0+c2d2-frac; - - /* d_costheta_jik and dg(cos_theta) - needed in any case! */ - v3_scale(&temp1,&dist_jk,d_costheta1); - v3_scale(&temp2,&dist_ij,-d_costheta2); /* ji -> ij => -1 */ - //v3_add(&temp1,&temp1,&temp2); - v3_sub(&temp1,&temp1,&temp2); /* there is a minus! */ - v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ - - /* store dg in temp2 and use it for dVjk later */ - v3_copy(&temp2,&temp1); - - /* f_c_jk + {d,}zeta contribution (df_c_jk = 0) */ - dzeta=&(exchange->dzeta_ji); - if(d_jkzeta_ji+=g; - - /* dzeta_ji */ - v3_add(dzeta,dzeta,&temp1); - } - else { - /* f_c_jk */ - s_r=S-R; - arg=M_PI*(d_jk-R)/s_r; - f_c_jk=0.5+0.5*cos(arg); - - /* zeta_ji */ - exchange->zeta_ji+=f_c_jk*g; - - /* dzeta_ji */ - v3_scale(&temp1,&temp1,f_c_jk); - v3_add(dzeta,dzeta,&temp1); - } - - /* dV_jk stuff | add force contribution on atom i immediately */ - if(exchange->d_ij_between_rs) { - zeta=f_c*g; - v3_scale(&temp1,&temp2,f_c); - v3_scale(&temp2,&dist_ij,df_c*g); - v3_add(&temp2,&temp2,&temp1); /* -> dzeta_jk in temp2 */ - } - else { - zeta=g; - // dzeta_jk is simply dg, which is stored in temp2 - } - /* betajnj * zeta_jk ^ nj-1 */ - tmp=exchange->betajnj*pow(zeta,(n-1.0)); - tmp=-chi/2.0*pow((1+tmp*zeta),(-1.0/(2.0*n)-1))*tmp; - v3_scale(&temp2,&temp2,tmp*B*exp(-mu*d_jk)*f_c_jk*0.5); - v3_add(&(ai->f),&(ai->f),&temp2); /* -1 skipped in f_a calc ^ */ - /* scaled with 0.5 ^ */ - - /* virial */ - ai->virial.xx-=temp2.x*dist_jk.x; - ai->virial.yy-=temp2.y*dist_jk.y; - ai->virial.zz-=temp2.z*dist_jk.z; - ai->virial.xy-=temp2.x*dist_jk.y; - ai->virial.xz-=temp2.x*dist_jk.z; - ai->virial.yz-=temp2.y*dist_jk.z; - -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVjk (3bp) contrib:\n"); - printf("%f | %f\n",temp2.x,ai->f.x); - printf("%f | %f\n",temp2.y,ai->f.y); - printf("%f | %f\n",temp2.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVjk (3bp) contrib:\n"); - printf("%f | %f\n",temp2.x*dist_jk.x,ai->virial.xx); - printf("%f | %f\n",temp2.y*dist_jk.y,ai->virial.yy); - printf("%f | %f\n",temp2.z*dist_jk.z,ai->virial.zz); -} -#endif - - } - - return 0; -} - - /* * debugging / critical check functions */ diff --git a/potentials/harmonic_oscillator.c b/potentials/harmonic_oscillator.c new file mode 100644 index 0000000..0d933b6 --- /dev/null +++ b/potentials/harmonic_oscillator.c @@ -0,0 +1,53 @@ +/* + * harmonic_oscillator.c - harmonic oscillator potential + * + * author: Frank Zirkelbach + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../moldyn.h" +#include "../math/math.h" +//#include "harmonic_oscillator.h" + +int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + t_ho_params *params; + t_3dvec force,distance; + double d,f; + double sc,equi_dist; + + params=moldyn->pot2b_params; + sc=params->spring_constant; + equi_dist=params->equilibrium_distance; + + if(air),&(ai->r)); + + if(bc) check_per_bound(moldyn,&distance); + d=v3_norm(&distance); + if(d<=moldyn->cutoff) { + moldyn->energy+=(0.5*sc*(d-equi_dist)*(d-equi_dist)); + /* f = -grad E; grad r_ij = -1 1/r_ij distance */ + f=sc*(1.0-equi_dist/d); + v3_scale(&force,&distance,f); + v3_add(&(ai->f),&(ai->f),&force); + virial_calc(ai,&force,&distance); + virial_calc(aj,&force,&distance); /* f and d signe switched */ + v3_scale(&force,&distance,-f); + v3_add(&(aj->f),&(aj->f),&force); + } + + return 0; +} + diff --git a/potentials/lennard_jones.c b/potentials/lennard_jones.c new file mode 100644 index 0000000..7d45a17 --- /dev/null +++ b/potentials/lennard_jones.c @@ -0,0 +1,60 @@ +/* + * lennard_jones.c - lennard jones potential + * + * author: Frank Zirkelbach + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../moldyn.h" +#inlcude "../math/math.h" +//#include "lennard_jones.h" + +int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + t_lj_params *params; + t_3dvec force,distance; + double d,h1,h2; + double eps,sig6,sig12; + + params=moldyn->pot2b_params; + eps=params->epsilon4; + sig6=params->sigma6; + sig12=params->sigma12; + + if(air),&(ai->r)); + if(bc) check_per_bound(moldyn,&distance); + d=v3_absolute_square(&distance); /* 1/r^2 */ + if(d<=moldyn->cutoff_square) { + d=1.0/d; /* 1/r^2 */ + h2=d*d; /* 1/r^4 */ + h1=h2*h2; /* 1/r^12 */ + moldyn->energy+=(eps*(sig12*h1-sig6*h2)-params->uc); + h2*=d; /* 1/r^8 */ + h1*=d; /* 1/r^14 */ + h2*=6*sig6; + h1*=12*sig12; + d=+h1-h2; + d*=eps; + v3_scale(&force,&distance,d); + v3_add(&(aj->f),&(aj->f),&force); + v3_scale(&force,&force,-1.0); /* f = - grad E */ + v3_add(&(ai->f),&(ai->f),&force); + virial_calc(ai,&force,&distance); + virial_calc(aj,&force,&distance); /* f and d signe switched */ + } + + return 0; +} + diff --git a/potentials/tersoff.c b/potentials/tersoff.c new file mode 100644 index 0000000..87bb187 --- /dev/null +++ b/potentials/tersoff.c @@ -0,0 +1,707 @@ +/* + * tersoff.c - tersoff potential + * + * author: Frank Zirkelbach + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../moldyn.h" +#include "../math/math.h" +//#include "tersoff.h" + +/* create mixed terms from parameters and set them */ +int tersoff_mult_complete_params(t_tersoff_mult_params *p) { + + printf("[moldyn] tersoff parameter completion\n"); + p->S2[0]=p->S[0]*p->S[0]; + p->S2[1]=p->S[1]*p->S[1]; + p->Smixed=sqrt(p->S[0]*p->S[1]); + p->S2mixed=p->Smixed*p->Smixed; + p->Rmixed=sqrt(p->R[0]*p->R[1]); + p->Amixed=sqrt(p->A[0]*p->A[1]); + p->Bmixed=sqrt(p->B[0]*p->B[1]); + p->lambda_m=0.5*(p->lambda[0]+p->lambda[1]); + p->mu_m=0.5*(p->mu[0]+p->mu[1]); + + printf("[moldyn] tersoff mult parameter info:\n"); + printf(" S (A) | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed); + printf(" R (A) | %f | %f | %f\n",p->R[0],p->R[1],p->Rmixed); + printf(" A (eV) | %f | %f | %f\n",p->A[0]/EV,p->A[1]/EV,p->Amixed/EV); + printf(" B (eV) | %f | %f | %f\n",p->B[0]/EV,p->B[1]/EV,p->Bmixed/EV); + printf(" lambda | %f | %f | %f\n",p->lambda[0],p->lambda[1], + p->lambda_m); + printf(" mu | %f | %f | %f\n",p->mu[0],p->mu[1],p->mu_m); + printf(" beta | %.10f | %.10f\n",p->beta[0],p->beta[1]); + printf(" n | %f | %f\n",p->n[0],p->n[1]); + printf(" c | %f | %f\n",p->c[0],p->c[1]); + printf(" d | %f | %f\n",p->d[0],p->d[1]); + printf(" h | %f | %f\n",p->h[0],p->h[1]); + printf(" chi | %f \n",p->chi); + + return 0; +} + +/* tersoff 1 body part */ +int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) { + + int brand; + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + + brand=ai->brand; + params=moldyn->pot1b_params; + exchange=&(params->exchange); + + /* + * simple: point constant parameters only depending on atom i to + * their right values + */ + + exchange->beta_i=&(params->beta[brand]); + exchange->n_i=&(params->n[brand]); + exchange->c_i=&(params->c[brand]); + exchange->d_i=&(params->d[brand]); + exchange->h_i=&(params->h[brand]); + + exchange->betaini=pow(*(exchange->beta_i),*(exchange->n_i)); + exchange->ci2=params->c[brand]*params->c[brand]; + exchange->di2=params->d[brand]*params->d[brand]; + exchange->ci2di2=exchange->ci2/exchange->di2; + + return 0; +} + +/* tersoff 2 body part */ +int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + t_3dvec dist_ij,force; + double d_ij,d_ij2; + double A,B,R,S,S2,lambda,mu; + double f_r,df_r; + double f_c,df_c; + int brand; + double s_r; + double arg; + + params=moldyn->pot2b_params; + brand=aj->brand; + exchange=&(params->exchange); + + /* clear 3bp and 2bp post run */ + exchange->run3bp=0; + exchange->run2bp_post=0; + + /* reset S > r > R mark */ + exchange->d_ij_between_rs=0; + + /* + * calc of 2bp contribution of V_ij and dV_ij/ji + * + * for Vij and dV_ij we need: + * - f_c_ij, df_c_ij + * - f_r_ij, df_r_ij + * + * for dV_ji we need: + * - f_c_ji = f_c_ij, df_c_ji = df_c_ij + * - f_r_ji = f_r_ij; df_r_ji = df_r_ij + * + */ + + /* constants */ + if(brand==ai->brand) { + S=params->S[brand]; + S2=params->S2[brand]; + R=params->R[brand]; + A=params->A[brand]; + B=params->B[brand]; + lambda=params->lambda[brand]; + mu=params->mu[brand]; + exchange->chi=1.0; + } + else { + S=params->Smixed; + S2=params->S2mixed; + R=params->Rmixed; + A=params->Amixed; + B=params->Bmixed; + lambda=params->lambda_m; + mu=params->mu_m; + params->exchange.chi=params->chi; + } + + /* dist_ij, d_ij */ + v3_sub(&dist_ij,&(aj->r),&(ai->r)); + if(bc) check_per_bound(moldyn,&dist_ij); + d_ij2=v3_absolute_square(&dist_ij); + + /* if d_ij2 > S2 => no force & potential energy contribution */ + if(d_ij2>S2) + return 0; + + /* now we will need the distance */ + //d_ij=v3_norm(&dist_ij); + d_ij=sqrt(d_ij2); + + /* save for use in 3bp */ + exchange->d_ij=d_ij; + exchange->d_ij2=d_ij2; + exchange->dist_ij=dist_ij; + + /* more constants */ + exchange->beta_j=&(params->beta[brand]); + exchange->n_j=&(params->n[brand]); + exchange->c_j=&(params->c[brand]); + exchange->d_j=&(params->d[brand]); + exchange->h_j=&(params->h[brand]); + if(brand==ai->brand) { + exchange->betajnj=exchange->betaini; + exchange->cj2=exchange->ci2; + exchange->dj2=exchange->di2; + exchange->cj2dj2=exchange->ci2di2; + } + else { + exchange->betajnj=pow(*(exchange->beta_j),*(exchange->n_j)); + exchange->cj2=params->c[brand]*params->c[brand]; + exchange->dj2=params->d[brand]*params->d[brand]; + exchange->cj2dj2=exchange->cj2/exchange->dj2; + } + + /* f_r_ij = f_r_ji, df_r_ij = df_r_ji */ + f_r=A*exp(-lambda*d_ij); + df_r=lambda*f_r/d_ij; + + /* f_a, df_a calc (again, same for ij and ji) | save for later use! */ + exchange->f_a=-B*exp(-mu*d_ij); + exchange->df_a=mu*exchange->f_a/d_ij; + + /* f_c, df_c calc (again, same for ij and ji) */ + if(d_ij r > R */ + exchange->d_ij_between_rs=1; + } + + /* add forces of 2bp (ij, ji) contribution + * dVij = dVji and we sum up both: no 1/2) */ + v3_add(&(ai->f),&(ai->f),&force); + + /* virial */ + ai->virial.xx-=force.x*dist_ij.x; + ai->virial.yy-=force.y*dist_ij.y; + ai->virial.zz-=force.z*dist_ij.z; + ai->virial.xy-=force.x*dist_ij.y; + ai->virial.xz-=force.x*dist_ij.z; + ai->virial.yz-=force.y*dist_ij.z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij, dVji (2bp) contrib:\n"); + printf("%f | %f\n",force.x,ai->f.x); + printf("%f | %f\n",force.y,ai->f.y); + printf("%f | %f\n",force.z,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij, dVji (2bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij.x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij.y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij.z,ai->virial.zz); +} +#endif + + /* energy 2bp contribution (ij, ji) is 0.5 f_r f_c ... */ + moldyn->energy+=(0.5*f_r*f_c); + + /* save for use in 3bp */ + exchange->f_c=f_c; + exchange->df_c=df_c; + + /* enable the run of 3bp function and 2bp post processing */ + exchange->run3bp=1; + exchange->run2bp_post=1; + + /* reset 3bp sums */ + exchange->zeta_ij=0.0; + exchange->zeta_ji=0.0; + v3_zero(&(exchange->dzeta_ij)); + v3_zero(&(exchange->dzeta_ji)); + + return 0; +} + +/* tersoff 2 body post part */ + +int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + /* + * here we have to allow for the 3bp sums + * + * that is: + * - zeta_ij, dzeta_ij + * - zeta_ji, dzeta_ji + * + * to compute the 3bp contribution to: + * - Vij, dVij + * - dVji + * + */ + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + + t_3dvec force,temp; + t_3dvec *dist_ij; + double b,db,tmp; + double f_c,df_c,f_a,df_a; + double chi,ni,betaini,nj,betajnj; + double zeta; + + params=moldyn->pot2b_params; + exchange=&(params->exchange); + + /* we do not run if f_c_ij was detected to be 0! */ + if(!(exchange->run2bp_post)) + return 0; + + f_c=exchange->f_c; + df_c=exchange->df_c; + f_a=exchange->f_a; + df_a=exchange->df_a; + betaini=exchange->betaini; + betajnj=exchange->betajnj; + ni=*(exchange->n_i); + nj=*(exchange->n_j); + chi=exchange->chi; + dist_ij=&(exchange->dist_ij); + + /* Vij and dVij */ + zeta=exchange->zeta_ij; + if(zeta==0.0) { + moldyn->debug++; /* just for debugging ... */ + b=chi; + v3_scale(&force,dist_ij,df_a*b*f_c); + } + else { + tmp=betaini*pow(zeta,ni-1.0); /* beta^n * zeta^n-1 */ + b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ + db=chi*pow(b,-1.0/(2*ni)-1); /* x(...)^(-1/2n - 1) */ + b=db*b; /* b_ij */ + db*=-0.5*tmp; /* db_ij */ + v3_scale(&force,&(exchange->dzeta_ij),f_a*db); + v3_scale(&temp,dist_ij,df_a*b); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,f_c); + } + v3_scale(&temp,dist_ij,df_c*b*f_a); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,-0.5); + + /* add force */ + v3_add(&(ai->f),&(ai->f),&force); + + /* virial */ + ai->virial.xx-=force.x*dist_ij->x; + ai->virial.yy-=force.y*dist_ij->y; + ai->virial.zz-=force.z*dist_ij->z; + ai->virial.xy-=force.x*dist_ij->y; + ai->virial.xz-=force.x*dist_ij->z; + ai->virial.yz-=force.y*dist_ij->z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij (3bp) contrib:\n"); + printf("%f | %f\n",force.x,ai->f.x); + printf("%f | %f\n",force.y,ai->f.y); + printf("%f | %f\n",force.z,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij (3bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); +} +#endif + + /* add energy of 3bp sum */ + moldyn->energy+=(0.5*f_c*b*f_a); + + /* dVji */ + zeta=exchange->zeta_ji; + if(zeta==0.0) { + moldyn->debug++; + b=chi; + v3_scale(&force,dist_ij,df_a*b*f_c); + } + else { + tmp=betajnj*pow(zeta,nj-1.0); /* beta^n * zeta^n-1 */ + b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ + db=chi*pow(b,-1.0/(2*nj)-1); /* x(...)^(-1/2n - 1) */ + b=db*b; /* b_ij */ + db*=-0.5*tmp; /* db_ij */ + v3_scale(&force,&(exchange->dzeta_ji),f_a*db); + v3_scale(&temp,dist_ij,df_a*b); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,f_c); + } + v3_scale(&temp,dist_ij,df_c*b*f_a); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,-0.5); + + /* add force */ + v3_add(&(ai->f),&(ai->f),&force); + + /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ +// TEST ... with a minus instead + ai->virial.xx-=force.x*dist_ij->x; + ai->virial.yy-=force.y*dist_ij->y; + ai->virial.zz-=force.z*dist_ij->z; + ai->virial.xy-=force.x*dist_ij->y; + ai->virial.xz-=force.x*dist_ij->z; + ai->virial.yz-=force.y*dist_ij->z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVji (3bp) contrib:\n"); + printf("%f | %f\n",force.x,ai->f.x); + printf("%f | %f\n",force.y,ai->f.y); + printf("%f | %f\n",force.z,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVji (3bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); +} +#endif + + return 0; +} + +/* tersoff 3 body part */ + +int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + t_3dvec dist_ij,dist_ik,dist_jk; + t_3dvec temp1,temp2; + t_3dvec *dzeta; + double R,S,S2,s_r; + double B,mu; + double d_ij,d_ik,d_jk,d_ij2,d_ik2,d_jk2; + double rr,dd; + double f_c,df_c; + double f_c_ik,df_c_ik,arg; + double f_c_jk; + double n,c,d,h; + double c2,d2,c2d2; + double cos_theta,d_costheta1,d_costheta2; + double h_cos,d2_h_cos2; + double frac,g,zeta,chi; + double tmp; + int brand; + + params=moldyn->pot3b_params; + exchange=&(params->exchange); + + if(!(exchange->run3bp)) + return 0; + + /* + * calc of 3bp contribution of V_ij and dV_ij/ji/jk & + * 2bp contribution of dV_jk + * + * for Vij and dV_ij we still need: + * - b_ij, db_ij (zeta_ij) + * - f_c_ik, df_c_ik, constants_i, cos_theta_ijk, d_costheta_ijk + * + * for dV_ji we still need: + * - b_ji, db_ji (zeta_ji) + * - f_c_jk, d_c_jk, constants_j, cos_theta_jik, d_costheta_jik + * + * for dV_jk we need: + * - f_c_jk + * - f_a_jk + * - db_jk (zeta_jk) + * - f_c_ji, df_c_ji, constants_j, cos_theta_jki, d_costheta_jki + * + */ + + /* + * get exchange data + */ + + /* dist_ij, d_ij - this is < S_ij ! */ + dist_ij=exchange->dist_ij; + d_ij=exchange->d_ij; + d_ij2=exchange->d_ij2; + + /* f_c_ij, df_c_ij (same for ji) */ + f_c=exchange->f_c; + df_c=exchange->df_c; + + /* + * calculate unknown values now ... + */ + + /* V_ij and dV_ij stuff (in b_ij there is f_c_ik) */ + + /* dist_ik, d_ik */ + v3_sub(&dist_ik,&(ak->r),&(ai->r)); + if(bc) check_per_bound(moldyn,&dist_ik); + d_ik2=v3_absolute_square(&dist_ik); + + /* ik constants */ + brand=ai->brand; + if(brand==ak->brand) { + R=params->R[brand]; + S=params->S[brand]; + S2=params->S2[brand]; + } + else { + R=params->Rmixed; + S=params->Smixed; + S2=params->S2mixed; + } + + /* zeta_ij/dzeta_ij contribution only for d_ik < S */ + if(d_ik2n_i); + c=*(exchange->c_i); + d=*(exchange->d_i); + h=*(exchange->h_i); + c2=exchange->ci2; + d2=exchange->di2; + c2d2=exchange->ci2di2; + + /* cosine of theta_ijk by scalaproduct */ + rr=v3_scalar_product(&dist_ij,&dist_ik); + dd=d_ij*d_ik; + cos_theta=rr/dd; + + /* d_costheta */ + tmp=1.0/dd; + d_costheta1=cos_theta/d_ij2-tmp; + d_costheta2=cos_theta/d_ik2-tmp; + + /* some usefull values */ + h_cos=(h-cos_theta); + d2_h_cos2=d2+(h_cos*h_cos); + frac=c2/(d2_h_cos2); + + /* g(cos_theta) */ + g=1.0+c2d2-frac; + + /* d_costheta_ij and dg(cos_theta) - needed in any case! */ + v3_scale(&temp1,&dist_ij,d_costheta1); + v3_scale(&temp2,&dist_ik,d_costheta2); + v3_add(&temp1,&temp1,&temp2); + v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ + + /* f_c_ik & df_c_ik + {d,}zeta contribution */ + dzeta=&(exchange->dzeta_ij); + if(d_ik f_c_ik=1.0; + // => df_c_ik=0.0; of course we do not set this! + + /* zeta_ij */ + exchange->zeta_ij+=g; + + /* dzeta_ij */ + v3_add(dzeta,dzeta,&temp1); + } + else { + /* {d,}f_c_ik */ + s_r=S-R; + arg=M_PI*(d_ik-R)/s_r; + f_c_ik=0.5+0.5*cos(arg); + df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik)); + + /* zeta_ij */ + exchange->zeta_ij+=f_c_ik*g; + + /* dzeta_ij */ + v3_scale(&temp1,&temp1,f_c_ik); + v3_scale(&temp2,&dist_ik,g*df_c_ik); + v3_add(&temp1,&temp1,&temp2); + v3_add(dzeta,dzeta,&temp1); + } + } + + /* dV_ji stuff (in b_ji there is f_c_jk) + dV_jk stuff! */ + + /* dist_jk, d_jk */ + v3_sub(&dist_jk,&(ak->r),&(aj->r)); + if(bc) check_per_bound(moldyn,&dist_jk); + d_jk2=v3_absolute_square(&dist_jk); + + /* jk constants */ + brand=aj->brand; + if(brand==ak->brand) { + R=params->R[brand]; + S=params->S[brand]; + S2=params->S2[brand]; + B=params->B[brand]; + mu=params->mu[brand]; + chi=1.0; + } + else { + R=params->Rmixed; + S=params->Smixed; + S2=params->S2mixed; + B=params->Bmixed; + mu=params->mu_m; + chi=params->chi; + } + + /* zeta_ji/dzeta_ji contribution only for d_jk < S_jk */ + if(d_jk2n_j); + c=*(exchange->c_j); + d=*(exchange->d_j); + h=*(exchange->h_j); + c2=exchange->cj2; + d2=exchange->dj2; + c2d2=exchange->cj2dj2; + + /* cosine of theta_jik by scalaproduct */ + rr=-v3_scalar_product(&dist_ij,&dist_jk); /* -1, as ij -> ji */ + dd=d_ij*d_jk; + cos_theta=rr/dd; + + /* d_costheta */ + d_costheta1=1.0/dd; + d_costheta2=cos_theta/d_ij2; + + /* some usefull values */ + h_cos=(h-cos_theta); + d2_h_cos2=d2+(h_cos*h_cos); + frac=c2/(d2_h_cos2); + + /* g(cos_theta) */ + g=1.0+c2d2-frac; + + /* d_costheta_jik and dg(cos_theta) - needed in any case! */ + v3_scale(&temp1,&dist_jk,d_costheta1); + v3_scale(&temp2,&dist_ij,-d_costheta2); /* ji -> ij => -1 */ + //v3_add(&temp1,&temp1,&temp2); + v3_sub(&temp1,&temp1,&temp2); /* there is a minus! */ + v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ + + /* store dg in temp2 and use it for dVjk later */ + v3_copy(&temp2,&temp1); + + /* f_c_jk + {d,}zeta contribution (df_c_jk = 0) */ + dzeta=&(exchange->dzeta_ji); + if(d_jkzeta_ji+=g; + + /* dzeta_ji */ + v3_add(dzeta,dzeta,&temp1); + } + else { + /* f_c_jk */ + s_r=S-R; + arg=M_PI*(d_jk-R)/s_r; + f_c_jk=0.5+0.5*cos(arg); + + /* zeta_ji */ + exchange->zeta_ji+=f_c_jk*g; + + /* dzeta_ji */ + v3_scale(&temp1,&temp1,f_c_jk); + v3_add(dzeta,dzeta,&temp1); + } + + /* dV_jk stuff | add force contribution on atom i immediately */ + if(exchange->d_ij_between_rs) { + zeta=f_c*g; + v3_scale(&temp1,&temp2,f_c); + v3_scale(&temp2,&dist_ij,df_c*g); + v3_add(&temp2,&temp2,&temp1); /* -> dzeta_jk in temp2 */ + } + else { + zeta=g; + // dzeta_jk is simply dg, which is stored in temp2 + } + /* betajnj * zeta_jk ^ nj-1 */ + tmp=exchange->betajnj*pow(zeta,(n-1.0)); + tmp=-chi/2.0*pow((1+tmp*zeta),(-1.0/(2.0*n)-1))*tmp; + v3_scale(&temp2,&temp2,tmp*B*exp(-mu*d_jk)*f_c_jk*0.5); + v3_add(&(ai->f),&(ai->f),&temp2); /* -1 skipped in f_a calc ^ */ + /* scaled with 0.5 ^ */ + + /* virial */ + ai->virial.xx-=temp2.x*dist_jk.x; + ai->virial.yy-=temp2.y*dist_jk.y; + ai->virial.zz-=temp2.z*dist_jk.z; + ai->virial.xy-=temp2.x*dist_jk.y; + ai->virial.xz-=temp2.x*dist_jk.z; + ai->virial.yz-=temp2.y*dist_jk.z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVjk (3bp) contrib:\n"); + printf("%f | %f\n",temp2.x,ai->f.x); + printf("%f | %f\n",temp2.y,ai->f.y); + printf("%f | %f\n",temp2.z,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVjk (3bp) contrib:\n"); + printf("%f | %f\n",temp2.x*dist_jk.x,ai->virial.xx); + printf("%f | %f\n",temp2.y*dist_jk.y,ai->virial.yy); + printf("%f | %f\n",temp2.z*dist_jk.z,ai->virial.zz); +} +#endif + + } + + return 0; +} + -- 2.20.1 From 296a35b943e922173ce648ec76a4472e287af108 Mon Sep 17 00:00:00 2001 From: hackbard Date: Mon, 5 Mar 2007 10:05:23 +0000 Subject: [PATCH 12/16] new structure (skipped 2 inlines) same code! --- Makefile | 2 +- moldyn.c | 56 +++---------- moldyn.h | 138 ++++--------------------------- potentials/harmonic_oscillator.c | 4 +- potentials/lennard_jones.c | 6 +- potentials/tersoff.c | 10 +-- sic.c | 6 +- 7 files changed, 42 insertions(+), 180 deletions(-) diff --git a/Makefile b/Makefile index 37fafcc..3e31459 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ POT_SRC+= potentials/harmonic_oscillator.c all: sic sic: - $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE) $(POT_SRC) sic.c -o sic + $(CC) $(CFLAGS) $(LDFLAGS) $(POT_SRC) $(SOURCE) sic.c -o sic .PHONY:clean clean: diff --git a/moldyn.c b/moldyn.c index 1ab88eb..dae975c 100644 --- a/moldyn.c +++ b/moldyn.c @@ -165,7 +165,6 @@ int set_pbc(t_moldyn *moldyn,u8 x,u8 y,u8 z) { int set_potential1b(t_moldyn *moldyn,pf_func1b func,void *params) { moldyn->func1b=func; - moldyn->pot1b_params=params; return 0; } @@ -173,7 +172,6 @@ int set_potential1b(t_moldyn *moldyn,pf_func1b func,void *params) { int set_potential2b(t_moldyn *moldyn,pf_func2b func,void *params) { moldyn->func2b=func; - moldyn->pot2b_params=params; return 0; } @@ -181,7 +179,6 @@ int set_potential2b(t_moldyn *moldyn,pf_func2b func,void *params) { int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func,void *params) { moldyn->func2b_post=func; - moldyn->pot2b_params=params; return 0; } @@ -189,7 +186,13 @@ int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func,void *params) { int set_potential3b(t_moldyn *moldyn,pf_func3b func,void *params) { moldyn->func3b=func; - moldyn->pot3b_params=params; + + return 0; +} + +int set_potential_params(t_moldyn *moldyn,void *params) { + + moldyn->pot_params=params; return 0; } @@ -1449,7 +1452,8 @@ printf("\n\n"); * virial calculation */ -inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) { +//inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) { +int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) { a->virial.xx+=f->x*d->x; a->virial.yy+=f->y*d->y; @@ -1465,7 +1469,8 @@ inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) { * periodic boundayr checking */ -inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) { +//inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) { +int check_per_bound(t_moldyn *moldyn,t_3dvec *a) { double x,y,z; t_3dvec *dim; @@ -1492,45 +1497,6 @@ inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) { return 0; } - -/* - * example potentials - */ - -/* harmonic oscillator potential and force */ - -int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { - - t_ho_params *params; - t_3dvec force,distance; - double d,f; - double sc,equi_dist; - - params=moldyn->pot2b_params; - sc=params->spring_constant; - equi_dist=params->equilibrium_distance; - - if(air),&(ai->r)); - - if(bc) check_per_bound(moldyn,&distance); - d=v3_norm(&distance); - if(d<=moldyn->cutoff) { - moldyn->energy+=(0.5*sc*(d-equi_dist)*(d-equi_dist)); - /* f = -grad E; grad r_ij = -1 1/r_ij distance */ - f=sc*(1.0-equi_dist/d); - v3_scale(&force,&distance,f); - v3_add(&(ai->f),&(ai->f),&force); - virial_calc(ai,&force,&distance); - virial_calc(aj,&force,&distance); /* f and d signe switched */ - v3_scale(&force,&distance,-f); - v3_add(&(aj->f),&(aj->f),&force); - } - - return 0; -} - /* * debugging / critical check functions */ diff --git a/moldyn.h b/moldyn.h index 3c53a86..1300998 100644 --- a/moldyn.h +++ b/moldyn.h @@ -84,13 +84,11 @@ typedef struct s_moldyn { /* potential force function and parameter pointers */ int (*func1b)(struct s_moldyn *moldyn,t_atom *ai); - void *pot1b_params; int (*func2b)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); int (*func2b_post)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); - void *pot2b_params; int (*func3b)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak, u8 bck); - void *pot3b_params; + void *pot_params; //int (*potential_force_function)(struct s_moldyn *moldyn); double cutoff; /* cutoff radius */ @@ -149,6 +147,12 @@ typedef struct s_moldyn { double debug; /* debugging stuff, ignore */ } t_moldyn; +/* + * + * defines + * + */ + #define MOLDYN_STAT_PBX 0x01 /* periodic boudaries in x */ #define MOLDYN_STAT_PBY 0x02 /* y */ #define MOLDYN_STAT_PBZ 0x04 /* and z direction */ @@ -164,115 +168,6 @@ typedef struct s_moldyn { #define P_SCALE_BERENDSEN 0x04 /* berendsen p control */ #define P_SCALE_DIRECT 0x08 /* direct p control */ -/* - * - * potential parameter structures - * - */ - -/* - * harmonic oscillator potential parameter structure - */ - -typedef struct s_ho_params { - double spring_constant; - double equilibrium_distance; -} t_ho_params; - -/* - * lennard jones potential parameter structure - */ - -typedef struct s_lj_params { - double sigma6; - double sigma12; - double epsilon4; - double uc; -} t_lj_params; - -/* - * tersoff - */ - -/* tersoff exchange structure to exchange 2bp and 3bp calculated values */ -typedef struct s_tersoff_exchange { - double f_c,df_c; - double f_a,df_a; - - t_3dvec dist_ij; - double d_ij2; - double d_ij; - - double chi; - - double *beta_i; - double *beta_j; - double *n_i; - double *n_j; - double *c_i; - double *c_j; - double *d_i; - double *d_j; - double *h_i; - double *h_j; - - double ci2; - double cj2; - double di2; - double dj2; - double ci2di2; - double cj2dj2; - double betaini; - double betajnj; - - u8 run3bp; - u8 run2bp_post; - u8 d_ij_between_rs; - - double zeta_ij; - double zeta_ji; - t_3dvec dzeta_ij; - t_3dvec dzeta_ji; -} t_tersoff_exchange; - -/* tersoff mult (2!) potential parameters */ -typedef struct s_tersoff_mult_params { - double S[2]; /* tersoff cutoff radii */ - double S2[2]; /* tersoff cutoff radii squared */ - double R[2]; /* tersoff cutoff radii */ - double Smixed; /* mixed S radius */ - double S2mixed; /* mixed S radius squared */ - double Rmixed; /* mixed R radius */ - double A[2]; /* factor of tersoff attractive part */ - double B[2]; /* factor of tersoff repulsive part */ - double Amixed; /* mixed A factor */ - double Bmixed; /* mixed B factor */ - double lambda[2]; /* tersoff lambda */ - double lambda_m; /* mixed lambda */ - double mu[2]; /* tersoff mu */ - double mu_m; /* mixed mu */ - - double chi; - - double beta[2]; - double n[2]; - double c[2]; - double d[2]; - double h[2]; - - t_tersoff_exchange exchange; /* exchange between 2bp and 3bp calc */ -} t_tersoff_mult_params; - - - -/* - * - * defines - * - */ - -#define ONE_THIRD (1.0/3.0) - /* * default values * @@ -323,6 +218,8 @@ typedef struct s_tersoff_mult_params { * */ +#define ONE_THIRD (1.0/3.0) + #define K_BOLTZMANN (1.380650524e-23*METER*NEWTON) /* NA/K */ #define EV (1.6021765314e-19*METER*NEWTON) /* NA */ @@ -446,17 +343,12 @@ int moldyn_integrate(t_moldyn *moldyn); int velocity_verlet(t_moldyn *moldyn); int potential_force_calc(t_moldyn *moldyn); -inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) - __attribute__((always_inline)); -inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) - __attribute__((always_inline)); -int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int tersoff_mult_complete_params(t_tersoff_mult_params *p); -int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai); -int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); +int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d); +//inline int virial_calc(t_atom *a,t_3dvec *f,t_3dvec *d) +// __attribute__((always_inline)); +int check_per_bound(t_moldyn *moldyn,t_3dvec *a); +//inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) +// __attribute__((always_inline)); int moldyn_bc_check(t_moldyn *moldyn); diff --git a/potentials/harmonic_oscillator.c b/potentials/harmonic_oscillator.c index 0d933b6..e2a80e4 100644 --- a/potentials/harmonic_oscillator.c +++ b/potentials/harmonic_oscillator.c @@ -17,7 +17,7 @@ #include "../moldyn.h" #include "../math/math.h" -//#include "harmonic_oscillator.h" +#include "harmonic_oscillator.h" int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { @@ -26,7 +26,7 @@ int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { double d,f; double sc,equi_dist; - params=moldyn->pot2b_params; + params=moldyn->pot_params; sc=params->spring_constant; equi_dist=params->equilibrium_distance; diff --git a/potentials/lennard_jones.c b/potentials/lennard_jones.c index 7d45a17..1738ea5 100644 --- a/potentials/lennard_jones.c +++ b/potentials/lennard_jones.c @@ -16,8 +16,8 @@ #include #include "../moldyn.h" -#inlcude "../math/math.h" -//#include "lennard_jones.h" +#include "../math/math.h" +#include "lennard_jones.h" int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { @@ -26,7 +26,7 @@ int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { double d,h1,h2; double eps,sig6,sig12; - params=moldyn->pot2b_params; + params=moldyn->pot_params; eps=params->epsilon4; sig6=params->sigma6; sig12=params->sigma12; diff --git a/potentials/tersoff.c b/potentials/tersoff.c index 87bb187..972075d 100644 --- a/potentials/tersoff.c +++ b/potentials/tersoff.c @@ -17,7 +17,7 @@ #include "../moldyn.h" #include "../math/math.h" -//#include "tersoff.h" +#include "tersoff.h" /* create mixed terms from parameters and set them */ int tersoff_mult_complete_params(t_tersoff_mult_params *p) { @@ -59,7 +59,7 @@ int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) { t_tersoff_exchange *exchange; brand=ai->brand; - params=moldyn->pot1b_params; + params=moldyn->pot_params; exchange=&(params->exchange); /* @@ -95,7 +95,7 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { double s_r; double arg; - params=moldyn->pot2b_params; + params=moldyn->pot_params; brand=aj->brand; exchange=&(params->exchange); @@ -281,7 +281,7 @@ int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { double chi,ni,betaini,nj,betajnj; double zeta; - params=moldyn->pot2b_params; + params=moldyn->pot_params; exchange=&(params->exchange); /* we do not run if f_c_ij was detected to be 0! */ @@ -430,7 +430,7 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { double tmp; int brand; - params=moldyn->pot3b_params; + params=moldyn->pot_params; exchange=&(params->exchange); if(!(exchange->run3bp)) diff --git a/sic.c b/sic.c index f97ffe8..e148709 100644 --- a/sic.c +++ b/sic.c @@ -8,9 +8,13 @@ #include #include "moldyn.h" - #include "posic.h" +/* potential */ +#include "potentials/harmonic_oscillator.h" +#include "potentials/lennard_jones.h" +#include "potentials/tersoff.h" + int hook(void *moldyn,void *hook_params) { t_moldyn *md; -- 2.20.1 From e333d9448b383cd3977f3919b6a1283a1e5e40e8 Mon Sep 17 00:00:00 2001 From: hackbard Date: Mon, 5 Mar 2007 10:12:51 +0000 Subject: [PATCH 13/16] added potential header files --- potentials/harmonic_oscillator.h | 20 ++++++++ potentials/lennard_jones.h | 22 ++++++++ potentials/tersoff.h | 87 ++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 potentials/harmonic_oscillator.h create mode 100644 potentials/lennard_jones.h create mode 100644 potentials/tersoff.h diff --git a/potentials/harmonic_oscillator.h b/potentials/harmonic_oscillator.h new file mode 100644 index 0000000..c9c9891 --- /dev/null +++ b/potentials/harmonic_oscillator.h @@ -0,0 +1,20 @@ +/* + * harmonic_oscillator.h - harmonic oscillator potential header file + * + * author: Frank Zirkelbach + * + */ + +#ifndef HARMONIC_OSCILLATOR_H +#define HARMONIC_OSCILLATOR_H + +/* types */ +typedef struct s_ho_params { + double spring_constant; + double equilibrium_distance; +} t_ho_params; + +/* function prototype */ +int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); + +#endif diff --git a/potentials/lennard_jones.h b/potentials/lennard_jones.h new file mode 100644 index 0000000..617658b --- /dev/null +++ b/potentials/lennard_jones.h @@ -0,0 +1,22 @@ +/* + * lennard_jones.h - lennard jones potential header file + * + * author: Frank Zirkelbach + * + */ + +#ifndef LENNARD_JONES_H +#define LENNARD_JONES_H + +/* types */ +typedef struct s_lj_params { + double sigma6; + double sigma12; + double epsilon4; + double uc; +} t_lj_params; + +/* function prototype */ +int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); + +#endif diff --git a/potentials/tersoff.h b/potentials/tersoff.h new file mode 100644 index 0000000..a04ed02 --- /dev/null +++ b/potentials/tersoff.h @@ -0,0 +1,87 @@ +/* + * tersoff.h - tersoff potential header file + * + * author: Frank Zirkelbach + * + */ + +#ifndef TERSOFF_H +#define TERSOFF_H + +/* tersoff exchange type */ +typedef struct s_tersoff_echange { + double f_c,df_c; + double f_a,df_a; + + t_3dvec dist_ij; + double d_ij2; + double d_ij; + + double chi; + + double *beta_i; + double *beta_j; + double *n_i; + double *n_j; + double *c_i; + double *c_j; + double *d_i; + double *d_j; + double *h_i; + double *h_j; + + double ci2; + double cj2; + double di2; + double dj2; + double ci2di2; + double cj2dj2; + double betaini; + double betajnj; + + u8 run3bp; + u8 run2bp_post; + u8 d_ij_between_rs; + + double zeta_ij; + double zeta_ji; + t_3dvec dzeta_ij; + t_3dvec dzeta_ji; +} t_tersoff_exchange; + +/* tersoff mult (2!) potential parameters */ +typedef struct s_tersoff_mult_params { + double S[2]; /* tersoff cutoff radii */ + double S2[2]; /* tersoff cutoff radii squared */ + double R[2]; /* tersoff cutoff radii */ + double Smixed; /* mixed S radius */ + double S2mixed; /* mixed S radius squared */ + double Rmixed; /* mixed R radius */ + double A[2]; /* factor of tersoff attractive part */ + double B[2]; /* factor of tersoff repulsive part */ + double Amixed; /* mixed A factor */ + double Bmixed; /* mixed B factor */ + double lambda[2]; /* tersoff lambda */ + double lambda_m; /* mixed lambda */ + double mu[2]; /* tersoff mu */ + double mu_m; /* mixed mu */ + + double chi; + + double beta[2]; + double n[2]; + double c[2]; + double d[2]; + double h[2]; + + t_tersoff_exchange exchange; /* exchange between 2bp and 3bp calc */ +} t_tersoff_mult_params; + +/* function prototypes */ +int tersoff_mult_complete_params(t_tersoff_mult_params *p); +int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai); +int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); + +#endif -- 2.20.1 From e25ff194682ff5fac86c60701343103e74973bed Mon Sep 17 00:00:00 2001 From: hackbard Date: Wed, 7 Mar 2007 16:23:21 +0000 Subject: [PATCH 14/16] tersoff MAYBE fixed now! --- moldyn.c | 8 +++--- moldyn.h | 13 +++++----- potentials/lennard_jones.c | 3 ++- potentials/tersoff.c | 39 ++++++++++++++--------------- sic.c | 50 +++++++++++++++++++++++--------------- 5 files changed, 64 insertions(+), 49 deletions(-) diff --git a/moldyn.c b/moldyn.c index dae975c..ca6f84a 100644 --- a/moldyn.c +++ b/moldyn.c @@ -162,28 +162,28 @@ int set_pbc(t_moldyn *moldyn,u8 x,u8 y,u8 z) { return 0; } -int set_potential1b(t_moldyn *moldyn,pf_func1b func,void *params) { +int set_potential1b(t_moldyn *moldyn,pf_func1b func) { moldyn->func1b=func; return 0; } -int set_potential2b(t_moldyn *moldyn,pf_func2b func,void *params) { +int set_potential2b(t_moldyn *moldyn,pf_func2b func) { moldyn->func2b=func; return 0; } -int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func,void *params) { +int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func) { moldyn->func2b_post=func; return 0; } -int set_potential3b(t_moldyn *moldyn,pf_func3b func,void *params) { +int set_potential3b(t_moldyn *moldyn,pf_func3b func) { moldyn->func3b=func; diff --git a/moldyn.h b/moldyn.h index 1300998..b140372 100644 --- a/moldyn.h +++ b/moldyn.h @@ -230,9 +230,9 @@ typedef struct s_moldyn { #define LC_SI (0.543105e-9*METER) /* A */ #define M_SI 28.08553 /* amu */ -//#define LJ_SIGMA_SI ((0.25*sqrt(3.0)*LC_SI)/1.122462) /* A */ +#define LJ_SIGMA_SI ((0.25*sqrt(3.0)*LC_SI)/1.122462) /* A */ //#define LJ_SIGMA_SI (LC_SI/1.122462) /* A */ -#define LJ_SIGMA_SI (0.5*sqrt(2.0)*LC_SI/1.122462) /* A */ +//#define LJ_SIGMA_SI (0.5*sqrt(2.0)*LC_SI/1.122462) /* A */ #define LJ_EPSILON_SI (2.1678*EV) /* NA */ #define TM_R_SI (2.7e-10*METER) /* A */ @@ -292,10 +292,11 @@ int set_pt_scale(t_moldyn *moldyn,u8 ptype,double ptc,u8 ttype,double ttc); int set_dim(t_moldyn *moldyn,double x,double y,double z,u8 visualize); int set_nn_dist(t_moldyn *moldyn,double dist); int set_pbc(t_moldyn *moldyn,u8 x,u8 y,u8 z); -int set_potential1b(t_moldyn *moldyn,pf_func1b func,void *params); -int set_potential2b(t_moldyn *moldyn,pf_func2b func,void *params); -int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func,void *params); -int set_potential3b(t_moldyn *moldyn,pf_func3b func,void *params); +int set_potential1b(t_moldyn *moldyn,pf_func1b func); +int set_potential2b(t_moldyn *moldyn,pf_func2b func); +int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func); +int set_potential3b(t_moldyn *moldyn,pf_func3b func); +int set_potential_params(t_moldyn *moldyn,void *params); int moldyn_set_log_dir(t_moldyn *moldyn,char *dir); int moldyn_set_report(t_moldyn *moldyn,char *author,char *title); diff --git a/potentials/lennard_jones.c b/potentials/lennard_jones.c index 1738ea5..1277c46 100644 --- a/potentials/lennard_jones.c +++ b/potentials/lennard_jones.c @@ -35,10 +35,11 @@ int lennard_jones(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { v3_sub(&distance,&(aj->r),&(ai->r)); if(bc) check_per_bound(moldyn,&distance); - d=v3_absolute_square(&distance); /* 1/r^2 */ + d=v3_absolute_square(&distance); /* r^2 */ if(d<=moldyn->cutoff_square) { d=1.0/d; /* 1/r^2 */ h2=d*d; /* 1/r^4 */ + h2*=d; /* 1/r^6 */ h1=h2*h2; /* 1/r^12 */ moldyn->energy+=(eps*(sig12*h1-sig6*h2)-params->uc); h2*=d; /* 1/r^8 */ diff --git a/potentials/tersoff.c b/potentials/tersoff.c index 972075d..01364ea 100644 --- a/potentials/tersoff.c +++ b/potentials/tersoff.c @@ -95,6 +95,9 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { double s_r; double arg; + /* use newtons third law */ + //if(aipot_params; brand=aj->brand; exchange=&(params->exchange); @@ -119,27 +122,11 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { * */ - /* constants */ - if(brand==ai->brand) { - S=params->S[brand]; + /* determine cutoff square */ + if(brand==ai->brand) S2=params->S2[brand]; - R=params->R[brand]; - A=params->A[brand]; - B=params->B[brand]; - lambda=params->lambda[brand]; - mu=params->mu[brand]; - exchange->chi=1.0; - } - else { - S=params->Smixed; + else S2=params->S2mixed; - R=params->Rmixed; - A=params->Amixed; - B=params->Bmixed; - lambda=params->lambda_m; - mu=params->mu_m; - params->exchange.chi=params->chi; - } /* dist_ij, d_ij */ v3_sub(&dist_ij,&(aj->r),&(ai->r)); @@ -166,12 +153,26 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { exchange->d_j=&(params->d[brand]); exchange->h_j=&(params->h[brand]); if(brand==ai->brand) { + S=params->S[brand]; + R=params->R[brand]; + A=params->A[brand]; + B=params->B[brand]; + lambda=params->lambda[brand]; + mu=params->mu[brand]; + exchange->chi=1.0; exchange->betajnj=exchange->betaini; exchange->cj2=exchange->ci2; exchange->dj2=exchange->di2; exchange->cj2dj2=exchange->ci2di2; } else { + S=params->Smixed; + R=params->Rmixed; + A=params->Amixed; + B=params->Bmixed; + lambda=params->lambda_m; + mu=params->mu_m; + params->exchange.chi=params->chi; exchange->betajnj=pow(*(exchange->beta_j),*(exchange->n_j)); exchange->cj2=params->c[brand]*params->c[brand]; exchange->dj2=params->d[brand]*params->d[brand]; diff --git a/sic.c b/sic.c index e148709..167735f 100644 --- a/sic.c +++ b/sic.c @@ -51,6 +51,8 @@ int main(int argc,char **argv) { /* testing location & velocity vector */ t_3dvec r,v; + memset(&r,0,sizeof(t_3dvec)); + memset(&v,0,sizeof(t_3dvec)); /* initialize moldyn */ moldyn_init(&md,argc,argv); @@ -59,17 +61,20 @@ int main(int argc,char **argv) { set_int_alg(&md,MOLDYN_INTEGRATE_VERLET); /* choose potential */ - //set_potential1b(&md,tersoff_mult_1bp,&tp); - //set_potential2b(&md,tersoff_mult_2bp,&tp); - //set_potential2b_post(&md,tersoff_mult_post_2bp,&tp); - //set_potential3b(&md,tersoff_mult_3bp,&tp); - set_potential2b(&md,lennard_jones,&lj); - //set_potential2b(&md,harmonic_oscillator,&ho); + set_potential1b(&md,tersoff_mult_1bp); + set_potential2b(&md,tersoff_mult_2bp); + set_potential2b_post(&md,tersoff_mult_post_2bp); + set_potential3b(&md,tersoff_mult_3bp); + //set_potential2b(&md,lennard_jones); + //set_potential2b(&md,harmonic_oscillator); + set_potential_params(&md,&tp); + //set_potential_params(&md,&lj); + //set_potential_params(&md,&ho); /* cutoff radius */ - //set_cutoff(&md,TM_S_SI); - //set_cutoff(&md,2*LC_SI*0.5*sqrt(1.5)); - set_cutoff(&md,2.0*LC_SI); + set_cutoff(&md,TM_S_SI); + //set_cutoff(&md,LC_SI*sqrt(3.0)); + //set_cutoff(&md,2.0*LC_SI); /* * potential parameters @@ -83,8 +88,8 @@ int main(int argc,char **argv) { lj.uc=lj.epsilon4*(lj.sigma12/pow(md.cutoff,12.0)-lj.sigma6/pow(md.cutoff,6)); /* harmonic oscillator */ - //ho.equilibrium_distance=0.25*sqrt(3.0)*LC_SI; - ho.equilibrium_distance=LC_SI; + ho.equilibrium_distance=0.25*sqrt(3.0)*LC_SI; + //ho.equilibrium_distance=LC_SI; ho.spring_constant=LJ_EPSILON_SI; /* @@ -126,16 +131,16 @@ int main(int argc,char **argv) { /* create the lattice / place atoms */ //create_lattice(&md,CUBIC,LC_SI,SI,M_SI, - create_lattice(&md,FCC,LC_SI,SI,M_SI, - //create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, - // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, - ATOM_ATTR_2BP|ATOM_ATTR_HB, + //create_lattice(&md,FCC,LC_SI,SI,M_SI, + create_lattice(&md,DIAMOND,LC_SI,SI,M_SI, + ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, + // ATOM_ATTR_2BP|ATOM_ATTR_HB, 0,6,6,6); moldyn_bc_check(&md); /* testing configuration */ - //r.x=0.28*sqrt(3)*LC_SI/2; v.x=0; - //r.x=1.75*LC_SI; v.x=-0.01; + //r.x=0.27*sqrt(3.0)*LC_SI/2.0; v.x=0; + //r.x=(TM_S_SI+TM_R_SI)/4.0; v.x=0; //r.y=0; v.y=0; //r.z=0; v.z=0; //add_atom(&md,SI,M_SI,0, @@ -149,6 +154,13 @@ int main(int argc,char **argv) { // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, // ATOM_ATTR_2BP|ATOM_ATTR_HB, // &r,&v); + //r.x=0; v.x=0; + //r.y=0; v.y=0; + //r.z=sin(M_PI*60.0/180.0)*(TM_S_SI+TM_R_SI)/4.0; v.z=0; + //add_atom(&md,SI,M_SI,0, + // ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, + // ATOM_ATTR_2BP|ATOM_ATTR_HB, + // &r,&v); /* set temperature & pressure */ set_temperature(&md,atof(argv[2])+273.0); @@ -164,7 +176,7 @@ int main(int argc,char **argv) { thermal_init(&md,TRUE); /* create the simulation schedule */ - moldyn_add_schedule(&md,101,1.0); + moldyn_add_schedule(&md,10001,1.0); //moldyn_add_schedule(&md,501,1.0); //moldyn_add_schedule(&md,501,1.0); @@ -175,7 +187,7 @@ int main(int argc,char **argv) { moldyn_set_log_dir(&md,argv[1]); moldyn_set_report(&md,"Frank Zirkelbach","Test 1"); moldyn_set_log(&md,LOG_TOTAL_ENERGY,1); - moldyn_set_log(&md,VISUAL_STEP,1); + moldyn_set_log(&md,VISUAL_STEP,100); moldyn_set_log(&md,CREATE_REPORT,0); /* -- 2.20.1 From ea612b88a0588b8f46fafaebf3b37fb46c83c0cf Mon Sep 17 00:00:00 2001 From: hackbard Date: Wed, 14 Mar 2007 15:12:05 +0000 Subject: [PATCH 15/16] improved log/report subsystem, playing around w/ pressure, sic hook testing --- moldyn.c | 192 ++++++++++++++++++++++++++++++++----------- moldyn.h | 16 +++- potentials/tersoff.c | 39 +++++---- report/report.h | 55 ++++++++++++- sic.c | 65 ++++++++++++--- 5 files changed, 282 insertions(+), 85 deletions(-) diff --git a/moldyn.c b/moldyn.c index ca6f84a..9a62b9f 100644 --- a/moldyn.c +++ b/moldyn.c @@ -246,6 +246,32 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { dprintf(moldyn->efd,"# total momentum log file\n"); printf("total momentum (%d)\n",timer); break; + case LOG_PRESSURE: + moldyn->pwrite=timer; + snprintf(filename,127,"%s/pressure",moldyn->vlsdir); + moldyn->pfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->pfd<0) { + perror("[moldyn] pressure log file\n"); + return moldyn->pfd; + } + dprintf(moldyn->pfd,"# pressure log file\n"); + printf("pressure (%d)\n",timer); + break; + case LOG_TEMPERATURE: + moldyn->twrite=timer; + snprintf(filename,127,"%s/temperature",moldyn->vlsdir); + moldyn->tfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->tfd<0) { + perror("[moldyn] temperature log file\n"); + return moldyn->tfd; + } + dprintf(moldyn->tfd,"# temperature log file\n"); + printf("temperature (%d)\n",timer); + break; case SAVE_STEP: moldyn->swrite=timer; printf("save file (%d)\n",timer); @@ -268,18 +294,47 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { perror("[moldyn] report fd open"); return moldyn->rfd; } - snprintf(filename,127,"%s/plot.scr",moldyn->vlsdir); - moldyn->pfd=open(filename, - O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR); - if(moldyn->pfd<0) { - perror("[moldyn] plot fd open"); - return moldyn->pfd; + if(moldyn->efd) { + snprintf(filename,127,"%s/e_plot.scr", + moldyn->vlsdir); + moldyn->epfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->epfd<0) { + perror("[moldyn] energy plot fd open"); + return moldyn->epfd; + } + dprintf(moldyn->epfd,e_plot_script); + close(moldyn->epfd); + } + if(moldyn->pfd) { + snprintf(filename,127,"%s/pressure_plot.scr", + moldyn->vlsdir); + moldyn->ppfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->ppfd<0) { + perror("[moldyn] p plot fd open"); + return moldyn->ppfd; + } + dprintf(moldyn->ppfd,pressure_plot_script); + close(moldyn->ppfd); + } + if(moldyn->tfd) { + snprintf(filename,127,"%s/temperature_plot.scr", + moldyn->vlsdir); + moldyn->tpfd=open(filename, + O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR); + if(moldyn->tpfd<0) { + perror("[moldyn] t plot fd open"); + return moldyn->tpfd; + } + dprintf(moldyn->tpfd,temperature_plot_script); + close(moldyn->tpfd); } dprintf(moldyn->rfd,report_start, moldyn->rauthor,moldyn->rtitle); - dprintf(moldyn->pfd,plot_script); - close(moldyn->pfd); break; default: printf("unknown log type: %02x\n",type); @@ -294,13 +349,35 @@ int moldyn_log_shutdown(t_moldyn *moldyn) { char sc[256]; printf("[moldyn] log shutdown\n"); - if(moldyn->efd) close(moldyn->efd); + if(moldyn->efd) { + close(moldyn->efd); + if(moldyn->rfd) { + dprintf(moldyn->rfd,report_energy); + snprintf(sc,255,"cd %s && gnuplot e_plot.scr", + moldyn->vlsdir); + system(sc); + } + } if(moldyn->mfd) close(moldyn->mfd); + if(moldyn->pfd) { + close(moldyn->pfd); + if(moldyn->rfd) + dprintf(moldyn->rfd,report_pressure); + snprintf(sc,255,"cd %s && gnuplot pressure_plot.scr", + moldyn->vlsdir); + system(sc); + } + if(moldyn->tfd) { + close(moldyn->tfd); + if(moldyn->rfd) + dprintf(moldyn->rfd,report_temperature); + snprintf(sc,255,"cd %s && gnuplot temperature_plot.scr", + moldyn->vlsdir); + system(sc); + } if(moldyn->rfd) { dprintf(moldyn->rfd,report_end); close(moldyn->rfd); - snprintf(sc,255,"cd %s && gnuplot plot.scr",moldyn->vlsdir); - system(sc); snprintf(sc,255,"cd %s && pdflatex report",moldyn->vlsdir); system(sc); snprintf(sc,255,"cd %s && pdflatex report",moldyn->vlsdir); @@ -676,9 +753,11 @@ double pressure_calc(t_moldyn *moldyn) { t_virial *virial; /* - * P = 1/(3V) sum_i ( p_i^2 / 2m + f_i r_i ) - * - * virial = f_i r_i + * PV = NkT + + * W = 1/3 sum_i f_i r_i + * virial = sum_i f_i r_i + * + * => P = (2 Ekin + virial) / (3V) */ v=0.0; @@ -698,9 +777,20 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { t_3dvec dim,*tp; double u,p; - double scale; + double scale,dv; t_atom *store; + /* + * dU = - p dV + * + * => p = - dU/dV + * + * dV: dx,y,z = 0.001 x,y,z + */ + + scale=1.00001; +printf("\n\nP-DEBUG:\n"); + tp=&(moldyn->tp); store=malloc(moldyn->count*sizeof(t_atom)); if(store==NULL) { @@ -714,27 +804,28 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { dim=moldyn->dim; /* derivative with respect to x direction */ - scale=1.0+moldyn->dv/(moldyn->dim.y*moldyn->dim.z); scale_dim(moldyn,scale,TRUE,0,0); scale_atoms(moldyn,scale,TRUE,0,0); + dv=0.00001*moldyn->dim.x*moldyn->dim.y*moldyn->dim.z; link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); - tp->x=(moldyn->energy-u)/moldyn->dv; + tp->x=(moldyn->energy-u)/dv; p=tp->x*tp->x; +printf("e: %f eV de: %f eV dV: %f A^3\n",moldyn->energy/moldyn->count/EV,(moldyn->energy-u)/moldyn->count/EV,dv); /* restore atomic configuration + dim */ memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); moldyn->dim=dim; /* derivative with respect to y direction */ - scale=1.0+moldyn->dv/(moldyn->dim.x*moldyn->dim.z); scale_dim(moldyn,scale,0,TRUE,0); scale_atoms(moldyn,scale,0,TRUE,0); + dv=0.00001*moldyn->dim.y*moldyn->dim.x*moldyn->dim.z; link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); - tp->y=(moldyn->energy-u)/moldyn->dv; + tp->y=(moldyn->energy-u)/dv; p+=tp->y*tp->y; /* restore atomic configuration + dim */ @@ -742,37 +833,19 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { moldyn->dim=dim; /* derivative with respect to z direction */ - scale=1.0+moldyn->dv/(moldyn->dim.x*moldyn->dim.y); scale_dim(moldyn,scale,0,0,TRUE); scale_atoms(moldyn,scale,0,0,TRUE); + dv=0.00001*moldyn->dim.z*moldyn->dim.x*moldyn->dim.y; link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); - tp->z=(moldyn->energy-u)/moldyn->dv; + tp->z=(moldyn->energy-u)/dv; p+=tp->z*tp->z; /* restore atomic configuration + dim */ memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); moldyn->dim=dim; - printf("dU/dV komp addiert = %f %f %f\n",tp->x,tp->y,tp->z); - - scale=1.0+pow(moldyn->dv/moldyn->volume,ONE_THIRD); - -printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); - scale_dim(moldyn,scale,1,1,1); - scale_atoms(moldyn,scale,1,1,1); - link_cell_shutdown(moldyn); - link_cell_init(moldyn,QUIET); - potential_force_calc(moldyn); -printf("debug: %f %f\n",moldyn->atom[0].r.x,moldyn->dim.x); - - printf("dU/dV einfach = %f\n",((moldyn->energy-u)/moldyn->dv)/ATM); - - /* restore atomic configuration + dim */ - memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); - moldyn->dim=dim; - /* restore energy */ moldyn->energy=u; @@ -1109,14 +1182,15 @@ int moldyn_set_schedule_hook(t_moldyn *moldyn,set_hook hook,void *hook_params) { int moldyn_integrate(t_moldyn *moldyn) { int i; - unsigned int e,m,s,v; - t_3dvec p; + unsigned int e,m,s,v,p,t; + t_3dvec momentum; t_moldyn_schedule *sched; t_atom *atom; int fd; char dir[128]; double ds; double energy_scale; + //double tp; sched=&(moldyn->schedule); atom=moldyn->atom; @@ -1129,6 +1203,8 @@ int moldyn_integrate(t_moldyn *moldyn) { m=moldyn->mwrite; s=moldyn->swrite; v=moldyn->vwrite; + p=moldyn->pwrite; + t=moldyn->twrite; /* sqaure of some variables */ moldyn->tau_square=moldyn->tau*moldyn->tau; @@ -1179,7 +1255,7 @@ int moldyn_integrate(t_moldyn *moldyn) { update_e_kin(moldyn); temperature_calc(moldyn); pressure_calc(moldyn); - //thermodynamic_pressure_calc(moldyn); + //tp=thermodynamic_pressure_calc(moldyn); /* p/t scaling */ if(moldyn->pt_scale&(T_SCALE_BERENDSEN|T_SCALE_DIRECT)) @@ -1198,9 +1274,23 @@ int moldyn_integrate(t_moldyn *moldyn) { } if(m) { if(!(i%m)) { - p=get_total_p(moldyn); + momentum=get_total_p(moldyn); dprintf(moldyn->mfd, - "%f %f\n",moldyn->time,v3_norm(&p)); + "%f %f %f %f %f\n",moldyn->time, + momentum.x,momentum.y,momentum.z, + v3_norm(&momentum)); + } + } + if(p) { + if(!(i%p)) { + dprintf(moldyn->pfd, + "%f %f\n",moldyn->time,moldyn->p/ATM); + } + } + if(t) { + if(!(i%t)) { + dprintf(moldyn->tfd, + "%f %f\n",moldyn->time,moldyn->t); } } if(s) { @@ -1221,13 +1311,17 @@ int moldyn_integrate(t_moldyn *moldyn) { if(!(i%v)) { visual_atoms(&(moldyn->vis),moldyn->time, moldyn->atom,moldyn->count); - printf("\rsched: %d, steps: %d, T: %f, P: %f V: %f", - sched->count,i, - moldyn->t,moldyn->p/ATM,moldyn->volume); - fflush(stdout); } } + /* display progress */ + if(!(i%10)) { + printf("\rsched: %d, steps: %d, T: %f, P: %f V: %f", + sched->count,i, + moldyn->t,moldyn->p/ATM,moldyn->volume); + fflush(stdout); + } + /* increase absolute time */ moldyn->time+=moldyn->tau; diff --git a/moldyn.h b/moldyn.h index b140372..85a4950 100644 --- a/moldyn.h +++ b/moldyn.h @@ -133,12 +133,18 @@ typedef struct s_moldyn { int efd; /* fd for energy log */ unsigned int mwrite; /* how often to log momentum */ int mfd; /* fd for momentum log */ + unsigned int pwrite; /* how often to log pressure */ + int pfd; /* fd for pressure log */ + unsigned int twrite; /* how often to log temperature */ + int tfd; /* fd for temperature log */ unsigned int vwrite; /* how often to visualize atom information */ unsigned int swrite; /* how often to create a save file */ int rfd; /* report file descriptor */ char rtitle[64]; /* report title */ char rauthor[64]; /* report author */ - int pfd; /* gnuplot script file descriptor */ + int epfd; /* energy gnuplot script file descriptor */ + int ppfd; /* pressure gnuplot script file descriptor */ + int tpfd; /* temperature gnuplot script file descriptor */ u8 status; /* general moldyn properties */ @@ -201,9 +207,11 @@ typedef struct s_moldyn { #define LOG_TOTAL_ENERGY 0x01 #define LOG_TOTAL_MOMENTUM 0x02 -#define SAVE_STEP 0x04 -#define VISUAL_STEP 0x08 -#define CREATE_REPORT 0x10 +#define LOG_PRESSURE 0x04 +#define LOG_TEMPERATURE 0x08 +#define SAVE_STEP 0x10 +#define VISUAL_STEP 0x20 +#define CREATE_REPORT 0x40 #define TRUE 1 #define FALSE 0 diff --git a/potentials/tersoff.c b/potentials/tersoff.c index 01364ea..16f771c 100644 --- a/potentials/tersoff.c +++ b/potentials/tersoff.c @@ -211,12 +211,13 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { v3_add(&(ai->f),&(ai->f),&force); /* virial */ - ai->virial.xx-=force.x*dist_ij.x; - ai->virial.yy-=force.y*dist_ij.y; - ai->virial.zz-=force.z*dist_ij.z; - ai->virial.xy-=force.x*dist_ij.y; - ai->virial.xz-=force.x*dist_ij.z; - ai->virial.yz-=force.y*dist_ij.z; + virial_calc(ai,&force,&dist_ij); + //ai->virial.xx-=force.x*dist_ij.x; + //ai->virial.yy-=force.y*dist_ij.y; + //ai->virial.zz-=force.z*dist_ij.z; + //ai->virial.xy-=force.x*dist_ij.y; + //ai->virial.xz-=force.x*dist_ij.z; + //ai->virial.yz-=force.y*dist_ij.z; #ifdef DEBUG if(ai==&(moldyn->atom[0])) { @@ -326,12 +327,13 @@ int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { v3_add(&(ai->f),&(ai->f),&force); /* virial */ - ai->virial.xx-=force.x*dist_ij->x; - ai->virial.yy-=force.y*dist_ij->y; - ai->virial.zz-=force.z*dist_ij->z; - ai->virial.xy-=force.x*dist_ij->y; - ai->virial.xz-=force.x*dist_ij->z; - ai->virial.yz-=force.y*dist_ij->z; + virial_calc(ai,&force,dist_ij); + //ai->virial.xx-=force.x*dist_ij->x; + //ai->virial.yy-=force.y*dist_ij->y; + //ai->virial.zz-=force.z*dist_ij->z; + //ai->virial.xy-=force.x*dist_ij->y; + //ai->virial.xz-=force.x*dist_ij->z; + //ai->virial.yz-=force.y*dist_ij->z; #ifdef DEBUG if(ai==&(moldyn->atom[0])) { @@ -380,12 +382,13 @@ if(ai==&(moldyn->atom[0])) { /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ // TEST ... with a minus instead - ai->virial.xx-=force.x*dist_ij->x; - ai->virial.yy-=force.y*dist_ij->y; - ai->virial.zz-=force.z*dist_ij->z; - ai->virial.xy-=force.x*dist_ij->y; - ai->virial.xz-=force.x*dist_ij->z; - ai->virial.yz-=force.y*dist_ij->z; + virial_calc(ai,&force,dist_ij); + //ai->virial.xx-=force.x*dist_ij->x; + //ai->virial.yy-=force.y*dist_ij->y; + //ai->virial.zz-=force.z*dist_ij->z; + //ai->virial.xy-=force.x*dist_ij->y; + //ai->virial.xz-=force.x*dist_ij->z; + //ai->virial.yz-=force.y*dist_ij->z; #ifdef DEBUG if(ai==&(moldyn->atom[0])) { diff --git a/report/report.h b/report/report.h index e46ff2a..4fe42f7 100644 --- a/report/report.h +++ b/report/report.h @@ -34,17 +34,38 @@ static char report_start[]="\ \\maketitle\n\ "; -static char report_end[]="\ +static char report_energy[]="\ \\begin{figure}[!h]\n\ \\begin{center}\n\ \\includegraphics[width=16cm]{energy.eps}\n\ \\caption{Kinetic, potential and total energy over time}\n\ \\end{center}\n\ \\end{figure}\n\ +"; + +static char report_pressure[]="\ +\\begin{figure}[!h]\n\ +\\begin{center}\n\ +\\includegraphics[width=16cm]{pressure.eps}\n\ +\\caption{Pressure over time}\n\ +\\end{center}\n\ +\\end{figure}\n\ +"; + +static char report_temperature[]="\ +\\begin{figure}[!h]\n\ +\\begin{center}\n\ +\\includegraphics[width=16cm]{temperature.eps}\n\ +\\caption{Temperature over time}\n\ +\\end{center}\n\ +\\end{figure}\n\ +"; + +static char report_end[]="\ \\end{document}\n\ "; -static char plot_script[]="\ +static char e_plot_script[]="\ set autoscale \n\ unset log \n\ unset label \n\ @@ -55,7 +76,35 @@ set xlabel 'Time [fs]' \n\ set ylabel 'Energy per atom [eV]' \n\ set terminal postscript eps enhanced color solid lw 1 'Helvetica' 14 \n\ set output 'energy.eps' \n\ -plot \"energy\" using 1:2 title 'Kinetic energy' with lines , \"energy\" using 1:3 title 'Potential energy' with lines , \"energy\" using 1:4 title 'Total energy' with lines\ +plot \"energy\" using 1:2 title 'Kinetic energy' with lines , \"energy\" using 1:3 title 'Potential energy' with lines , \"energy\" using 1:4 title 'Total energy' with lines \ +"; + +static char pressure_plot_script[]="\ +set autoscale \n\ +unset log \n\ +unset label \n\ +set xtic auto \n\ +set ytic auto \n\ +set title 'Pressure vs. time' \n\ +set xlabel 'Time [fs]' \n\ +set ylabel 'Pressure [atm]' \n\ +set terminal postscript eps enhanced color solid lw 1 'Helvetica' 14 \n\ +set output 'pressure.eps' \n\ +plot \"pressure\" using 1:2 title 'Pressure' with lines \ +"; + +static char temperature_plot_script[]="\ +set autoscale \n\ +unset log \n\ +unset label \n\ +set xtic auto \n\ +set ytic auto \n\ +set title 'Temperature vs. time' \n\ +set xlabel 'Time [fs]' \n\ +set ylabel 'Temperature [K]' \n\ +set terminal postscript eps enhanced color solid lw 1 'Helvetica' 14 \n\ +set output 'temperature.eps' \n\ +plot \"temperature\" using 1:2 title 'Temperature' with lines \ "; #endif diff --git a/sic.c b/sic.c index 167735f..682d89e 100644 --- a/sic.c +++ b/sic.c @@ -15,20 +15,51 @@ #include "potentials/lennard_jones.h" #include "potentials/tersoff.h" +#define INJECT 20 +#define NR_ATOMS 20 + int hook(void *moldyn,void *hook_params) { t_moldyn *md; + t_3dvec r,v,dist; + double d; + unsigned char run; + int i,j; + t_atom *atom; md=moldyn; - /* switch to direct scaling in first hook */ - if(md->schedule.count==0) + printf("\nschedule hook: "); + + if(!(md->schedule.count%2)) { + /* add carbon at random place, and enable t scaling */ + for(j=0;jrandom))*md->dim.x; + r.y=rand_get_double(&(md->random))*md->dim.y; + r.z=rand_get_double(&(md->random))*md->dim.z; + for(i=0;icount;i++) { + atom=&(md->atom[i]); + v3_sub(&dist,&(atom->r),&r); + d=v3_absolute_square(&dist); + if(d>TM_R_C) + run=0; + } + } + v.x=0; v.y=0; v.z=0; + add_atom(md,C,M_C,1, + ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB, + &r,&v); + } + printf("adding atoms & enable t scaling\n"); set_pt_scale(md,0,0,T_SCALE_BERENDSEN,100.0); - /* switch off temp scaling in second hook */ - if(md->schedule.count==1) + } + else { + /* disable t scaling */ + printf("disabling t scaling\n"); set_pt_scale(md,0,0,0,0); - - //set_temperature(md,md->t_ref-100.0); + } return 0; } @@ -49,6 +80,9 @@ int main(int argc,char **argv) { t_ho_params ho; t_tersoff_mult_params tp; + /* atom injection counter */ + int inject; + /* testing location & velocity vector */ t_3dvec r,v; memset(&r,0,sizeof(t_3dvec)); @@ -176,18 +210,27 @@ int main(int argc,char **argv) { thermal_init(&md,TRUE); /* create the simulation schedule */ - moldyn_add_schedule(&md,10001,1.0); - //moldyn_add_schedule(&md,501,1.0); - //moldyn_add_schedule(&md,501,1.0); + /* initial configuration */ + moldyn_add_schedule(&md,500,1.0); + /* adding atoms */ + for(inject=0;inject Date: Fri, 27 Apr 2007 16:39:13 +0000 Subject: [PATCH 16/16] add another way of calculating tersoff + small moldyn mods --- Makefile | 7 +- moldyn.c | 253 +++++++++--- moldyn.h | 53 ++- potentials/tersoff.c | 826 ++++++++++++++++---------------------- potentials/tersoff.h | 42 +- potentials/tersoff_orig.c | 707 ++++++++++++++++++++++++++++++++ potentials/tersoff_orig.h | 87 ++++ report/report.h | 6 +- sic.c | 36 +- 9 files changed, 1418 insertions(+), 599 deletions(-) create mode 100644 potentials/tersoff_orig.c create mode 100644 potentials/tersoff_orig.h diff --git a/Makefile b/Makefile index 3e31459..70fcb8b 100644 --- a/Makefile +++ b/Makefile @@ -8,10 +8,11 @@ CFLAGS+=-g #CFLAGS+=-DVDEBUG LDFLAGS=-lm -SOURCE=moldyn.c visual/visual.c random/random.c +SOURCE=moldyn.c visual/visual.c random/random.c list/list.c -POT_SRC=potentials/tersoff.c potentials/lennard_jones.c -POT_SRC+= potentials/harmonic_oscillator.c +POT_SRC=potentials/tersoff.c +#POT_SRC=potentials/tersoff_orig.c +POT_SRC+= potentials/lennard_jones.c potentials/harmonic_oscillator.c all: sic diff --git a/moldyn.c b/moldyn.c index 9a62b9f..4d73617 100644 --- a/moldyn.c +++ b/moldyn.c @@ -82,7 +82,7 @@ int set_pressure(t_moldyn *moldyn,double p_ref) { moldyn->p_ref=p_ref; - printf("[moldyn] pressure [atm]: %f\n",moldyn->p_ref/ATM); + printf("[moldyn] pressure [bar]: %f\n",moldyn->p_ref/BAR); return 0; } @@ -176,16 +176,37 @@ int set_potential2b(t_moldyn *moldyn,pf_func2b func) { return 0; } -int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func) { +int set_potential3b_j1(t_moldyn *moldyn,pf_func2b func) { - moldyn->func2b_post=func; + moldyn->func3b_j1=func; return 0; } -int set_potential3b(t_moldyn *moldyn,pf_func3b func) { +int set_potential3b_j2(t_moldyn *moldyn,pf_func2b func) { - moldyn->func3b=func; + moldyn->func3b_j2=func; + + return 0; +} + +int set_potential3b_j3(t_moldyn *moldyn,pf_func2b func) { + + moldyn->func3b_j3=func; + + return 0; +} + +int set_potential3b_k1(t_moldyn *moldyn,pf_func3b func) { + + moldyn->func3b_k1=func; + + return 0; +} + +int set_potential3b_k2(t_moldyn *moldyn,pf_func3b func) { + + moldyn->func3b_k2=func; return 0; } @@ -294,6 +315,7 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { perror("[moldyn] report fd open"); return moldyn->rfd; } + printf("report -> "); if(moldyn->efd) { snprintf(filename,127,"%s/e_plot.scr", moldyn->vlsdir); @@ -306,6 +328,7 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { } dprintf(moldyn->epfd,e_plot_script); close(moldyn->epfd); + printf("energy "); } if(moldyn->pfd) { snprintf(filename,127,"%s/pressure_plot.scr", @@ -319,6 +342,7 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { } dprintf(moldyn->ppfd,pressure_plot_script); close(moldyn->ppfd); + printf("pressure "); } if(moldyn->tfd) { snprintf(filename,127,"%s/temperature_plot.scr", @@ -332,9 +356,11 @@ int moldyn_set_log(t_moldyn *moldyn,u8 type,int timer) { } dprintf(moldyn->tpfd,temperature_plot_script); close(moldyn->tpfd); + printf("temperature "); } dprintf(moldyn->rfd,report_start, moldyn->rauthor,moldyn->rtitle); + printf("\n"); break; default: printf("unknown log type: %02x\n",type); @@ -672,6 +698,8 @@ double temperature_calc(t_moldyn *moldyn) { /* assume up to date kinetic energy, which is 3/2 N k_B T */ moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count); + moldyn->t_sum+=moldyn->t; + moldyn->mean_t=moldyn->t_sum/moldyn->total_steps; return moldyn->t; } @@ -769,6 +797,16 @@ double pressure_calc(t_moldyn *moldyn) { /* assume up to date kinetic energy */ moldyn->p=2.0*moldyn->ekin+v; moldyn->p/=(3.0*moldyn->volume); + moldyn->p_sum+=moldyn->p; + moldyn->mean_p=moldyn->p_sum/moldyn->total_steps; + + /* pressure from 'absolute coordinates' virial */ + virial=&(moldyn->virial); + v=virial->xx+virial->yy+virial->zz; + moldyn->gp=2.0*moldyn->ekin+v; + moldyn->gp/=(3.0*moldyn->volume); + moldyn->gp_sum+=moldyn->gp; + moldyn->mean_gp=moldyn->gp_sum/moldyn->total_steps; return moldyn->p; } @@ -788,7 +826,7 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { * dV: dx,y,z = 0.001 x,y,z */ - scale=1.00001; + scale=1.00000000000001; printf("\n\nP-DEBUG:\n"); tp=&(moldyn->tp); @@ -806,13 +844,12 @@ printf("\n\nP-DEBUG:\n"); /* derivative with respect to x direction */ scale_dim(moldyn,scale,TRUE,0,0); scale_atoms(moldyn,scale,TRUE,0,0); - dv=0.00001*moldyn->dim.x*moldyn->dim.y*moldyn->dim.z; + dv=0.00000000000001*moldyn->dim.x*moldyn->dim.y*moldyn->dim.z; link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); tp->x=(moldyn->energy-u)/dv; p=tp->x*tp->x; -printf("e: %f eV de: %f eV dV: %f A^3\n",moldyn->energy/moldyn->count/EV,(moldyn->energy-u)/moldyn->count/EV,dv); /* restore atomic configuration + dim */ memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); @@ -821,7 +858,7 @@ printf("e: %f eV de: %f eV dV: %f A^3\n",moldyn->energy/moldyn->count/EV,(moldyn /* derivative with respect to y direction */ scale_dim(moldyn,scale,0,TRUE,0); scale_atoms(moldyn,scale,0,TRUE,0); - dv=0.00001*moldyn->dim.y*moldyn->dim.x*moldyn->dim.z; + dv=0.00000000000001*moldyn->dim.y*moldyn->dim.x*moldyn->dim.z; link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); @@ -835,7 +872,7 @@ printf("e: %f eV de: %f eV dV: %f A^3\n",moldyn->energy/moldyn->count/EV,(moldyn /* derivative with respect to z direction */ scale_dim(moldyn,scale,0,0,TRUE); scale_atoms(moldyn,scale,0,0,TRUE); - dv=0.00001*moldyn->dim.z*moldyn->dim.x*moldyn->dim.y; + dv=0.00000000000001*moldyn->dim.z*moldyn->dim.x*moldyn->dim.y; link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); @@ -939,7 +976,7 @@ moldyn->debug=scale; } -double get_e_kin(t_moldyn *moldyn) { +double e_kin_calc(t_moldyn *moldyn) { int i; t_atom *atom; @@ -953,11 +990,6 @@ double get_e_kin(t_moldyn *moldyn) { return moldyn->ekin; } -double update_e_kin(t_moldyn *moldyn) { - - return(get_e_kin(moldyn)); -} - double get_total_energy(t_moldyn *moldyn) { return(moldyn->ekin+moldyn->energy); @@ -1018,7 +1050,12 @@ int link_cell_init(t_moldyn *moldyn,u8 vol) { if(lc->cells<27) printf("[moldyn] FATAL: less then 27 subcells!\n"); - if(vol) printf("[moldyn] initializing linked cells (%d)\n",lc->cells); + if(vol) { + printf("[moldyn] initializing linked cells (%d)\n",lc->cells); + printf(" x: %d x %f A\n",lc->nx,lc->x); + printf(" y: %d x %f A\n",lc->ny,lc->y); + printf(" z: %d x %f A\n",lc->nz,lc->z); + } for(i=0;icells;i++) list_init_f(&(lc->subcell[i])); @@ -1053,7 +1090,7 @@ int link_cell_update(t_moldyn *moldyn) { i=((atom[count].r.x+(moldyn->dim.x/2))/lc->x); j=((atom[count].r.y+(moldyn->dim.y/2))/lc->y); k=((atom[count].r.z+(moldyn->dim.z/2))/lc->z); - list_add_immediate_f(&(moldyn->lc.subcell[i+j*nx+k*nx*ny]), + list_add_immediate_f(&(lc->subcell[i+j*nx+k*nx*ny]), &(atom[count])); } @@ -1229,6 +1266,7 @@ int moldyn_integrate(t_moldyn *moldyn) { /* zero absolute time */ moldyn->time=0.0; + moldyn->total_steps=0; /* debugging, ignore */ moldyn->debug=0; @@ -1252,10 +1290,11 @@ int moldyn_integrate(t_moldyn *moldyn) { moldyn->integrate(moldyn); /* calculate kinetic energy, temperature and pressure */ - update_e_kin(moldyn); + e_kin_calc(moldyn); temperature_calc(moldyn); pressure_calc(moldyn); //tp=thermodynamic_pressure_calc(moldyn); +//printf("thermodynamic p: %f %f %f - %f\n",moldyn->tp.x/BAR,moldyn->tp.y/BAR,moldyn->tp.z/BAR,tp/BAR); /* p/t scaling */ if(moldyn->pt_scale&(T_SCALE_BERENDSEN|T_SCALE_DIRECT)) @@ -1284,13 +1323,16 @@ int moldyn_integrate(t_moldyn *moldyn) { if(p) { if(!(i%p)) { dprintf(moldyn->pfd, - "%f %f\n",moldyn->time,moldyn->p/ATM); + "%f %f %f %f %f\n",moldyn->time, + moldyn->p/BAR,moldyn->mean_p/BAR, + moldyn->gp/BAR,moldyn->mean_gp/BAR); } } if(t) { if(!(i%t)) { dprintf(moldyn->tfd, - "%f %f\n",moldyn->time,moldyn->t); + "%f %f %f\n", + moldyn->time,moldyn->t,moldyn->mean_t); } } if(s) { @@ -1316,14 +1358,18 @@ int moldyn_integrate(t_moldyn *moldyn) { /* display progress */ if(!(i%10)) { - printf("\rsched: %d, steps: %d, T: %f, P: %f V: %f", + printf("\rsched: %d, steps: %d, T: %f, P: %f %f V: %f", sched->count,i, - moldyn->t,moldyn->p/ATM,moldyn->volume); + moldyn->mean_t, + moldyn->mean_p/BAR, + moldyn->mean_gp/BAR, + moldyn->volume); fflush(stdout); } /* increase absolute time */ moldyn->time+=moldyn->tau; + moldyn->total_steps+=1; } @@ -1410,6 +1456,9 @@ int potential_force_calc(t_moldyn *moldyn) { /* reset energy */ moldyn->energy=0.0; + /* reset global virial */ + memset(&(moldyn->virial),0,sizeof(t_virial)); + /* reset force, site energy and virial of every atom */ for(i=0;idnlc; + /* first loop over atoms j */ + if(moldyn->func2b) { + for(j=0;j<27;j++) { + + this=&(neighbour_i[j]); + list_reset_f(this); + + if(this->start==NULL) + continue; + + bc_ij=(jcurrent->data; + + if(jtom==&(itom[i])) + continue; + + if((jtom->attr&ATOM_ATTR_2BP)& + (itom[i].attr&ATOM_ATTR_2BP)) { + moldyn->func2b(moldyn, + &(itom[i]), + jtom, + bc_ij); + } + } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); + + } + } + + /* 3 body potential/force */ + + if(!(itom[i].attr&ATOM_ATTR_3BP)) + continue; + + /* copy the neighbour lists */ + memcpy(neighbour_i2,neighbour_i,27*sizeof(t_list)); + + /* second loop over atoms j */ for(j=0;j<27;j++) { this=&(neighbour_i[j]); @@ -1466,25 +1556,70 @@ int potential_force_calc(t_moldyn *moldyn) { if(jtom==&(itom[i])) continue; - if((jtom->attr&ATOM_ATTR_2BP)& - (itom[i].attr&ATOM_ATTR_2BP)) { - moldyn->func2b(moldyn, - &(itom[i]), - jtom, - bc_ij); - } + if(!(jtom->attr&ATOM_ATTR_3BP)) + continue; - /* 3 body potential/force */ + /* reset 3bp run */ + moldyn->run3bp=1; - if(!(itom[i].attr&ATOM_ATTR_3BP)|| - !(jtom->attr&ATOM_ATTR_3BP)) + if(moldyn->func3b_j1) + moldyn->func3b_j1(moldyn, + &(itom[i]), + jtom, + bc_ij); + + /* in first j loop, 3bp run can be skipped */ + if(!(moldyn->run3bp)) continue; + + /* first loop over atoms k */ + if(moldyn->func3b_k1) { + + for(k=0;k<27;k++) { + + that=&(neighbour_i2[k]); + list_reset_f(that); + + if(that->start==NULL) + continue; + + bc_ik=(kcurrent->data; + + if(!(ktom->attr&ATOM_ATTR_3BP)) + continue; + + if(ktom==jtom) + continue; + + if(ktom==&(itom[i])) + continue; + + moldyn->func3b_k1(moldyn, + &(itom[i]), + jtom, + ktom, + bc_ik|bc_ij); + + } while(list_next_f(that)!=\ + L_NO_NEXT_ELEMENT); + + } + + } + + if(moldyn->func3b_j2) + moldyn->func3b_j2(moldyn, + &(itom[i]), + jtom, + bc_ij); + + /* second loop over atoms k */ + if(moldyn->func3b_k2) { - /* get neighbours of i */ for(k=0;k<27;k++) { that=&(neighbour_i2[k]); @@ -1508,37 +1643,53 @@ int potential_force_calc(t_moldyn *moldyn) { if(ktom==&(itom[i])) continue; - moldyn->func3b(moldyn, - &(itom[i]), - jtom, - ktom, - bc_ik|bc_ij); + moldyn->func3b_k2(moldyn, + &(itom[i]), + jtom, + ktom, + bc_ik|bc_ij); } while(list_next_f(that)!=\ L_NO_NEXT_ELEMENT); } + + } /* 2bp post function */ - if(moldyn->func2b_post) { - moldyn->func2b_post(moldyn, - &(itom[i]), - jtom,bc_ij); + if(moldyn->func3b_j3) { + moldyn->func3b_j3(moldyn, + &(itom[i]), + jtom,bc_ij); } } while(list_next_f(this)!=L_NO_NEXT_ELEMENT); } + +#ifdef DEBUG + //printf("\n\n"); +#endif +#ifdef VDEBUG + printf("\n\n"); +#endif } #ifdef DEBUG -printf("\n\n"); -#endif -#ifdef VDEBUG -printf("\n\n"); + printf("\nATOM 0: %f %f %f\n\n",itom->f.x,itom->f.y,itom->f.z); #endif + /* calculate global virial */ + for(i=0;ivirial.xx+=moldyn->atom[i].r.x*moldyn->atom[i].f.x; + moldyn->virial.yy+=moldyn->atom[i].r.y*moldyn->atom[i].f.y; + moldyn->virial.zz+=moldyn->atom[i].r.z*moldyn->atom[i].f.z; + moldyn->virial.xy+=moldyn->atom[i].r.y*moldyn->atom[i].f.x; + moldyn->virial.xz+=moldyn->atom[i].r.z*moldyn->atom[i].f.x; + moldyn->virial.yz+=moldyn->atom[i].r.z*moldyn->atom[i].f.y; + } + return 0; } diff --git a/moldyn.h b/moldyn.h index 85a4950..5b12048 100644 --- a/moldyn.h +++ b/moldyn.h @@ -85,11 +85,15 @@ typedef struct s_moldyn { /* potential force function and parameter pointers */ int (*func1b)(struct s_moldyn *moldyn,t_atom *ai); int (*func2b)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); - int (*func2b_post)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); - int (*func3b)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak, - u8 bck); + int (*func3b_j1)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); + int (*func3b_j2)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); + int (*func3b_j3)(struct s_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); + int (*func3b_k1)(struct s_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bck); + int (*func3b_k2)(struct s_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bck); void *pot_params; - //int (*potential_force_function)(struct s_moldyn *moldyn); + unsigned char run3bp; double cutoff; /* cutoff radius */ double cutoff_square; /* square of the cutoff radius */ @@ -99,9 +103,18 @@ typedef struct s_moldyn { double t_ref; /* reference temperature */ double t; /* actual temperature */ + double t_sum; /* sum over all t */ + double mean_t; /* mean value of t */ + + t_virial virial; /* global virial (absolute coordinates) */ + double gp; /* pressure computed from global virial */ + double gp_sum; /* sum over all gp */ + double mean_gp; /* mean value of gp */ double p_ref; /* reference pressure */ double p; /* actual pressure (computed by virial) */ + double p_sum; /* sum over all p */ + double mean_p; /* mean value of p */ t_3dvec tp; /* thermodynamic pressure dU/dV */ double dv; /* dV for thermodynamic pressure calc */ @@ -121,7 +134,7 @@ typedef struct s_moldyn { double tau; /* delta t */ double time; /* absolute time */ double tau_square; /* delta t squared */ - double elapsed; /* total elapsed time */ + int total_steps; /* total steps */ double energy; /* potential energy */ double ekin; /* kinetic energy */ @@ -175,7 +188,7 @@ typedef struct s_moldyn { #define P_SCALE_DIRECT 0x08 /* direct p control */ /* - * default values + * default values & units * * - length unit: 1 A (1 A = 1e-10 m) * - time unit: 1 fs (1 fs = 1e-15 s) @@ -191,7 +204,9 @@ typedef struct s_moldyn { #define KILOGRAM (1.0/AMU) /* amu */ #define NEWTON (METER*KILOGRAM/(SECOND*SECOND)) /* A amu / fs^2 */ #define PASCAL (NEWTON/(METER*METER)) /* N / A^2 */ -#define ATM ((1.0133e5*PASCAL)) /* N / A^2 */ +#define BAR ((1.0e5*PASCAL)) /* N / A^2 */ +#define K_BOLTZMANN (1.380650524e-23*METER*NEWTON) /* NA/K */ +#define EV (1.6021765314e-19*METER*NEWTON) /* NA */ #define MOLDYN_TEMP 273.0 #define MOLDYN_TAU 1.0 @@ -220,17 +235,12 @@ typedef struct s_moldyn { #define QUIET 0 /* - * - * phsical values / constants - * + * potential related phsical values / constants * */ #define ONE_THIRD (1.0/3.0) -#define K_BOLTZMANN (1.380650524e-23*METER*NEWTON) /* NA/K */ -#define EV (1.6021765314e-19*METER*NEWTON) /* NA */ - #define C 0x06 #define M_C 12.011 /* amu */ @@ -284,10 +294,9 @@ typedef struct s_moldyn { * */ -typedef int (*pf_func1b)(t_moldyn *,t_atom *ai); -typedef int (*pf_func2b)(t_moldyn *,t_atom *,t_atom *,u8 bc); -typedef int (*pf_func2b_post)(t_moldyn *,t_atom *,t_atom *,u8 bc); -typedef int (*pf_func3b)(t_moldyn *,t_atom *,t_atom *,t_atom *,u8 bc); +typedef int (*pf_func1b)(t_moldyn *,t_atom *); +typedef int (*pf_func2b)(t_moldyn *,t_atom *,t_atom *,u8); +typedef int (*pf_func3b)(t_moldyn *,t_atom *,t_atom *,t_atom *,u8); int moldyn_init(t_moldyn *moldyn,int argc,char **argv); int moldyn_shutdown(t_moldyn *moldyn); @@ -302,8 +311,11 @@ int set_nn_dist(t_moldyn *moldyn,double dist); int set_pbc(t_moldyn *moldyn,u8 x,u8 y,u8 z); int set_potential1b(t_moldyn *moldyn,pf_func1b func); int set_potential2b(t_moldyn *moldyn,pf_func2b func); -int set_potential2b_post(t_moldyn *moldyn,pf_func2b_post func); -int set_potential3b(t_moldyn *moldyn,pf_func3b func); +int set_potential3b_j1(t_moldyn *moldyn,pf_func2b func); +int set_potential3b_j2(t_moldyn *moldyn,pf_func2b func); +int set_potential3b_j3(t_moldyn *moldyn,pf_func2b func); +int set_potential3b_k1(t_moldyn *moldyn,pf_func3b func); +int set_potential3b_k2(t_moldyn *moldyn,pf_func3b func); int set_potential_params(t_moldyn *moldyn,void *params); int moldyn_set_log_dir(t_moldyn *moldyn,char *dir); @@ -331,8 +343,7 @@ int scale_volume(t_moldyn *moldyn); int scale_dim(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z); int scale_atoms(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z); -double get_e_kin(t_moldyn *moldyn); -double update_e_kin(t_moldyn *moldyn); +double e_kin_calc(t_moldyn *moldyn); double get_total_energy(t_moldyn *moldyn); t_3dvec get_total_p(t_moldyn *moldyn); diff --git a/potentials/tersoff.c b/potentials/tersoff.c index 16f771c..531d292 100644 --- a/potentials/tersoff.c +++ b/potentials/tersoff.c @@ -85,10 +85,9 @@ int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) { int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { t_tersoff_mult_params *params; - t_tersoff_exchange *exchange; t_3dvec dist_ij,force; double d_ij,d_ij2; - double A,B,R,S,S2,lambda,mu; + double A,R,S,S2,lambda; double f_r,df_r; double f_c,df_c; int brand; @@ -96,31 +95,10 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { double arg; /* use newtons third law */ - //if(aipot_params; brand=aj->brand; - exchange=&(params->exchange); - - /* clear 3bp and 2bp post run */ - exchange->run3bp=0; - exchange->run2bp_post=0; - - /* reset S > r > R mark */ - exchange->d_ij_between_rs=0; - - /* - * calc of 2bp contribution of V_ij and dV_ij/ji - * - * for Vij and dV_ij we need: - * - f_c_ij, df_c_ij - * - f_r_ij, df_r_ij - * - * for dV_ji we need: - * - f_c_ji = f_c_ij, df_c_ji = df_c_ij - * - f_r_ji = f_r_ij; df_r_ji = df_r_ij - * - */ /* determine cutoff square */ if(brand==ai->brand) @@ -128,71 +106,41 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { else S2=params->S2mixed; - /* dist_ij, d_ij */ + /* dist_ij, d_ij2 */ v3_sub(&dist_ij,&(aj->r),&(ai->r)); if(bc) check_per_bound(moldyn,&dist_ij); d_ij2=v3_absolute_square(&dist_ij); /* if d_ij2 > S2 => no force & potential energy contribution */ - if(d_ij2>S2) + if(d_ij2>S2) { return 0; + } /* now we will need the distance */ - //d_ij=v3_norm(&dist_ij); d_ij=sqrt(d_ij2); - /* save for use in 3bp */ - exchange->d_ij=d_ij; - exchange->d_ij2=d_ij2; - exchange->dist_ij=dist_ij; - /* more constants */ - exchange->beta_j=&(params->beta[brand]); - exchange->n_j=&(params->n[brand]); - exchange->c_j=&(params->c[brand]); - exchange->d_j=&(params->d[brand]); - exchange->h_j=&(params->h[brand]); if(brand==ai->brand) { S=params->S[brand]; R=params->R[brand]; A=params->A[brand]; - B=params->B[brand]; lambda=params->lambda[brand]; - mu=params->mu[brand]; - exchange->chi=1.0; - exchange->betajnj=exchange->betaini; - exchange->cj2=exchange->ci2; - exchange->dj2=exchange->di2; - exchange->cj2dj2=exchange->ci2di2; } else { S=params->Smixed; R=params->Rmixed; A=params->Amixed; - B=params->Bmixed; lambda=params->lambda_m; - mu=params->mu_m; - params->exchange.chi=params->chi; - exchange->betajnj=pow(*(exchange->beta_j),*(exchange->n_j)); - exchange->cj2=params->c[brand]*params->c[brand]; - exchange->dj2=params->d[brand]*params->d[brand]; - exchange->cj2dj2=exchange->cj2/exchange->dj2; } - /* f_r_ij = f_r_ji, df_r_ij = df_r_ji */ + /* f_r_ij, df_r_ij */ f_r=A*exp(-lambda*d_ij); df_r=lambda*f_r/d_ij; - /* f_a, df_a calc (again, same for ij and ji) | save for later use! */ - exchange->f_a=-B*exp(-mu*d_ij); - exchange->df_a=mu*exchange->f_a/d_ij; - - /* f_c, df_c calc (again, same for ij and ji) */ + /* f_c, df_c */ if(d_ij r > R */ - exchange->d_ij_between_rs=1; } - /* add forces of 2bp (ij, ji) contribution - * dVij = dVji and we sum up both: no 1/2) */ + /* add forces */ v3_add(&(ai->f),&(ai->f),&force); + v3_sub(&(aj->f),&(aj->f),&force); + +#ifdef DEBUG + if((ai==&(moldyn->atom[0]))|(aj==&(moldyn->atom[0]))) { + printf("force 2bp: [%d %d]\n",ai->tag,aj->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + if(ai==&(moldyn->atom[0])) + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); + if(aj==&(moldyn->atom[0])) + printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + } +#endif /* virial */ - virial_calc(ai,&force,&dist_ij); + //virial_calc(ai,&force,&dist_ij); + //virial_calc(aj,&force,&dist_ij); //ai->virial.xx-=force.x*dist_ij.x; //ai->virial.yy-=force.y*dist_ij.y; //ai->virial.zz-=force.z*dist_ij.z; @@ -219,270 +176,86 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { //ai->virial.xz-=force.x*dist_ij.z; //ai->virial.yz-=force.y*dist_ij.z; -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij, dVji (2bp) contrib:\n"); - printf("%f | %f\n",force.x,ai->f.x); - printf("%f | %f\n",force.y,ai->f.y); - printf("%f | %f\n",force.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij, dVji (2bp) contrib:\n"); - printf("%f | %f\n",force.x*dist_ij.x,ai->virial.xx); - printf("%f | %f\n",force.y*dist_ij.y,ai->virial.yy); - printf("%f | %f\n",force.z*dist_ij.z,ai->virial.zz); -} -#endif - - /* energy 2bp contribution (ij, ji) is 0.5 f_r f_c ... */ - moldyn->energy+=(0.5*f_r*f_c); - - /* save for use in 3bp */ - exchange->f_c=f_c; - exchange->df_c=df_c; - - /* enable the run of 3bp function and 2bp post processing */ - exchange->run3bp=1; - exchange->run2bp_post=1; - - /* reset 3bp sums */ - exchange->zeta_ij=0.0; - exchange->zeta_ji=0.0; - v3_zero(&(exchange->dzeta_ij)); - v3_zero(&(exchange->dzeta_ji)); + /* energy 2bp contribution */ + moldyn->energy+=f_r*f_c; return 0; } -/* tersoff 2 body post part */ - -int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { - - /* - * here we have to allow for the 3bp sums - * - * that is: - * - zeta_ij, dzeta_ij - * - zeta_ji, dzeta_ji - * - * to compute the 3bp contribution to: - * - Vij, dVij - * - dVji - * - */ +/* tersoff 3 body potential function (first ij loop) */ +int tersoff_mult_3bp_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { t_tersoff_mult_params *params; t_tersoff_exchange *exchange; - - t_3dvec force,temp; - t_3dvec *dist_ij; - double b,db,tmp; - double f_c,df_c,f_a,df_a; - double chi,ni,betaini,nj,betajnj; - double zeta; + unsigned char brand; + double S2; + t_3dvec dist_ij; + double d_ij2,d_ij; params=moldyn->pot_params; exchange=&(params->exchange); - /* we do not run if f_c_ij was detected to be 0! */ - if(!(exchange->run2bp_post)) - return 0; - - f_c=exchange->f_c; - df_c=exchange->df_c; - f_a=exchange->f_a; - df_a=exchange->df_a; - betaini=exchange->betaini; - betajnj=exchange->betajnj; - ni=*(exchange->n_i); - nj=*(exchange->n_j); - chi=exchange->chi; - dist_ij=&(exchange->dist_ij); - - /* Vij and dVij */ - zeta=exchange->zeta_ij; - if(zeta==0.0) { - moldyn->debug++; /* just for debugging ... */ - b=chi; - v3_scale(&force,dist_ij,df_a*b*f_c); - } - else { - tmp=betaini*pow(zeta,ni-1.0); /* beta^n * zeta^n-1 */ - b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ - db=chi*pow(b,-1.0/(2*ni)-1); /* x(...)^(-1/2n - 1) */ - b=db*b; /* b_ij */ - db*=-0.5*tmp; /* db_ij */ - v3_scale(&force,&(exchange->dzeta_ij),f_a*db); - v3_scale(&temp,dist_ij,df_a*b); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,f_c); - } - v3_scale(&temp,dist_ij,df_c*b*f_a); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,-0.5); - - /* add force */ - v3_add(&(ai->f),&(ai->f),&force); + /* reset zeta sum */ + exchange->zeta_ij=0.0; - /* virial */ - virial_calc(ai,&force,dist_ij); - //ai->virial.xx-=force.x*dist_ij->x; - //ai->virial.yy-=force.y*dist_ij->y; - //ai->virial.zz-=force.z*dist_ij->z; - //ai->virial.xy-=force.x*dist_ij->y; - //ai->virial.xz-=force.x*dist_ij->z; - //ai->virial.yz-=force.y*dist_ij->z; + /* + * set ij depending values + */ -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij (3bp) contrib:\n"); - printf("%f | %f\n",force.x,ai->f.x); - printf("%f | %f\n",force.y,ai->f.y); - printf("%f | %f\n",force.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVij (3bp) contrib:\n"); - printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); - printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); - printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); -} -#endif + brand=ai->brand; + + if(brand==aj->brand) + S2=params->S2[brand]; + else + S2=params->S2mixed; - /* add energy of 3bp sum */ - moldyn->energy+=(0.5*f_c*b*f_a); + /* dist_ij, d_ij2 */ + v3_sub(&dist_ij,&(aj->r),&(ai->r)); + if(bc) check_per_bound(moldyn,&dist_ij); + d_ij2=v3_absolute_square(&dist_ij); - /* dVji */ - zeta=exchange->zeta_ji; - if(zeta==0.0) { - moldyn->debug++; - b=chi; - v3_scale(&force,dist_ij,df_a*b*f_c); - } - else { - tmp=betajnj*pow(zeta,nj-1.0); /* beta^n * zeta^n-1 */ - b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ - db=chi*pow(b,-1.0/(2*nj)-1); /* x(...)^(-1/2n - 1) */ - b=db*b; /* b_ij */ - db*=-0.5*tmp; /* db_ij */ - v3_scale(&force,&(exchange->dzeta_ji),f_a*db); - v3_scale(&temp,dist_ij,df_a*b); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,f_c); + /* if d_ij2 > S2 => no force & potential energy contribution */ + if(d_ij2>S2) { + moldyn->run3bp=0; + return 0; } - v3_scale(&temp,dist_ij,df_c*b*f_a); - v3_add(&force,&force,&temp); - v3_scale(&force,&force,-0.5); - /* add force */ - v3_add(&(ai->f),&(ai->f),&force); - - /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ -// TEST ... with a minus instead - virial_calc(ai,&force,dist_ij); - //ai->virial.xx-=force.x*dist_ij->x; - //ai->virial.yy-=force.y*dist_ij->y; - //ai->virial.zz-=force.z*dist_ij->z; - //ai->virial.xy-=force.x*dist_ij->y; - //ai->virial.xz-=force.x*dist_ij->z; - //ai->virial.yz-=force.y*dist_ij->z; + /* d_ij */ + d_ij=sqrt(d_ij2); -#ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVji (3bp) contrib:\n"); - printf("%f | %f\n",force.x,ai->f.x); - printf("%f | %f\n",force.y,ai->f.y); - printf("%f | %f\n",force.z,ai->f.z); -} -#endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVji (3bp) contrib:\n"); - printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); - printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); - printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); -} -#endif + /* store values */ + exchange->dist_ij=dist_ij; + exchange->d_ij2=d_ij2; + exchange->d_ij=d_ij; + /* reset k counter for first k loop */ + exchange->kcount=0; + return 0; } -/* tersoff 3 body part */ - -int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { +/* tersoff 3 body potential function (first k loop) */ +int tersoff_mult_3bp_k1(t_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { t_tersoff_mult_params *params; t_tersoff_exchange *exchange; - t_3dvec dist_ij,dist_ik,dist_jk; - t_3dvec temp1,temp2; - t_3dvec *dzeta; - double R,S,S2,s_r; - double B,mu; - double d_ij,d_ik,d_jk,d_ij2,d_ik2,d_jk2; - double rr,dd; - double f_c,df_c; - double f_c_ik,df_c_ik,arg; - double f_c_jk; - double n,c,d,h; - double c2,d2,c2d2; - double cos_theta,d_costheta1,d_costheta2; - double h_cos,d2_h_cos2; - double frac,g,zeta,chi; - double tmp; - int brand; + unsigned char brand; + double R,S,S2; + t_3dvec dist_ij,dist_ik; + double d_ik2,d_ik,d_ij; + double cos_theta,h_cos,d2_h_cos2,frac,g,dg,s_r,arg; + double f_c_ik,df_c_ik; + int kcount; params=moldyn->pot_params; exchange=&(params->exchange); + kcount=exchange->kcount; - if(!(exchange->run3bp)) - return 0; - - /* - * calc of 3bp contribution of V_ij and dV_ij/ji/jk & - * 2bp contribution of dV_jk - * - * for Vij and dV_ij we still need: - * - b_ij, db_ij (zeta_ij) - * - f_c_ik, df_c_ik, constants_i, cos_theta_ijk, d_costheta_ijk - * - * for dV_ji we still need: - * - b_ji, db_ji (zeta_ji) - * - f_c_jk, d_c_jk, constants_j, cos_theta_jik, d_costheta_jik - * - * for dV_jk we need: - * - f_c_jk - * - f_a_jk - * - db_jk (zeta_jk) - * - f_c_ji, df_c_ji, constants_j, cos_theta_jki, d_costheta_jki - * - */ - - /* - * get exchange data - */ - - /* dist_ij, d_ij - this is < S_ij ! */ - dist_ij=exchange->dist_ij; - d_ij=exchange->d_ij; - d_ij2=exchange->d_ij2; - - /* f_c_ij, df_c_ij (same for ji) */ - f_c=exchange->f_c; - df_c=exchange->df_c; - - /* - * calculate unknown values now ... - */ - - /* V_ij and dV_ij stuff (in b_ij there is f_c_ik) */ - - /* dist_ik, d_ik */ - v3_sub(&dist_ik,&(ak->r),&(ai->r)); - if(bc) check_per_bound(moldyn,&dist_ik); - d_ik2=v3_absolute_square(&dist_ik); + if(kcount>TERSOFF_MAXN) { + printf("FATAL: neighbours = %d\n",kcount); + printf(" -> %d %d %d\n",ai->tag,aj->tag,ak->tag); + } /* ik constants */ brand=ai->brand; @@ -497,215 +270,298 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { S2=params->S2mixed; } - /* zeta_ij/dzeta_ij contribution only for d_ik < S */ - if(d_ik2n_i); - c=*(exchange->c_i); - d=*(exchange->d_i); - h=*(exchange->h_i); - c2=exchange->ci2; - d2=exchange->di2; - c2d2=exchange->ci2di2; - - /* cosine of theta_ijk by scalaproduct */ - rr=v3_scalar_product(&dist_ij,&dist_ik); - dd=d_ij*d_ik; - cos_theta=rr/dd; - - /* d_costheta */ - tmp=1.0/dd; - d_costheta1=cos_theta/d_ij2-tmp; - d_costheta2=cos_theta/d_ik2-tmp; - - /* some usefull values */ - h_cos=(h-cos_theta); - d2_h_cos2=d2+(h_cos*h_cos); - frac=c2/(d2_h_cos2); - - /* g(cos_theta) */ - g=1.0+c2d2-frac; - - /* d_costheta_ij and dg(cos_theta) - needed in any case! */ - v3_scale(&temp1,&dist_ij,d_costheta1); - v3_scale(&temp2,&dist_ik,d_costheta2); - v3_add(&temp1,&temp1,&temp2); - v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ - - /* f_c_ik & df_c_ik + {d,}zeta contribution */ - dzeta=&(exchange->dzeta_ij); - if(d_ik f_c_ik=1.0; - // => df_c_ik=0.0; of course we do not set this! - - /* zeta_ij */ - exchange->zeta_ij+=g; - - /* dzeta_ij */ - v3_add(dzeta,dzeta,&temp1); - } - else { - /* {d,}f_c_ik */ - s_r=S-R; - arg=M_PI*(d_ik-R)/s_r; - f_c_ik=0.5+0.5*cos(arg); - df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik)); - - /* zeta_ij */ - exchange->zeta_ij+=f_c_ik*g; - - /* dzeta_ij */ - v3_scale(&temp1,&temp1,f_c_ik); - v3_scale(&temp2,&dist_ik,g*df_c_ik); - v3_add(&temp1,&temp1,&temp2); - v3_add(dzeta,dzeta,&temp1); - } + /* dist_ik, d_ik2 */ + v3_sub(&dist_ik,&(ak->r),&(ai->r)); + if(bc) check_per_bound(moldyn,&dist_ik); + d_ik2=v3_absolute_square(&dist_ik); + + /* store data for second k loop */ + exchange->dist_ik[kcount]=dist_ik; + exchange->d_ik2[kcount]=d_ik2; + + /* return if not within cutoff */ + if(d_ik2>S2) { + exchange->kcount++; + return 0; + } + + /* d_ik */ + d_ik=sqrt(d_ik2); + + /* dist_ij, d_ij */ + dist_ij=exchange->dist_ij; + d_ij=exchange->d_ij; + + /* cos theta */ + cos_theta=v3_scalar_product(&dist_ij,&dist_ik)/(d_ij*d_ik); + + /* g_ijk */ + h_cos=*(exchange->h_i)-cos_theta; + d2_h_cos2=exchange->di2+(h_cos*h_cos); + frac=exchange->ci2/d2_h_cos2; + g=1.0+exchange->ci2di2-frac; + dg=-2.0*frac*h_cos/d2_h_cos2; + + /* zeta sum += f_c_ik * g_ijk */ + if(d_ik<=R) { + exchange->zeta_ij+=g; + f_c_ik=1.0; + df_c_ik=0.0; + } + else { + s_r=S-R; + arg=M_PI*(d_ik-R)/s_r; + f_c_ik=0.5+0.5*cos(arg); + df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik)); + exchange->zeta_ij+=f_c_ik*g; } - /* dV_ji stuff (in b_ji there is f_c_jk) + dV_jk stuff! */ + /* store even more data for second k loop */ + exchange->g[kcount]=g; + exchange->dg[kcount]=dg; + exchange->d_ik[kcount]=d_ik; + exchange->cos_theta[kcount]=cos_theta; + exchange->f_c_ik[kcount]=f_c_ik; + exchange->df_c_ik[kcount]=df_c_ik; - /* dist_jk, d_jk */ - v3_sub(&dist_jk,&(ak->r),&(aj->r)); - if(bc) check_per_bound(moldyn,&dist_jk); - d_jk2=v3_absolute_square(&dist_jk); + /* increase k counter */ + exchange->kcount++; + + return 0; +} + +int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + t_3dvec force; + double f_a,df_a,b,db,f_c,df_c; + double mu,B,chi; + double d_ij; + unsigned char brand; + double ni,tmp; + double S,R,s_r,arg; + + params=moldyn->pot_params; + exchange=&(params->exchange); - /* jk constants */ brand=aj->brand; - if(brand==ak->brand) { - R=params->R[brand]; + if(brand==ai->brand) { S=params->S[brand]; - S2=params->S2[brand]; + R=params->R[brand]; B=params->B[brand]; mu=params->mu[brand]; chi=1.0; } else { - R=params->Rmixed; S=params->Smixed; - S2=params->S2mixed; + R=params->Rmixed; B=params->Bmixed; mu=params->mu_m; chi=params->chi; } - /* zeta_ji/dzeta_ji contribution only for d_jk < S_jk */ - if(d_jk2n_j); - c=*(exchange->c_j); - d=*(exchange->d_j); - h=*(exchange->h_j); - c2=exchange->cj2; - d2=exchange->dj2; - c2d2=exchange->cj2dj2; - - /* cosine of theta_jik by scalaproduct */ - rr=-v3_scalar_product(&dist_ij,&dist_jk); /* -1, as ij -> ji */ - dd=d_ij*d_jk; - cos_theta=rr/dd; - - /* d_costheta */ - d_costheta1=1.0/dd; - d_costheta2=cos_theta/d_ij2; - - /* some usefull values */ - h_cos=(h-cos_theta); - d2_h_cos2=d2+(h_cos*h_cos); - frac=c2/(d2_h_cos2); - - /* g(cos_theta) */ - g=1.0+c2d2-frac; - - /* d_costheta_jik and dg(cos_theta) - needed in any case! */ - v3_scale(&temp1,&dist_jk,d_costheta1); - v3_scale(&temp2,&dist_ij,-d_costheta2); /* ji -> ij => -1 */ - //v3_add(&temp1,&temp1,&temp2); - v3_sub(&temp1,&temp1,&temp2); /* there is a minus! */ - v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ - - /* store dg in temp2 and use it for dVjk later */ - v3_copy(&temp2,&temp1); - - /* f_c_jk + {d,}zeta contribution (df_c_jk = 0) */ - dzeta=&(exchange->dzeta_ji); - if(d_jkzeta_ji+=g; - - /* dzeta_ji */ - v3_add(dzeta,dzeta,&temp1); - } - else { - /* f_c_jk */ - s_r=S-R; - arg=M_PI*(d_jk-R)/s_r; - f_c_jk=0.5+0.5*cos(arg); - - /* zeta_ji */ - exchange->zeta_ji+=f_c_jk*g; - - /* dzeta_ji */ - v3_scale(&temp1,&temp1,f_c_jk); - v3_add(dzeta,dzeta,&temp1); - } - - /* dV_jk stuff | add force contribution on atom i immediately */ - if(exchange->d_ij_between_rs) { - zeta=f_c*g; - v3_scale(&temp1,&temp2,f_c); - v3_scale(&temp2,&dist_ij,df_c*g); - v3_add(&temp2,&temp2,&temp1); /* -> dzeta_jk in temp2 */ - } - else { - zeta=g; - // dzeta_jk is simply dg, which is stored in temp2 - } - /* betajnj * zeta_jk ^ nj-1 */ - tmp=exchange->betajnj*pow(zeta,(n-1.0)); - tmp=-chi/2.0*pow((1+tmp*zeta),(-1.0/(2.0*n)-1))*tmp; - v3_scale(&temp2,&temp2,tmp*B*exp(-mu*d_jk)*f_c_jk*0.5); - v3_add(&(ai->f),&(ai->f),&temp2); /* -1 skipped in f_a calc ^ */ - /* scaled with 0.5 ^ */ - - /* virial */ - ai->virial.xx-=temp2.x*dist_jk.x; - ai->virial.yy-=temp2.y*dist_jk.y; - ai->virial.zz-=temp2.z*dist_jk.z; - ai->virial.xy-=temp2.x*dist_jk.y; - ai->virial.xz-=temp2.x*dist_jk.z; - ai->virial.yz-=temp2.y*dist_jk.z; + d_ij=exchange->d_ij; + + /* f_c, df_c */ + if(d_ijzeta_ij==0.0) { + b=chi; + db=0.0; + } + else { + ni=*(exchange->n_i); + tmp=exchange->betaini*pow(exchange->zeta_ij,ni-1.0); + b=(1.0+exchange->zeta_ij*tmp); + db=chi*pow(b,-1.0/(2*ni)-1.0); + b=db*b; + db*=-0.5*tmp; + } + + /* force contribution */ + v3_scale(&force,&(exchange->dist_ij),df_a*f_c+f_a*df_c); + v3_scale(&force,&force,-0.5*b); + v3_add(&(ai->f),&(ai->f),&force); + v3_sub(&(aj->f),&(aj->f),&force); #ifdef DEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVjk (3bp) contrib:\n"); - printf("%f | %f\n",temp2.x,ai->f.x); - printf("%f | %f\n",temp2.y,ai->f.y); - printf("%f | %f\n",temp2.z,ai->f.z); -} + if((ai==&(moldyn->atom[0]))|(aj==&(moldyn->atom[0]))) { + printf("force 3bp (j2): [%d %d sum]\n",ai->tag,aj->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + if(ai==&(moldyn->atom[0])) + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); + if(aj==&(moldyn->atom[0])) + printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + } #endif -#ifdef VDEBUG -if(ai==&(moldyn->atom[0])) { - printf("dVjk (3bp) contrib:\n"); - printf("%f | %f\n",temp2.x*dist_jk.x,ai->virial.xx); - printf("%f | %f\n",temp2.y*dist_jk.y,ai->virial.yy); - printf("%f | %f\n",temp2.z*dist_jk.z,ai->virial.zz); + + /* virial */ + //virial_calc(ai,&force,&(exchange->dist_ij)); + //virial_calc(aj,&force,&(exchange->dist_ij)); + + /* dzeta prefactor = - 0.5 f_c f_a db */ + exchange->pre_dzeta=-0.5*f_a*f_c*db; + + /* energy contribution */ + moldyn->energy+=0.5*f_c*b*f_a; + + /* reset k counter for second k loop */ + exchange->kcount=0; + + return 0; } + +/* tersoff 3 body potential function (second k loop) */ +int tersoff_mult_3bp_k2(t_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + int kcount; + t_3dvec dist_ik,dist_ij; + double d_ik2,d_ik,d_ij2,d_ij; + unsigned char brand; + double S2; + double g,dg,cos_theta; + double pre_dzeta; + double f_c_ik,df_c_ik; + double dijdik_inv,fcdg,dfcg; + t_3dvec dcosdri,dcosdrj,dcosdrk; + t_3dvec force,tmp; + + params=moldyn->pot_params; + exchange=&(params->exchange); + kcount=exchange->kcount; + + if(kcount>TERSOFF_MAXN) + printf("FATAL: neighbours!\n"); + + /* d_ik2 */ + d_ik2=exchange->d_ik2[kcount]; + + brand=ak->brand; + if(brand==ai->brand) + S2=params->S2[brand]; + else + S2=params->S2mixed; + + /* return if d_ik > S */ + if(d_ik2>S2) { + exchange->kcount++; + return 0; + } + + /* prefactor dzeta */ + pre_dzeta=exchange->pre_dzeta; + + /* dist_ik, d_ik */ + dist_ik=exchange->dist_ik[kcount]; + d_ik=exchange->d_ik[kcount]; + + /* f_c_ik, df_c_ik */ + f_c_ik=exchange->f_c_ik[kcount]; + df_c_ik=exchange->df_c_ik[kcount]; + + /* dist_ij, d_ij2, d_ij */ + dist_ij=exchange->dist_ij; + d_ij2=exchange->d_ij2; + d_ij=exchange->d_ij; + + /* g, dg, cos_theta */ + g=exchange->g[kcount]; + dg=exchange->dg[kcount]; + cos_theta=exchange->cos_theta[kcount]; + + /* cos_theta derivatives wrt i,j,k */ + dijdik_inv=1.0/(d_ij*d_ik); + v3_scale(&dcosdrj,&dist_ik,dijdik_inv); + v3_scale(&tmp,&dist_ij,-cos_theta/d_ij2); + v3_add(&dcosdrj,&dcosdrj,&tmp); + v3_scale(&dcosdrk,&dist_ij,dijdik_inv); + v3_scale(&tmp,&dist_ik,-cos_theta/d_ik2); + v3_add(&dcosdrk,&dcosdrk,&tmp); + v3_add(&dcosdri,&dcosdrj,&dcosdrk); + v3_scale(&dcosdri,&dcosdri,-1.0); + + /* f_c_ik * dg, df_c_ik * g */ + fcdg=f_c_ik*dg; + dfcg=df_c_ik*g; + + /* derivative wrt i */ + v3_scale(&force,&dist_ik,dfcg); + v3_scale(&tmp,&dcosdri,fcdg); + v3_add(&force,&force,&tmp); + v3_scale(&force,&force,pre_dzeta); + + /* force contribution */ + v3_add(&(ai->f),&(ai->f),&force); + +#ifdef DEBUG + if(ai==&(moldyn->atom[0])) { + printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); + } +#endif + + /* virial */ + //virial_calc(ai,&force,&dist_ij); + + /* derivatice wrt j */ + v3_scale(&force,&dcosdrj,fcdg*pre_dzeta); + + /* force contribution */ + v3_add(&(aj->f),&(aj->f),&force); + +#ifdef DEBUG + if(aj==&(moldyn->atom[0])) { + printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + printf("total j: %f %f %f\n",aj->f.x,aj->f.y,aj->f.z); + } #endif + /* virial */ + //virial_calc(aj,&force,&dist_ij); + + /* derivative wrt k */ + v3_scale(&force,&dist_ik,dfcg); + v3_scale(&tmp,&dcosdrk,fcdg); + v3_add(&force,&force,&tmp); + v3_scale(&force,&force,pre_dzeta); + + /* force contribution */ + v3_add(&(ak->f),&(ak->f),&force); + +#ifdef DEBUG + if(ak==&(moldyn->atom[0])) { + printf("force 3bp (k2): [%d %d %d]\n",ai->tag,aj->tag,ak->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + printf("total k: %f %f %f\n",ak->f.x,ak->f.y,ak->f.z); } +#endif + + /* virial */ + virial_calc(ak,&force,&dist_ik); + + /* increase k counter */ + exchange->kcount++; return 0; -} +} diff --git a/potentials/tersoff.h b/potentials/tersoff.h index a04ed02..52e848f 100644 --- a/potentials/tersoff.h +++ b/potentials/tersoff.h @@ -8,45 +8,41 @@ #ifndef TERSOFF_H #define TERSOFF_H +#define TERSOFF_MAXN 16*27 + /* tersoff exchange type */ typedef struct s_tersoff_echange { - double f_c,df_c; - double f_a,df_a; t_3dvec dist_ij; double d_ij2; double d_ij; - double chi; + t_3dvec dist_ik[TERSOFF_MAXN]; + double d_ik2[TERSOFF_MAXN]; + double d_ik[TERSOFF_MAXN]; + + double f_c_ik[TERSOFF_MAXN]; + double df_c_ik[TERSOFF_MAXN]; + + double g[TERSOFF_MAXN]; + double dg[TERSOFF_MAXN]; + double cos_theta[TERSOFF_MAXN]; double *beta_i; - double *beta_j; double *n_i; - double *n_j; double *c_i; - double *c_j; double *d_i; - double *d_j; double *h_i; - double *h_j; double ci2; - double cj2; double di2; - double dj2; double ci2di2; - double cj2dj2; double betaini; - double betajnj; - - u8 run3bp; - u8 run2bp_post; - u8 d_ij_between_rs; double zeta_ij; - double zeta_ji; - t_3dvec dzeta_ij; - t_3dvec dzeta_ji; + double pre_dzeta; + + int kcount; } t_tersoff_exchange; /* tersoff mult (2!) potential parameters */ @@ -81,7 +77,11 @@ typedef struct s_tersoff_mult_params { int tersoff_mult_complete_params(t_tersoff_mult_params *p); int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai); int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); -int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); +int tersoff_mult_3bp_j1(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int tersoff_mult_3bp_k1(t_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); +int tersoff_mult_3bp_j2(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int tersoff_mult_3bp_k2(t_moldyn *moldyn, + t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); #endif diff --git a/potentials/tersoff_orig.c b/potentials/tersoff_orig.c new file mode 100644 index 0000000..90121f2 --- /dev/null +++ b/potentials/tersoff_orig.c @@ -0,0 +1,707 @@ +/* + * tersoff_orig.c - tersoff potential + * + * author: Frank Zirkelbach + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../moldyn.h" +#include "../math/math.h" +#include "tersoff_orig.h" + +/* create mixed terms from parameters and set them */ +int tersoff_mult_complete_params(t_tersoff_mult_params *p) { + + printf("[moldyn] tersoff parameter completion\n"); + p->S2[0]=p->S[0]*p->S[0]; + p->S2[1]=p->S[1]*p->S[1]; + p->Smixed=sqrt(p->S[0]*p->S[1]); + p->S2mixed=p->Smixed*p->Smixed; + p->Rmixed=sqrt(p->R[0]*p->R[1]); + p->Amixed=sqrt(p->A[0]*p->A[1]); + p->Bmixed=sqrt(p->B[0]*p->B[1]); + p->lambda_m=0.5*(p->lambda[0]+p->lambda[1]); + p->mu_m=0.5*(p->mu[0]+p->mu[1]); + + printf("[moldyn] tersoff mult parameter info:\n"); + printf(" S (A) | %f | %f | %f\n",p->S[0],p->S[1],p->Smixed); + printf(" R (A) | %f | %f | %f\n",p->R[0],p->R[1],p->Rmixed); + printf(" A (eV) | %f | %f | %f\n",p->A[0]/EV,p->A[1]/EV,p->Amixed/EV); + printf(" B (eV) | %f | %f | %f\n",p->B[0]/EV,p->B[1]/EV,p->Bmixed/EV); + printf(" lambda | %f | %f | %f\n",p->lambda[0],p->lambda[1], + p->lambda_m); + printf(" mu | %f | %f | %f\n",p->mu[0],p->mu[1],p->mu_m); + printf(" beta | %.10f | %.10f\n",p->beta[0],p->beta[1]); + printf(" n | %f | %f\n",p->n[0],p->n[1]); + printf(" c | %f | %f\n",p->c[0],p->c[1]); + printf(" d | %f | %f\n",p->d[0],p->d[1]); + printf(" h | %f | %f\n",p->h[0],p->h[1]); + printf(" chi | %f \n",p->chi); + + return 0; +} + +/* tersoff 1 body part */ +int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) { + + int brand; + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + + brand=ai->brand; + params=moldyn->pot_params; + exchange=&(params->exchange); + + /* + * simple: point constant parameters only depending on atom i to + * their right values + */ + + exchange->beta_i=&(params->beta[brand]); + exchange->n_i=&(params->n[brand]); + exchange->c_i=&(params->c[brand]); + exchange->d_i=&(params->d[brand]); + exchange->h_i=&(params->h[brand]); + + exchange->betaini=pow(*(exchange->beta_i),*(exchange->n_i)); + exchange->ci2=params->c[brand]*params->c[brand]; + exchange->di2=params->d[brand]*params->d[brand]; + exchange->ci2di2=exchange->ci2/exchange->di2; + + return 0; +} + +/* tersoff 2 body part */ +int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + t_3dvec dist_ij,force; + double d_ij,d_ij2; + double A,B,R,S,S2,lambda,mu; + double f_r,df_r; + double f_c,df_c; + int brand; + double s_r; + double arg; + + /* use newtons third law */ + //if(aipot_params; + brand=aj->brand; + exchange=&(params->exchange); + + /* clear 3bp and 2bp post run */ + exchange->run3bp=0; + exchange->run2bp_post=0; + + /* reset S > r > R mark */ + exchange->d_ij_between_rs=0; + + /* + * calc of 2bp contribution of V_ij and dV_ij/ji + * + * for Vij and dV_ij we need: + * - f_c_ij, df_c_ij + * - f_r_ij, df_r_ij + * + * for dV_ji we need: + * - f_c_ji = f_c_ij, df_c_ji = df_c_ij + * - f_r_ji = f_r_ij; df_r_ji = df_r_ij + * + */ + + /* determine cutoff square */ + if(brand==ai->brand) + S2=params->S2[brand]; + else + S2=params->S2mixed; + + /* dist_ij, d_ij */ + v3_sub(&dist_ij,&(aj->r),&(ai->r)); + if(bc) check_per_bound(moldyn,&dist_ij); + d_ij2=v3_absolute_square(&dist_ij); + + /* if d_ij2 > S2 => no force & potential energy contribution */ + if(d_ij2>S2) + return 0; + + /* now we will need the distance */ + //d_ij=v3_norm(&dist_ij); + d_ij=sqrt(d_ij2); + + /* save for use in 3bp */ + exchange->d_ij=d_ij; + exchange->d_ij2=d_ij2; + exchange->dist_ij=dist_ij; + + /* more constants */ + exchange->beta_j=&(params->beta[brand]); + exchange->n_j=&(params->n[brand]); + exchange->c_j=&(params->c[brand]); + exchange->d_j=&(params->d[brand]); + exchange->h_j=&(params->h[brand]); + if(brand==ai->brand) { + S=params->S[brand]; + R=params->R[brand]; + A=params->A[brand]; + B=params->B[brand]; + lambda=params->lambda[brand]; + mu=params->mu[brand]; + exchange->chi=1.0; + exchange->betajnj=exchange->betaini; + exchange->cj2=exchange->ci2; + exchange->dj2=exchange->di2; + exchange->cj2dj2=exchange->ci2di2; + } + else { + S=params->Smixed; + R=params->Rmixed; + A=params->Amixed; + B=params->Bmixed; + lambda=params->lambda_m; + mu=params->mu_m; + exchange->chi=params->chi; + exchange->betajnj=pow(*(exchange->beta_j),*(exchange->n_j)); + exchange->cj2=params->c[brand]*params->c[brand]; + exchange->dj2=params->d[brand]*params->d[brand]; + exchange->cj2dj2=exchange->cj2/exchange->dj2; + } + + /* f_r_ij = f_r_ji, df_r_ij = df_r_ji */ + f_r=A*exp(-lambda*d_ij); + df_r=lambda*f_r/d_ij; + + /* f_a, df_a calc (again, same for ij and ji) | save for later use! */ + exchange->f_a=-B*exp(-mu*d_ij); + exchange->df_a=mu*exchange->f_a/d_ij; + + /* f_c, df_c calc (again, same for ij and ji) */ + if(d_ij r > R */ + exchange->d_ij_between_rs=1; + } + + /* add forces of 2bp (ij, ji) contribution + * dVij = dVji and we sum up both: no 1/2) */ + v3_add(&(ai->f),&(ai->f),&force); + + /* virial */ + virial_calc(ai,&force,&dist_ij); + //ai->virial.xx-=force.x*dist_ij.x; + //ai->virial.yy-=force.y*dist_ij.y; + //ai->virial.zz-=force.z*dist_ij.z; + //ai->virial.xy-=force.x*dist_ij.y; + //ai->virial.xz-=force.x*dist_ij.z; + //ai->virial.yz-=force.y*dist_ij.z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij, dVji (2bp) contrib: [%d %d]\n",ai->tag,aj->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij, dVji (2bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij.x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij.y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij.z,ai->virial.zz); +} +#endif + + /* energy 2bp contribution (ij, ji) is 0.5 f_r f_c ... */ + moldyn->energy+=(0.5*f_r*f_c); + + /* save for use in 3bp */ + exchange->f_c=f_c; + exchange->df_c=df_c; + + /* enable the run of 3bp function and 2bp post processing */ + exchange->run3bp=1; + exchange->run2bp_post=1; + + /* reset 3bp sums */ + exchange->zeta_ij=0.0; + exchange->zeta_ji=0.0; + v3_zero(&(exchange->dzeta_ij)); + v3_zero(&(exchange->dzeta_ji)); + + return 0; +} + +/* tersoff 2 body post part */ + +int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) { + + /* + * here we have to allow for the 3bp sums + * + * that is: + * - zeta_ij, dzeta_ij + * - zeta_ji, dzeta_ji + * + * to compute the 3bp contribution to: + * - Vij, dVij + * - dVji + * + */ + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + + t_3dvec force,temp; + t_3dvec *dist_ij; + double b,db,tmp; + double f_c,df_c,f_a,df_a; + double chi,ni,betaini,nj,betajnj; + double zeta; + + params=moldyn->pot_params; + exchange=&(params->exchange); + + /* we do not run if f_c_ij was detected to be 0! */ + if(!(exchange->run2bp_post)) + return 0; + + f_c=exchange->f_c; + df_c=exchange->df_c; + f_a=exchange->f_a; + df_a=exchange->df_a; + betaini=exchange->betaini; + betajnj=exchange->betajnj; + ni=*(exchange->n_i); + nj=*(exchange->n_j); + chi=exchange->chi; + dist_ij=&(exchange->dist_ij); + + /* Vij and dVij */ + zeta=exchange->zeta_ij; + if(zeta==0.0) { + moldyn->debug++; /* just for debugging ... */ + b=chi; + v3_scale(&force,dist_ij,df_a*b*f_c); + } + else { + tmp=betaini*pow(zeta,ni-1.0); /* beta^n * zeta^n-1 */ + b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ + db=chi*pow(b,-1.0/(2*ni)-1); /* x(...)^(-1/2n - 1) */ + b=db*b; /* b_ij */ + db*=-0.5*tmp; /* db_ij */ + v3_scale(&force,&(exchange->dzeta_ij),f_a*db); + v3_scale(&temp,dist_ij,df_a*b); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,f_c); + } + v3_scale(&temp,dist_ij,df_c*b*f_a); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,-0.5); + + /* add force */ + v3_add(&(ai->f),&(ai->f),&force); + + /* virial */ + virial_calc(ai,&force,dist_ij); + //ai->virial.xx-=force.x*dist_ij->x; + //ai->virial.yy-=force.y*dist_ij->y; + //ai->virial.zz-=force.z*dist_ij->z; + //ai->virial.xy-=force.x*dist_ij->y; + //ai->virial.xz-=force.x*dist_ij->z; + //ai->virial.yz-=force.y*dist_ij->z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij (3bp) contrib: [%d %d sum]\n",ai->tag,aj->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVij (3bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); +} +#endif + + /* add energy of 3bp sum */ + moldyn->energy+=(0.5*f_c*b*f_a); + + /* dVji */ + zeta=exchange->zeta_ji; + if(zeta==0.0) { + moldyn->debug++; + b=chi; + v3_scale(&force,dist_ij,df_a*b*f_c); + } + else { + tmp=betajnj*pow(zeta,nj-1.0); /* beta^n * zeta^n-1 */ + b=(1+zeta*tmp); /* 1 + beta^n zeta^n */ + db=chi*pow(b,-1.0/(2*nj)-1); /* x(...)^(-1/2n - 1) */ + b=db*b; /* b_ij */ + db*=-0.5*tmp; /* db_ij */ + v3_scale(&force,&(exchange->dzeta_ji),f_a*db); + v3_scale(&temp,dist_ij,df_a*b); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,f_c); + } + v3_scale(&temp,dist_ij,df_c*b*f_a); + v3_add(&force,&force,&temp); + v3_scale(&force,&force,-0.5); + + /* add force */ + v3_add(&(ai->f),&(ai->f),&force); + + /* virial - plus sign, as dist_ij = - dist_ji - (really??) */ +// TEST ... with a minus instead + virial_calc(ai,&force,dist_ij); + //ai->virial.xx-=force.x*dist_ij->x; + //ai->virial.yy-=force.y*dist_ij->y; + //ai->virial.zz-=force.z*dist_ij->z; + //ai->virial.xy-=force.x*dist_ij->y; + //ai->virial.xz-=force.x*dist_ij->z; + //ai->virial.yz-=force.y*dist_ij->z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVji (3bp) contrib: [%d %d sum]\n",ai->tag,aj->tag); + printf("adding %f %f %f\n",force.x,force.y,force.z); + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVji (3bp) contrib:\n"); + printf("%f | %f\n",force.x*dist_ij->x,ai->virial.xx); + printf("%f | %f\n",force.y*dist_ij->y,ai->virial.yy); + printf("%f | %f\n",force.z*dist_ij->z,ai->virial.zz); +} +#endif + + return 0; +} + +/* tersoff 3 body part */ + +int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) { + + t_tersoff_mult_params *params; + t_tersoff_exchange *exchange; + t_3dvec dist_ij,dist_ik,dist_jk; + t_3dvec temp1,temp2; + t_3dvec *dzeta; + double R,S,S2,s_r; + double B,mu; + double d_ij,d_ik,d_jk,d_ij2,d_ik2,d_jk2; + double rr,dd; + double f_c,df_c; + double f_c_ik,df_c_ik,arg; + double f_c_jk; + double n,c,d,h; + double c2,d2,c2d2; + double cos_theta,d_costheta1,d_costheta2; + double h_cos,d2_h_cos2; + double frac,g,zeta,chi; + double tmp; + int brand; + + params=moldyn->pot_params; + exchange=&(params->exchange); + + if(!(exchange->run3bp)) + return 0; + + /* + * calc of 3bp contribution of V_ij and dV_ij/ji/jk & + * 2bp contribution of dV_jk + * + * for Vij and dV_ij we still need: + * - b_ij, db_ij (zeta_ij) + * - f_c_ik, df_c_ik, constants_i, cos_theta_ijk, d_costheta_ijk + * + * for dV_ji we still need: + * - b_ji, db_ji (zeta_ji) + * - f_c_jk, d_c_jk, constants_j, cos_theta_jik, d_costheta_jik + * + * for dV_jk we need: + * - f_c_jk + * - f_a_jk + * - db_jk (zeta_jk) + * - f_c_ji, df_c_ji, constants_j, cos_theta_jki, d_costheta_jki + * + */ + + /* + * get exchange data + */ + + /* dist_ij, d_ij - this is < S_ij ! */ + dist_ij=exchange->dist_ij; + d_ij=exchange->d_ij; + d_ij2=exchange->d_ij2; + + /* f_c_ij, df_c_ij (same for ji) */ + f_c=exchange->f_c; + df_c=exchange->df_c; + + /* + * calculate unknown values now ... + */ + + /* V_ij and dV_ij stuff (in b_ij there is f_c_ik) */ + + /* dist_ik, d_ik */ + v3_sub(&dist_ik,&(ak->r),&(ai->r)); + if(bc) check_per_bound(moldyn,&dist_ik); + d_ik2=v3_absolute_square(&dist_ik); + + /* ik constants */ + brand=ai->brand; + if(brand==ak->brand) { + R=params->R[brand]; + S=params->S[brand]; + S2=params->S2[brand]; + } + else { + R=params->Rmixed; + S=params->Smixed; + S2=params->S2mixed; + } + + /* zeta_ij/dzeta_ij contribution only for d_ik < S */ + if(d_ik2n_i); + c=*(exchange->c_i); + d=*(exchange->d_i); + h=*(exchange->h_i); + c2=exchange->ci2; + d2=exchange->di2; + c2d2=exchange->ci2di2; + + /* cosine of theta_ijk by scalaproduct */ + rr=v3_scalar_product(&dist_ij,&dist_ik); + dd=d_ij*d_ik; + cos_theta=rr/dd; + + /* d_costheta */ + tmp=1.0/dd; + d_costheta1=cos_theta/d_ij2-tmp; + d_costheta2=cos_theta/d_ik2-tmp; + + /* some usefull values */ + h_cos=(h-cos_theta); + d2_h_cos2=d2+(h_cos*h_cos); + frac=c2/(d2_h_cos2); + + /* g(cos_theta) */ + g=1.0+c2d2-frac; + + /* d_costheta_ij and dg(cos_theta) - needed in any case! */ + v3_scale(&temp1,&dist_ij,d_costheta1); + v3_scale(&temp2,&dist_ik,d_costheta2); + v3_add(&temp1,&temp1,&temp2); + v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ + + /* f_c_ik & df_c_ik + {d,}zeta contribution */ + dzeta=&(exchange->dzeta_ij); + if(d_ik f_c_ik=1.0; + // => df_c_ik=0.0; of course we do not set this! + + /* zeta_ij */ + exchange->zeta_ij+=g; + + /* dzeta_ij */ + v3_add(dzeta,dzeta,&temp1); + } + else { + /* {d,}f_c_ik */ + s_r=S-R; + arg=M_PI*(d_ik-R)/s_r; + f_c_ik=0.5+0.5*cos(arg); + df_c_ik=0.5*sin(arg)*(M_PI/(s_r*d_ik)); + + /* zeta_ij */ + exchange->zeta_ij+=f_c_ik*g; + + /* dzeta_ij */ + v3_scale(&temp1,&temp1,f_c_ik); + v3_scale(&temp2,&dist_ik,g*df_c_ik); + v3_add(&temp1,&temp1,&temp2); + v3_add(dzeta,dzeta,&temp1); + } + } + + /* dV_ji stuff (in b_ji there is f_c_jk) + dV_jk stuff! */ + + /* dist_jk, d_jk */ + v3_sub(&dist_jk,&(ak->r),&(aj->r)); + if(bc) check_per_bound(moldyn,&dist_jk); + d_jk2=v3_absolute_square(&dist_jk); + + /* jk constants */ + brand=aj->brand; + if(brand==ak->brand) { + R=params->R[brand]; + S=params->S[brand]; + S2=params->S2[brand]; + B=params->B[brand]; + mu=params->mu[brand]; + chi=1.0; + } + else { + R=params->Rmixed; + S=params->Smixed; + S2=params->S2mixed; + B=params->Bmixed; + mu=params->mu_m; + chi=params->chi; + } + + /* zeta_ji/dzeta_ji contribution only for d_jk < S_jk */ + if(d_jk2n_j); + c=*(exchange->c_j); + d=*(exchange->d_j); + h=*(exchange->h_j); + c2=exchange->cj2; + d2=exchange->dj2; + c2d2=exchange->cj2dj2; + + /* cosine of theta_jik by scalaproduct */ + rr=-v3_scalar_product(&dist_ij,&dist_jk); /* -1, as ij -> ji */ + dd=d_ij*d_jk; + cos_theta=rr/dd; + + /* d_costheta */ + d_costheta1=1.0/dd; + d_costheta2=cos_theta/d_ij2; + + /* some usefull values */ + h_cos=(h-cos_theta); + d2_h_cos2=d2+(h_cos*h_cos); + frac=c2/(d2_h_cos2); + + /* g(cos_theta) */ + g=1.0+c2d2-frac; + + /* d_costheta_jik and dg(cos_theta) - needed in any case! */ + v3_scale(&temp1,&dist_jk,d_costheta1); + v3_scale(&temp2,&dist_ij,-d_costheta2); /* ji -> ij => -1 */ + //v3_add(&temp1,&temp1,&temp2); + v3_sub(&temp1,&temp1,&temp2); /* there is a minus! */ + v3_scale(&temp1,&temp1,-2.0*frac*h_cos/d2_h_cos2); /* dg */ + + /* store dg in temp2 and use it for dVjk later */ + v3_copy(&temp2,&temp1); + + /* f_c_jk + {d,}zeta contribution (df_c_jk = 0) */ + dzeta=&(exchange->dzeta_ji); + if(d_jkzeta_ji+=g; + + /* dzeta_ji */ + v3_add(dzeta,dzeta,&temp1); + } + else { + /* f_c_jk */ + s_r=S-R; + arg=M_PI*(d_jk-R)/s_r; + f_c_jk=0.5+0.5*cos(arg); + + /* zeta_ji */ + exchange->zeta_ji+=f_c_jk*g; + + /* dzeta_ji */ + v3_scale(&temp1,&temp1,f_c_jk); + v3_add(dzeta,dzeta,&temp1); + } + + /* dV_jk stuff | add force contribution on atom i immediately */ + if(exchange->d_ij_between_rs) { + zeta=f_c*g; + v3_scale(&temp1,&temp2,f_c); + v3_scale(&temp2,&dist_ij,df_c*g); + v3_add(&temp2,&temp2,&temp1); /* -> dzeta_jk in temp2 */ + } + else { + zeta=g; + // dzeta_jk is simply dg, which is stored in temp2 + } + /* betajnj * zeta_jk ^ nj-1 */ + tmp=exchange->betajnj*pow(zeta,(n-1.0)); + tmp=-chi/2.0*pow((1+tmp*zeta),(-1.0/(2.0*n)-1))*tmp; + v3_scale(&temp2,&temp2,tmp*B*exp(-mu*d_jk)*f_c_jk*0.5); + v3_add(&(ai->f),&(ai->f),&temp2); /* -1 skipped in f_a calc ^ */ + /* scaled with 0.5 ^ */ + + /* virial */ + ai->virial.xx-=temp2.x*dist_jk.x; + ai->virial.yy-=temp2.y*dist_jk.y; + ai->virial.zz-=temp2.z*dist_jk.z; + ai->virial.xy-=temp2.x*dist_jk.y; + ai->virial.xz-=temp2.x*dist_jk.z; + ai->virial.yz-=temp2.y*dist_jk.z; + +#ifdef DEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVjk (3bp) contrib: [%d %d %d]\n",ai->tag,aj->tag,ak->tag); + printf("adding %f %f %f\n",temp2.x,temp2.y,temp2.z); + printf("total i: %f %f %f\n",ai->f.x,ai->f.y,ai->f.z); +} +#endif +#ifdef VDEBUG +if(ai==&(moldyn->atom[0])) { + printf("dVjk (3bp) contrib:\n"); + printf("%f | %f\n",temp2.x*dist_jk.x,ai->virial.xx); + printf("%f | %f\n",temp2.y*dist_jk.y,ai->virial.yy); + printf("%f | %f\n",temp2.z*dist_jk.z,ai->virial.zz); +} +#endif + + } + + return 0; +} + diff --git a/potentials/tersoff_orig.h b/potentials/tersoff_orig.h new file mode 100644 index 0000000..d5d4a66 --- /dev/null +++ b/potentials/tersoff_orig.h @@ -0,0 +1,87 @@ +/* + * tersoff_orig.h - tersoff potential header file + * + * author: Frank Zirkelbach + * + */ + +#ifndef TERSOFF_H +#define TERSOFF_H + +/* tersoff exchange type */ +typedef struct s_tersoff_echange { + double f_c,df_c; + double f_a,df_a; + + t_3dvec dist_ij; + double d_ij2; + double d_ij; + + double chi; + + double *beta_i; + double *beta_j; + double *n_i; + double *n_j; + double *c_i; + double *c_j; + double *d_i; + double *d_j; + double *h_i; + double *h_j; + + double ci2; + double cj2; + double di2; + double dj2; + double ci2di2; + double cj2dj2; + double betaini; + double betajnj; + + u8 run3bp; + u8 run2bp_post; + u8 d_ij_between_rs; + + double zeta_ij; + double zeta_ji; + t_3dvec dzeta_ij; + t_3dvec dzeta_ji; +} t_tersoff_exchange; + +/* tersoff mult (2!) potential parameters */ +typedef struct s_tersoff_mult_params { + double S[2]; /* tersoff cutoff radii */ + double S2[2]; /* tersoff cutoff radii squared */ + double R[2]; /* tersoff cutoff radii */ + double Smixed; /* mixed S radius */ + double S2mixed; /* mixed S radius squared */ + double Rmixed; /* mixed R radius */ + double A[2]; /* factor of tersoff attractive part */ + double B[2]; /* factor of tersoff repulsive part */ + double Amixed; /* mixed A factor */ + double Bmixed; /* mixed B factor */ + double lambda[2]; /* tersoff lambda */ + double lambda_m; /* mixed lambda */ + double mu[2]; /* tersoff mu */ + double mu_m; /* mixed mu */ + + double chi; + + double beta[2]; + double n[2]; + double c[2]; + double d[2]; + double h[2]; + + t_tersoff_exchange exchange; /* exchange between 2bp and 3bp calc */ +} t_tersoff_mult_params; + +/* function prototypes */ +int tersoff_mult_complete_params(t_tersoff_mult_params *p); +int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai); +int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int tersoff_mult_post_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc); +int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc); + +#endif diff --git a/report/report.h b/report/report.h index 4fe42f7..bd4ce88 100644 --- a/report/report.h +++ b/report/report.h @@ -87,10 +87,10 @@ set xtic auto \n\ set ytic auto \n\ set title 'Pressure vs. time' \n\ set xlabel 'Time [fs]' \n\ -set ylabel 'Pressure [atm]' \n\ +set ylabel 'Pressure [bar]' \n\ set terminal postscript eps enhanced color solid lw 1 'Helvetica' 14 \n\ set output 'pressure.eps' \n\ -plot \"pressure\" using 1:2 title 'Pressure' with lines \ +plot \"pressure\" using 1:2 title 'P' with lines , \"pressure\" using 1:3 title '

' with lines , \"pressure\" using 1:4 title 'P (global virial)' with lines , \"pressure\" using 1:5 title '

' with lines \ "; static char temperature_plot_script[]="\ @@ -104,7 +104,7 @@ set xlabel 'Time [fs]' \n\ set ylabel 'Temperature [K]' \n\ set terminal postscript eps enhanced color solid lw 1 'Helvetica' 14 \n\ set output 'temperature.eps' \n\ -plot \"temperature\" using 1:2 title 'Temperature' with lines \ +plot \"temperature\" using 1:2 title 'T' with lines , \"temperature\" using 1:3 title '' with lines \ "; #endif diff --git a/sic.c b/sic.c index 682d89e..a78f3a0 100644 --- a/sic.c +++ b/sic.c @@ -14,9 +14,10 @@ #include "potentials/harmonic_oscillator.h" #include "potentials/lennard_jones.h" #include "potentials/tersoff.h" +//#include "potentials/tersoff_orig.h" -#define INJECT 20 -#define NR_ATOMS 20 +#define INJECT 1 +#define NR_ATOMS 4 int hook(void *moldyn,void *hook_params) { @@ -97,8 +98,13 @@ int main(int argc,char **argv) { /* choose potential */ set_potential1b(&md,tersoff_mult_1bp); set_potential2b(&md,tersoff_mult_2bp); - set_potential2b_post(&md,tersoff_mult_post_2bp); - set_potential3b(&md,tersoff_mult_3bp); + //set_potential3b_j1(&md,tersoff_mult_2bp); + //set_potential3b_k1(&md,tersoff_mult_3bp); + //set_potential3b_j3(&md,tersoff_mult_post_2bp); + set_potential3b_j1(&md,tersoff_mult_3bp_j1); + set_potential3b_k1(&md,tersoff_mult_3bp_k1); + set_potential3b_j2(&md,tersoff_mult_3bp_j2); + set_potential3b_k2(&md,tersoff_mult_3bp_k2); //set_potential2b(&md,lennard_jones); //set_potential2b(&md,harmonic_oscillator); set_potential_params(&md,&tp); @@ -198,7 +204,7 @@ int main(int argc,char **argv) { /* set temperature & pressure */ set_temperature(&md,atof(argv[2])+273.0); - set_pressure(&md,ATM); + set_pressure(&md,BAR); /* set p/t scaling */ //set_pt_scale(&md,P_SCALE_BERENDSEN,0.001, @@ -211,14 +217,14 @@ int main(int argc,char **argv) { /* create the simulation schedule */ /* initial configuration */ - moldyn_add_schedule(&md,500,1.0); + moldyn_add_schedule(&md,10000,1.0); /* adding atoms */ - for(inject=0;inject