int average_and_fluctuation_calc(t_moldyn *moldyn) {
+ int denom;
+
if(moldyn->total_steps<moldyn->avg_skip)
return 0;
- int denom=moldyn->total_steps+1-moldyn->avg_skip;
+ denom=moldyn->total_steps+1-moldyn->avg_skip;
/* assume up to date energies, temperature, pressure etc */
double thermodynamic_pressure_calc(t_moldyn *moldyn) {
- t_3dvec dim,*tp;
+ t_3dvec dim;
+ //t_3dvec *tp;
double u_up,u_down,dv;
double scale,p;
t_atom *store;
for(i=0;i<lc->cells;i++) {
#ifdef STATIC_LISTS
- //printf(" ---> %d free %p\n",i,lc->subcell[i]);
free(lc->subcell[i]);
#else
//printf(" ---> %d free %p\n",i,lc->subcell[i].start);
/* get current time */
gettimeofday(&t2,NULL);
- printf("\rsched:%d, steps:%d, T:%3.1f/%3.1f P:%4.1f/%4.1f V:%6.1f (%d)",
- sched->count,i,
- moldyn->t,moldyn->t_avg,
- moldyn->p_avg/BAR,moldyn->gp_avg/BAR,
- moldyn->volume,
- (int)(t2.tv_sec-t1.tv_sec));
- fflush(stdout);
+printf("\rsched:%d, steps:%d/%d, T:%3.1f/%3.1f P:%4.1f/%4.1f V:%6.1f (%d)",
+ sched->count,i,moldyn->total_steps,
+ moldyn->t,moldyn->t_avg,
+ moldyn->p_avg/BAR,moldyn->gp_avg/BAR,
+ moldyn->volume,
+ (int)(t2.tv_sec-t1.tv_sec));
+
+ fflush(stdout);
/* copy over time */
t1=t2;
/* check for hooks */
if(sched->hook) {
- printf("\n ## schedule hook %d/%d start ##\n",
- sched->count+1,sched->total_sched-1);
+ printf("\n ## schedule hook %d start ##\n",
+ sched->count);
sched->hook(moldyn,sched->hook_params);
printf(" ## schedule hook end ##\n");
}
}
size=sizeof(t_moldyn);
- cnt=read(fd,moldyn,size);
- if(cnt!=size) {
- perror("[moldyn] load save file read (moldyn)");
- return cnt;
+
+ while(size) {
+ cnt=read(fd,moldyn,size);
+ if(cnt<0) {
+ perror("[moldyn] load save file read (moldyn)");
+ return cnt;
+ }
+ size-=cnt;
}
size=moldyn->count*sizeof(t_atom);
return -1;
}
- cnt=read(fd,moldyn->atom,size);
- if(cnt!=size) {
- perror("[moldyn] load save file read (atoms)");
- return cnt;
+ while(size) {
+ cnt=read(fd,moldyn->atom,size);
+ if(cnt<0) {
+ perror("[moldyn] load save file read (atoms)");
+ return cnt;
+ }
+ size-=cnt;
}
// hooks etc ...
t_list *this;
unsigned char bc;
t_3dvec dist;
- double d,norm;
+ double d;
+ //double norm;
int o,s;
unsigned char ibrand;
lc=&(moldyn->lc);
- slots=(int)(moldyn->cutoff/dr);
+ slots=moldyn->cutoff/dr;
o=2*slots;
printf("[moldyn] pair correlation calc info:\n");
jtom=this->current->data;
#endif
-
- if(jtom==&(itom[i]))
- continue;
-
- /* only count pairs once */
- if(itom[i].tag>jtom->tag)
+ /* only count pairs once,
+ * skip same atoms */
+ if(itom[i].tag>=jtom->tag)
continue;
/*
if(bc) check_per_bound(moldyn,&dist);
d=v3_absolute_square(&dist);
- /* ignore if greater cutoff */
- if(d>moldyn->cutoff_square)
+ /* ignore if greater or equal cutoff */
+ if(d>=moldyn->cutoff_square)
continue;
/* fill the slots */
d=sqrt(d);
s=(int)(d/dr);
+ /* should never happen but it does 8) -
+ * related to -ffloat-store problem! */
+ if(s>=slots) s=slots-1;
+
if(ibrand!=jtom->brand) {
/* mixed */
stat[s]+=1;
/* type b - type b bonds */
stat[s+o]+=1;
}
-
#ifdef STATIC_LISTS
}
#else
#include "potentials/harmonic_oscillator.h"
#include "potentials/lennard_jones.h"
#include "potentials/albe.h"
-
#ifdef TERSOFF_ORIG
#include "potentials/tersoff_orig.h"
#else
#include "potentials/tersoff.h"
#endif
-//#define INJECT 800
-#define INJECT 1
-#define NR_ATOMS 1
-#define R_C 1.5
-#define T_C 5.0
-//#define INJ_LENX (1*ALBE_LC_SIC)
-//#define INJ_LENY (1*ALBE_LC_SIC)
-//#define INJ_LENZ (1*ALBE_LC_SIC)
-#define INJ_LENX (1*ALBE_LC_SI)
-#define INJ_LENY (1*ALBE_LC_SI)
-#define INJ_LENZ (1*ALBE_LC_SI)
-#define INJ_TYPE_SILICON
-//#define INJ_TYPE_CARBON
-#define INJ_OFFSET (ALBE_LC_SI/8.0)
-#define RELAX_S 20
-
-#define LCNTX 9
-#define LCNTY 9
-#define LCNTZ 9
-#define PRERUN 40
-#define POSTRUN 3000
-
-#define R_TITLE "Silicon self-interstitial"
-#define LOG_E 10
-#define LOG_T 10
-#define LOG_P 10
-#define LOG_S 100
-#define LOG_V 20
-
typedef struct s_hp {
- int a_count; /* atom count */
- u8 quit; /* quit mark */
- int argc; /* arg count */
- char **argv; /* args */
+ int prerun_count; /* prerun count */
+ int insert_count; /* insert count */
+ int postrun_count; /* post run count */
+ unsigned char state; /* current state */
+ int argc; /* arg count */
+ char **argv; /* args */
} t_hp;
-int hook_del_atom(void *moldyn,void *hook_params) {
-
- t_moldyn *md;
- t_hp *hp;
+#define STATE_PRERUN 0x00
+#define STATE_INSERT 0x01
+#define STATE_POSTRUN 0x02
- md=moldyn;
- hp=hook_params;
+/* include the config file */
+#include "config.h"
- set_pt_scale(md,0,0,T_SCALE_BERENDSEN,100.0);
- del_atom(md,2);
+int insert_atoms(t_moldyn *moldyn) {
- return 0;
-}
-
-int hook_add_atom(void *moldyn,void *hook_params) {
-
- t_moldyn *md;
+ int i,j;
+ u8 run;
t_3dvec r,v,dist;
double d;
- unsigned char run;
- int i,j;
- t_atom *atom;
- t_hp *hp;
-
- md=moldyn;
- hp=hook_params;
- /* quit */
- if(hp->quit)
- return 0;
-
- /* switch on t scaling */
- if(md->schedule.count==0)
- set_pt_scale(md,0,0,T_SCALE_BERENDSEN,100.0);
+ t_atom *atom;
- /* last schedule add if there is enough carbon inside */
- if(hp->a_count==(INJECT*NR_ATOMS)) {
- hp->quit=1;
- moldyn_add_schedule(md,POSTRUN,1.0);
- return 0;
- }
+ atom=moldyn->atom;
- /* more relaxing time for too high temperatures */
- if(md->t-md->t_ref>T_C) {
- moldyn_add_schedule(md,RELAX_S,1.0);
- return 0;
- }
+ v.x=0; v.y=0; v.z=0;
- /* inject carbon atoms */
- printf("injecting another %d atoms ... (-> %d / %d)\n",
- NR_ATOMS,hp->a_count+NR_ATOMS,INJECT*NR_ATOMS);
- for(j=0;j<NR_ATOMS;j++) {
+ for(j=0;j<INS_ATOMS;j++) {
run=1;
while(run) {
// tetrahedral
r.z=0.0;
*/
// hexagonal
- //
+ /*
r.x=-1.0/8.0*ALBE_LC_SI;
r.y=-1.0/8.0*ALBE_LC_SI;
r.z=1.0/8.0*ALBE_LC_SI;
- //
+ */
// 110 dumbbell
/*
r.x=(-0.5+0.25+0.125)*ALBE_LC_SI;
md->atom[4372].r.y=(-0.5+0.125+0.125)*ALBE_LC_SI;
*/
// random
- /*
- r.x=(rand_get_double(&(md->random))-0.5)*INJ_LENX;
- r.y=(rand_get_double(&(md->random))-0.5)*INJ_LENY;
- r.z=(rand_get_double(&(md->random))-0.5)*INJ_LENZ;
- */
+ //
+ r.x=(rand_get_double(&(moldyn->random))-0.5)*INS_LENX;
+ r.y=(rand_get_double(&(moldyn->random))-0.5)*INS_LENY;
+ r.z=(rand_get_double(&(moldyn->random))-0.5)*INS_LENZ;
+ //
// offset
- r.x+=INJ_OFFSET;
- r.y+=INJ_OFFSET;
- r.z+=INJ_OFFSET;
+ r.x+=INS_OFFSET;
+ r.y+=INS_OFFSET;
+ r.z+=INS_OFFSET;
/* assume valid coordinates */
run=0;
- for(i=0;i<md->count;i++) {
- atom=&(md->atom[i]);
+ for(i=0;i<moldyn->count;i++) {
+ atom=&(moldyn->atom[i]);
v3_sub(&dist,&(atom->r),&r);
+ check_per_bound(moldyn,&dist);
d=v3_absolute_square(&dist);
/* reject coordinates */
- if(d<R_C) {
+ if(d<INS_R_C) {
//printf("atom %d - %f\n",i,d);
run=1;
break;
}
}
}
- v.x=0; v.y=0; v.z=0;
-#ifdef INJ_TYPE_CARBON
- add_atom(md,C,M_C,1,
-#else
- add_atom(md,SI,M_SI,0,
-#endif
- ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_HB|ATOM_ATTR_VB,
+ add_atom(moldyn,INS_TYPE,INS_MASS,INS_BRAND,
+ ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|\
+ //ATOM_ATTR_HB|ATOM_ATTR_VB,
+ ATOM_ATTR_HB,
&r,&v);
}
- hp->a_count+=NR_ATOMS;
- /* add schedule for simulating injected atoms ;) */
- moldyn_add_schedule(md,RELAX_S,1.0);
+ return 0;
+}
+
+int sic_hook(void *moldyn,void *hook_params) {
+
+ t_hp *hp;
+ t_moldyn *md;
+ int steps;
+ double tau;
+
+ hp=hook_params;
+ md=moldyn;
+
+ /* switch on t scaling */
+ if(md->schedule.count==0)
+ set_pt_scale(md,0,0,T_SCALE_BERENDSEN,100.0);
+
+ /* my lousy state machine ! */
+
+ /* switch to insert state immediately */
+ if(hp->state==STATE_PRERUN)
+ hp->state=STATE_INSERT;
+
+ /* act according to state */
+ switch(hp->state) {
+ case STATE_INSERT:
+ /* check temperature */
+ if(md->t_avg-md->t_ref>INS_DELTA_TC) {
+ steps=INS_RELAX;
+ tau=INS_TAU;
+ break;
+ }
+ /* insert atoms */
+ hp->insert_count+=1;
+ printf(" ### insert atoms (%d/%d) ###\n",
+ hp->insert_count*INS_ATOMS,INS_RUNS*INS_ATOMS);
+ insert_atoms(md);
+ /* change state after last insertion */
+ if(hp->insert_count==INS_RUNS)
+ hp->state=STATE_POSTRUN;
+ break;
+ case STATE_POSTRUN:
+ /* settings */
+ if(md->t-md->t_ref>POST_DELTA_TC) {
+ steps=POST_RELAX;
+ tau=POST_TAU;
+ }
+ /* decrease temperature */
+ hp->postrun_count+=1;
+ printf(" ### postrun (%d/%d) ###\n",
+ hp->postrun_count,POST_RUNS);
+ set_temperature(md,md->t_ref-POST_DT);
+ if(hp->postrun_count==POST_RUNS)
+ return 0;
+ break;
+ default:
+ printf("[hook] FATAL (default case!?!)\n");
+ break;
+ }
+
+ /* add schedule */
+ moldyn_add_schedule(md,steps,tau);
return 0;
}
int main(int argc,char **argv) {
- /* check argv */
- //if(argc!=3) {
- // printf("[sic] usage: %s <logdir> <temperatur>\n",argv[0]);
- // return -1;
- //}
-
/* main moldyn structure */
t_moldyn md;
// ATOM_ATTR_2BP|ATOM_ATTR_HB,
0,LCNTX,LCNTY,LCNTZ,NULL);
// 1,LCNTX,LCNTY,LCNTZ,NULL);
- //
/* create zinkblende structure */
/*
set_pressure(&md,BAR);
/* set amount of steps to skip before average calc */
- set_avg_skip(&md,(8.0/10.0*PRERUN));
+ set_avg_skip(&md,AVG_SKIP);
/* set p/t scaling */
//set_pt_scale(&md,0,0,T_SCALE_BERENDSEN,100.0);
thermal_init(&md,TRUE);
/* create the simulation schedule */
- moldyn_add_schedule(&md,PRERUN,1.0);
+ moldyn_add_schedule(&md,PRERUN,PRE_TAU);
/* schedule hook function */
memset(&hookparam,0,sizeof(t_hp));
hookparam.argc=argc;
hookparam.argv=argv;
- moldyn_set_schedule_hook(&md,&hook_add_atom,&hookparam);
+ moldyn_set_schedule_hook(&md,&sic_hook,&hookparam);
//moldyn_set_schedule_hook(&md,&hook_del_atom,&hookparam);
//moldyn_add_schedule(&md,POSTRUN,1.0);