X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=moldyn.c;h=0fd1aca88d3b7243ee58cbe2d219cf0e4e2190f9;hb=512390ceb93a2dd630943165b35bba683e0ffcfc;hp=3d669d223401ddd8fe9277e9ea07654186e7018e;hpb=83775c491117faa149281d0302fc8b8064d6b080;p=physik%2Fposic.git diff --git a/moldyn.c b/moldyn.c index 3d669d2..0fd1aca 100644 --- a/moldyn.c +++ b/moldyn.c @@ -5,17 +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) { @@ -73,7 +215,7 @@ int destroy_lattice(t_atom *atom) { return 0; } -int thermal_init(t_atom *atom,t_random *random,int count,double t) { +int thermal_init(t_moldyn *moldyn,t_random *random,int count) { /* * - gaussian distribution of velocities @@ -84,11 +226,14 @@ int thermal_init(t_atom *atom,t_random *random,int count,double t) { 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; @@ -111,15 +256,18 @@ int thermal_init(t_atom *atom,t_random *random,int count,double t) { } /* velocity scaling */ - scale_velocity(atom,count,t); + scale_velocity(moldyn,count); return 0; } -int scale_velocity(t_atom *atom,int count,double t) { +int scale_velocity(t_moldyn *moldyn,int count) { int i; double e,c; + t_atom *atom; + + atom=moldyn->atom; /* * - velocity scaling (E = 3/2 N k T), E: kinetic energy @@ -127,7 +275,7 @@ int scale_velocity(t_atom *atom,int count,double t) { e=0.0; for(i=0;it)); 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; +} + /* * @@ -189,6 +350,22 @@ t_3dvec get_total_p(t_atom *atom, int count) { 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); @@ -197,11 +374,44 @@ int moldyn_integrate(t_moldyn *moldyn) { /* integration step */ moldyn->integrate(moldyn); - /* check for visualiziation */ - // to be continued ... - if(!(i%1)) { - visual_atoms(moldyn->visual,i*moldyn->tau, - moldyn->atom,moldyn->count); + /* 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); } } @@ -233,7 +443,7 @@ int velocity_verlet(t_moldyn *moldyn) { /* velocities */ v3_scale(&delta,&(atom[i].f),0.5*tau/atom[i].mass); - v3_add(&(atom[i].r),&(atom[i].r),&delta); + v3_add(&(atom[i].v),&(atom[i].v),&delta); } /* forces depending on chosen potential */ @@ -255,6 +465,72 @@ int velocity_verlet(t_moldyn *moldyn) { * */ +/* harmonic oscillator potential and force */ + +double potential_harmonic_oscillator(t_moldyn *moldyn) { + + t_ho_params *params; + t_atom *atom; + int i,j; + int count; + t_3dvec distance; + double d,u; + double sc,equi_dist; + + params=moldyn->pot_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) {