X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=moldyn.c;h=0fd1aca88d3b7243ee58cbe2d219cf0e4e2190f9;hb=512390ceb93a2dd630943165b35bba683e0ffcfc;hp=ba3c1a30c8c2bd995a2ac2264d9a79984db01015;hpb=706aed2512544b99ff34308fdb673b19ee884ce0;p=physik%2Fposic.git diff --git a/moldyn.c b/moldyn.c index ba3c1a3..0fd1aca 100644 --- a/moldyn.c +++ b/moldyn.c @@ -5,14 +5,159 @@ * */ -#include "moldyn.h" - +#define _GNU_SOURCE #include #include +#include +#include +#include +#include +#include +#include + +#include "moldyn.h" #include "math/math.h" #include "init/init.h" +#include "random/random.h" +#include "visual/visual.h" + +int moldyn_usage(char **argv) { + + printf("\n%s usage:\n\n",argv[0]); + printf("--- general options ---\n"); + printf("-E (log total energy)\n"); + printf("-M (log total momentum)\n"); + printf("-D (dump total information)\n"); + printf("-S (single save file)\n"); + printf("-V (rasmol file)\n"); + printf("--- physics options ---\n"); + printf("-T [K] (%f)\n",MOLDYN_TEMP); + printf("-t [s] (%f)\n",MOLDYN_TAU); + printf("-R (%d)\n",MOLDYN_RUNS); + printf("\n"); + + return 0; +} + +int moldyn_parse_argv(t_moldyn *moldyn,int argc,char **argv) { + + int i; + memset(moldyn,0,sizeof(t_moldyn)); + + /* default values */ + moldyn->t=MOLDYN_TEMP; + moldyn->tau=MOLDYN_TAU; + moldyn->time_steps=MOLDYN_RUNS; + + /* parse argv */ + for(i=1;iewrite=atoi(argv[++i]); + strncpy(moldyn->efb,argv[++i],64); + break; + case 'M': + moldyn->mwrite=atoi(argv[++i]); + strncpy(moldyn->mfb,argv[++i],64); + break; + case 'D': + moldyn->dwrite=atoi(argv[++i]); + strncpy(moldyn->dfb,argv[++i],64); + break; + case 'S': + moldyn->swrite=atoi(argv[++i]); + strncpy(moldyn->sfb,argv[++i],64); + break; + case 'V': + moldyn->vwrite=atoi(argv[++i]); + strncpy(moldyn->vfb,argv[++i],64); + break; + case 'T': + moldyn->t=atof(argv[++i]); + break; + case 't': + moldyn->tau=atof(argv[++i]); + break; + case 'R': + moldyn->time_steps=atoi(argv[++i]); + break; + default: + printf("unknown option %s\n",argv[i]); + moldyn_usage(argv); + return -1; + } + } else { + moldyn_usage(argv); + return -1; + } + } + + return 0; +} + +int moldyn_log_init(t_moldyn *moldyn,void *v) { + + moldyn->lvstat=0; + t_visual *vis; + + vis=v; + + if(moldyn->ewrite) { + moldyn->efd=open(moldyn->efb,O_WRONLY|O_CREAT|O_TRUNC); + if(moldyn->efd<0) { + perror("[moldyn] efd open"); + return moldyn->efd; + } + dprintf(moldyn->efd,"# moldyn total energy logfile\n"); + moldyn->lvstat|=MOLDYN_LVSTAT_TOTAL_E; + } + + if(moldyn->mwrite) { + moldyn->mfd=open(moldyn->mfb,O_WRONLY|O_CREAT|O_TRUNC); + if(moldyn->mfd<0) { + perror("[moldyn] mfd open"); + return moldyn->mfd; + } + dprintf(moldyn->mfd,"# moldyn total momentum logfile\n"); + moldyn->lvstat|=MOLDYN_LVSTAT_TOTAL_M; + } + + if(moldyn->swrite) + moldyn->lvstat|=MOLDYN_LVSTAT_SAVE; + + if(moldyn->dwrite) { + moldyn->dfd=open(moldyn->dfb,O_WRONLY|O_CREAT|O_TRUNC); + if(moldyn->dfd<0) { + perror("[moldyn] dfd open"); + return moldyn->dfd; + } + write(moldyn->dfd,moldyn,sizeof(t_moldyn)); + moldyn->lvstat|=MOLDYN_LVSTAT_DUMP; + } + + if((moldyn->vwrite)&&(vis)) { + moldyn->visual=vis; + visual_init(vis,moldyn->vfb); + moldyn->lvstat|=MOLDYN_LVSTAT_VISUAL; + } + + moldyn->lvstat|=MOLDYN_LVSTAT_INITIALIZED; + + return 0; +} + +int moldyn_shutdown(t_moldyn *moldyn) { + + if(moldyn->efd) close(moldyn->efd); + if(moldyn->mfd) close(moldyn->efd); + if(moldyn->dfd) close(moldyn->efd); + if(moldyn->visual) visual_tini(moldyn->visual); + + return 0; +} int create_lattice(unsigned char type,int element,double mass,double lc, int a,int b,int c,t_atom **atom) { @@ -42,8 +187,8 @@ int create_lattice(unsigned char type,int element,double mass,double lc, ret=diamond_init(a,b,c,lc,*atom,&origin); break; default: - ret=-1; printf("unknown lattice type (%02x)\n",type); + return -1; } /* debug */ @@ -51,6 +196,7 @@ int create_lattice(unsigned char type,int element,double mass,double lc, printf("ok, there is something wrong ...\n"); printf("calculated -> %d atoms\n",count); printf("created -> %d atoms\n",ret); + return -1; } while(count) { @@ -62,3 +208,405 @@ int create_lattice(unsigned char type,int element,double mass,double lc, return ret; } +int destroy_lattice(t_atom *atom) { + + if(atom) free(atom); + + return 0; +} + +int thermal_init(t_moldyn *moldyn,t_random *random,int count) { + + /* + * - gaussian distribution of velocities + * - zero total momentum + * - velocity scaling (E = 3/2 N k T), E: kinetic energy + */ + + int i; + double v,sigma; + t_3dvec p_total,delta; + t_atom *atom; + + atom=moldyn->atom; + + /* gaussian distribution of velocities */ + v3_zero(&p_total); + for(i=0;it/atom[i].mass); + /* x direction */ + v=sigma*rand_get_gauss(random); + atom[i].v.x=v; + p_total.x+=atom[i].mass*v; + /* y direction */ + v=sigma*rand_get_gauss(random); + atom[i].v.y=v; + p_total.y+=atom[i].mass*v; + /* z direction */ + v=sigma*rand_get_gauss(random); + atom[i].v.z=v; + p_total.z+=atom[i].mass*v; + } + + /* zero total momentum */ + v3_scale(&p_total,&p_total,1.0/count); + for(i=0;iatom; + + /* + * - velocity scaling (E = 3/2 N k T), E: kinetic energy + */ + e=0.0; + for(i=0;it)); + for(i=0;ipotential(moldyn)); +} + +double get_total_energy(t_moldyn *moldyn) { + + double e; + + e=get_e_kin(moldyn->atom,moldyn->count); + e+=get_e_pot(moldyn); + + return e; +} + +t_3dvec get_total_p(t_atom *atom, int count) { + + t_3dvec p,p_total; + int i; + + v3_zero(&p_total); + for(i=0;iatom[0].mass)); + tau*=1.0E-9; + if(tautau) + printf("[moldyn] warning: time step (%f > %.15f)\n", + moldyn->tau,tau); + + return tau; +} + + +/* + * + * 'integration of newtons equation' - algorithms + * + */ + +/* start the integration */ + +int moldyn_integrate(t_moldyn *moldyn) { + + int i; + unsigned int e,m,s,d,v; + t_3dvec p; + + int fd; + char fb[128]; + + e=moldyn->ewrite; + m=moldyn->mwrite; + s=moldyn->swrite; + d=moldyn->dwrite; + v=moldyn->vwrite; + + if(!(moldyn->lvstat&MOLDYN_LVSTAT_INITIALIZED)) { + printf("[moldyn] warning, lv system not initialized\n"); + return -1; + } + + /* calculate initial forces */ + moldyn->force(moldyn); + + for(i=0;itime_steps;i++) { + /* integration step */ + moldyn->integrate(moldyn); + + /* check for log & visualiziation */ + if(e) { + if(!(i%e)) + dprintf(moldyn->efd, + "%.15f %.45f\n",i*moldyn->tau, + get_total_energy(moldyn)); + } + if(m) { + if(!(i%m)) { + p=get_total_p(moldyn->atom,moldyn->count); + dprintf(moldyn->mfd, + "%.15f %.45f\n",i*moldyn->tau, + v3_norm(&p)); + } + } + if(s) { + if(!(i%s)) { + snprintf(fb,128,"%s-%f-%.15f.save",moldyn->sfb, + moldyn->t,i*moldyn->tau); + fd=open(fb,O_WRONLY|O_TRUNC|O_CREAT); + if(fd<0) perror("[moldyn] save fd open"); + else { + write(fd,moldyn,sizeof(t_moldyn)); + write(fd,moldyn->atom, + moldyn->count*sizeof(t_atom)); + } + } + } + if(d) { + if(!(i%d)) + write(moldyn->dfd,moldyn->atom, + moldyn->count*sizeof(t_atom)); + + } + if(v) { + if(!(i%v)) + visual_atoms(moldyn->visual,i*moldyn->tau, + moldyn->atom,moldyn->count); + } + } + + return 0; +} + +/* velocity verlet */ + +int velocity_verlet(t_moldyn *moldyn) { + + int i,count; + double tau,tau_square; + t_3dvec delta; + t_atom *atom; + + atom=moldyn->atom; + count=moldyn->count; + tau=moldyn->tau; + + tau_square=tau*tau; + + for(i=0;idim)); + + /* velocities */ + v3_scale(&delta,&(atom[i].f),0.5*tau/atom[i].mass); + v3_add(&(atom[i].v),&(atom[i].v),&delta); + } + + /* forces depending on chosen potential */ + moldyn->force(moldyn); + + for(i=0;ipot_params; + atom=moldyn->atom; + sc=params->spring_constant; + equi_dist=params->equilibrium_distance; + count=moldyn->count; + + u=0.0; + for(i=0;iatom; + count=moldyn->count; + params=moldyn->pot_params; + sc=params->spring_constant; + equi_dist=params->equilibrium_distance; + + for(i=0;idim)); + d=v3_norm(&distance); + if(d<=moldyn->cutoff) { + v3_scale(&force,&distance, + (-sc*(1.0-(equi_dist/d)))); + v3_add(&(atom[i].f),&(atom[i].f),&force); + v3_sub(&(atom[j].f),&(atom[j].f),&force); + } + } + } + + return 0; +} + + +/* lennard jones potential & force for one sort of atoms */ + +double potential_lennard_jones(t_moldyn *moldyn) { + + t_lj_params *params; + t_atom *atom; + int i,j; + int count; + t_3dvec distance; + double d,help; + double u; + double eps,sig6,sig12; + + params=moldyn->pot_params; + atom=moldyn->atom; + count=moldyn->count; + eps=params->epsilon; + sig6=params->sigma6; + sig12=params->sigma12; + + u=0.0; + for(i=0;iatom; + count=moldyn->count; + params=moldyn->pot_params; + eps=params->epsilon; + sig6=params->sigma6; + sig12=params->sigma12; + + for(i=0;idim)); + d=v3_absolute_square(&distance); + if(d<=moldyn->cutoff_square) { + h1=1.0/d; /* 1/r^2 */ + d=h1*h1; /* 1/r^4 */ + h2=d*d; /* 1/r^8 */ + h1*=d; /* 1/r^6 */ + h1*=h2; /* 1/r^14 */ + h1*=sig12; + h2*=sig6; + d=12.0*h1-6.0*h2; + d*=eps; + v3_scale(&force,&distance,d); + v3_add(&(atom[j].f),&(atom[j].f),&force); + v3_sub(&(atom[i].f),&(atom[i].f),&force); + } + } + } + + return 0; +} +