X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=moldyn.c;h=94d596e91878237cf41a127cd8aa947cbcd18997;hb=fb951c04e522e4637618bf622fc67194c2a7b15f;hp=faa6b7c3ea6354a7f1ab08a51cca462d567fd405;hpb=2d562a1946322ae5b70bdce180321f32adbeab62;p=physik%2Fposic.git diff --git a/moldyn.c b/moldyn.c index faa6b7c..94d596e 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; } @@ -96,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?"on":"off"); + printf(" visualize simulation box: %s\n",visualize?"yes":"no"); + printf(" delta volume (pressure calc): %f\n",moldyn->dv); return 0; } @@ -115,6 +143,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 +154,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 +205,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 +219,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 +232,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 +245,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; } @@ -242,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; @@ -257,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; @@ -292,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) { @@ -429,6 +482,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++) { @@ -460,6 +515,29 @@ 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; + + double_ekin=0; + 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 +556,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 +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; + 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; + + 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); + + 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; @@ -592,11 +818,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 +880,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++) @@ -797,10 +1021,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; @@ -863,6 +1091,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++) { @@ -884,12 +1115,15 @@ 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 */ if(e) { if(!(i%e)) + 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)); } @@ -946,7 +1180,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 +1191,15 @@ int velocity_verlet(t_moldyn *moldyn) { for(i=0;ienergy=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; - + /* reset site energy */ itom[i].e=0.0; + } + + /* get energy,force and virial of every atom */ + for(i=0;ifunc1b(moldyn,&(itom[i])); @@ -1130,6 +1373,29 @@ int potential_force_calc(t_moldyn *moldyn) { #ifdef DEBUG printf("\n\n"); #endif +#ifdef VDEBUG +printf("\n\n"); +#endif + +temperature_calc(moldyn); +pressure_calc(moldyn); +ideal_gas_law_pressure(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; } @@ -1176,23 +1442,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; @@ -1212,6 +1484,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 */ @@ -1220,16 +1494,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; @@ -1376,6 +1654,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 +1722,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 ... */ @@ -1514,7 +1801,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); } @@ -1551,6 +1837,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 */ @@ -1582,12 +1876,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])) { @@ -1596,6 +1891,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 +1913,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 +1961,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 +1976,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 +2013,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 +2066,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 +2081,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 +2109,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 +2119,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 +2188,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 }