Merge branch 'master' of git://git.gromacs.org/gromacs
[gromacs/adressmacs.git] / src / contrib / ehole.c
blob1243e769a1bf9bd095fcd8b0db360aefb063106e
1 /*
2 * $Id: ehole.c,v 1.12.2.3 2008/02/29 07:02:43 spoel Exp $
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.3.3
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2008, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
33 * And Hey:
34 * Groningen Machine for Chemical Simulation
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <stdlib.h>
41 #include <math.h>
42 #include <string.h>
43 #include "typedefs.h"
44 #include "smalloc.h"
45 #include "macros.h"
46 #include "copyrite.h"
47 #include "statutil.h"
48 #include "gmx_fatal.h"
49 #include "random.h"
50 #include "pdbio.h"
51 #include "futil.h"
52 #include "physics.h"
53 #include "xvgr.h"
54 #include "vec.h"
55 #include "names.h"
56 #include "ehdata.h"
58 typedef struct {
59 int maxparticle;
60 int maxstep;
61 int nsim;
62 int nsave;
63 int nana;
64 int seed;
65 int nevent;
66 gmx_bool bForce;
67 gmx_bool bScatter;
68 gmx_bool bHole;
69 real dt;
70 real deltax;
71 real epsr;
72 real Alj;
73 real Eauger;
74 real Efermi;
75 real Eband;
76 real rho;
77 real matom;
78 real evdist;
79 real size;
80 } t_eh_params;
82 #define ELECTRONMASS 5.447e-4
83 /* Resting mass of electron in a.m.u. */
84 #define HOLEMASS (0.8*ELECTRONMASS)
85 /* Effective mass of a hole! */
86 #define HBAR (PLANCK/2*M_PI)
88 static void calc_forces(int n,rvec x[],rvec f[],real q[],real ener[],real Alj)
90 const real facel = FACEL;
91 int i,j,m;
92 rvec dx;
93 real qi,r2,r_1,r_2,fscal,df,vc,vctot,vlj,vljtot;
95 for(i=0; (i<n); i++)
96 clear_rvec(f[i]);
98 vctot = vljtot = 0;
99 for(i=0; (i<n-1); i++) {
100 qi = q[i]*facel;
101 for(j=i+1; (j<n); j++) {
102 rvec_sub(x[i],x[j],dx);
103 r2 = iprod(dx,dx);
104 r_1 = 1.0/sqrt(r2);
105 r_2 = r_1*r_1;
106 vc = qi*q[j]*r_1;
107 vctot += vc;
108 vlj = Alj*(r_2*r_2*r_2);
109 vljtot += vlj;
110 fscal = (6*vlj+vc)*r_2;
111 for(m=0; (m<DIM); m++) {
112 df = fscal*dx[m];
113 f[i][m] += df;
114 f[j][m] -= df;
118 ener[eCOUL] = vctot;
119 ener[eREPULS] = vljtot;
120 ener[ePOT] = vctot+vljtot;
123 static void calc_ekin(int nparticle,rvec v[],rvec vold[],
124 real q[],real m[],real ener[],real eparticle[])
126 rvec vt;
127 real ekh=0,eke=0,ee;
128 int i;
130 for(i=0; (i<nparticle); i++) {
131 rvec_add(v[i],vold[i],vt);
132 ee = 0.125*m[i]*iprod(vt,vt);
133 eparticle[i] = ee/ELECTRONVOLT;
134 if (q[i] > 0)
135 ekh += ee;
136 else
137 eke += ee;
139 ener[eHOLE] = ekh;
140 ener[eELECTRON] = eke;
141 ener[eKIN] = ekh+eke+ener[eLATTICE];
144 static void polar2cart(real amp,real phi,real theta,rvec v)
146 real ss = sin(theta);
148 v[XX] = amp*cos(phi)*ss;
149 v[YY] = amp*sin(phi)*ss;
150 v[ZZ] = amp*cos(theta);
153 static void rand_vector(real amp,rvec v,int *seed)
155 real theta,phi;
157 theta = M_PI*rando(seed);
158 phi = 2*M_PI*rando(seed);
159 polar2cart(amp,phi,theta,v);
162 static void rotate_theta(rvec v,real nv,real dth,int *seed,FILE *fp)
164 real dphi,theta0,phi0,cc,ss;
165 matrix mphi,mtheta,mphi_1,mtheta_1;
166 rvec vp,vq,vold;
168 copy_rvec(v,vold);
169 theta0 = acos(v[ZZ]/nv);
170 phi0 = atan2(v[YY],v[XX]);
171 if (fp)
172 fprintf(fp,"Theta = %g Phi = %g\n",theta0,phi0);
174 clear_mat(mphi);
175 cc = cos(-phi0);
176 ss = sin(-phi0);
177 mphi[XX][XX] = mphi[YY][YY] = cc;
178 mphi[XX][YY] = -ss;
179 mphi[YY][XX] = ss;
180 mphi[ZZ][ZZ] = 1;
181 m_inv(mphi,mphi_1);
183 clear_mat(mtheta);
184 cc = cos(-theta0);
185 ss = sin(-theta0);
186 mtheta[XX][XX] = mtheta[ZZ][ZZ] = cc;
187 mtheta[XX][ZZ] = ss;
188 mtheta[ZZ][XX] = -ss;
189 mtheta[YY][YY] = 1;
190 m_inv(mtheta,mtheta_1);
192 dphi = 2*M_PI*rando(seed);
194 /* Random rotation */
195 polar2cart(nv,dphi,dth,vp);
197 mvmul(mtheta_1,vp,vq);
198 mvmul(mphi_1,vq,v);
200 if (fp) {
201 real cold = cos_angle(vold,v);
202 real cnew = cos(dth);
203 if (fabs(cold-cnew) > 1e-4)
204 fprintf(fp,"cos(theta) = %8.4f should be %8.4f dth = %8.4f dphi = %8.4f\n",
205 cold,cnew,dth,dphi);
209 static int create_electron(int index,rvec x[],rvec v[],rvec vold[],rvec vv,
210 real m[],real q[],
211 rvec center,real e0,int *seed)
213 m[index] = ELECTRONMASS;
214 q[index] = -1;
216 clear_rvec(v[index]);
217 svmul(sqrt(2*e0/m[index]),vv,v[index]);
218 copy_rvec(v[index],vold[index]);
219 copy_rvec(center,x[index]);
221 return index+1;
224 static int create_pair(int index,rvec x[],rvec v[],rvec vold[],
225 real m[],real q[],
226 rvec center,real e0,t_eh_params *ehp,rvec dq)
228 static real massfactor = 2*HOLEMASS/(ELECTRONMASS*(ELECTRONMASS+HOLEMASS));
229 rvec x0;
230 real ve,e1;
232 m[index] = ELECTRONMASS;
233 m[index+1] = HOLEMASS;
234 q[index] = -1;
235 q[index+1] = 1;
237 rand_vector(0.5*ehp->deltax,x0,&ehp->seed);
238 rvec_sub(center,x0,x[index]);
239 rvec_add(center,x0,x[index+1]);
241 ve = sqrt(massfactor*e0)/(0.5*ehp->deltax);
242 svmul(-ve,x0,v[index]);
243 svmul(ELECTRONMASS*ve/HOLEMASS,x0,v[index+1]);
244 copy_rvec(v[index],vold[index]);
245 copy_rvec(v[index+1],vold[index+1]);
246 e1 = 0.5*(m[index]*iprod(v[index],v[index])+
247 m[index+1]*iprod(v[index+1],v[index+1]));
248 if (fabs(e0-e1)/e0 > 1e-6)
249 gmx_fatal(FARGS,"Error in create pair: e0 = %f, e1 = %f\n",e0,e1);
251 return index+2;
254 static int scatter_all(FILE *fp,int nparticle,int nstep,
255 rvec x[],rvec v[],rvec vold[],
256 real mass[],real charge[],real ener[],real eparticle[],
257 t_eh_params *ehp,int *nelec,int *nhole,t_ana_scat s[])
259 int i,m,np;
260 real p_el,p_inel,ptot,nv,ekin,omega,theta,costheta,Q,e0,ekprime,size2,fac;
261 rvec dq,center,vv;
263 size2 = sqr(ehp->size);
264 np = nparticle;
265 for(i=0; (i<nparticle); i++) {
266 /* Check cross sections, assume same cross sections for holes
267 * as for electrons, for elastic scattering
269 if ((size2 == 0) || (iprod(x[i],x[i]) < size2)) {
270 nv = norm(v[i]);
271 ekin = eparticle[i];
272 p_el = cross_el(ekin,ehp->rho,NULL)*nv*ehp->dt;
274 /* Only electrons can scatter inelasticlly */
275 if (charge[i] < 0)
276 p_inel = cross_inel(ekin,ehp->rho,NULL)*nv*ehp->dt;
277 else
278 p_inel = 0;
280 /* Test whether we have to scatter at all */
281 ptot = (1 - (1-p_el)*(1-p_inel));
282 if (debug && 0)
283 fprintf(debug,"p_el = %10.3e p_inel = %10.3e ptot = %10.3e\n",
284 p_el,p_inel,ptot);
285 if (rando(&ehp->seed) < ptot) {
286 /* Test whether we have to scatter inelastic */
287 ptot = p_inel/(p_el+p_inel);
288 if (rando(&ehp->seed) < ptot) {
289 add_scatter_event(&(s[i]),x[i],TRUE,ehp->dt*nstep,ekin);
290 /* Energy loss in inelastic collision is omega */
291 if ((omega = get_omega(ekin,&ehp->seed,debug,NULL)) >= ekin)
292 gmx_fatal(FARGS,"Energy transfer error: omega = %f, ekin = %f",
293 omega,ekin);
294 else {
295 /* Scattering angle depends on energy and energy loss */
296 Q = get_q_inel(ekin,omega,&ehp->seed,debug,NULL);
297 costheta = -0.5*(Q+omega-2*ekin)/sqrt(ekin*(ekin-omega));
299 /* See whether we have gained enough energy to liberate another
300 * hole-electron pair
302 e0 = band_ener(&ehp->seed,debug,NULL);
303 ekprime = e0 + omega - (ehp->Efermi+0.5*ehp->Eband);
304 /* Ouput */
305 fprintf(fp,"Inelastic %d: Ekin=%.2f Omega=%.2f Q=%.2f Eband=%.2f costheta=%.3f\n",
306 i+1,ekin,omega,Q,e0,costheta);
307 if ((costheta < -1) || (costheta > 1)) {
308 fprintf(fp,"Electron/hole creation not possible due to momentum constraints\n");
309 /* Scale the velocity according to the energy loss */
310 svmul(sqrt(1-omega/ekin),v[i],v[i]);
311 ener[eLATTICE] += omega*ELECTRONVOLT;
313 else {
314 theta = acos(costheta);
316 copy_rvec(v[i],dq);
317 /* Rotate around theta with random delta phi */
318 rotate_theta(v[i],nv,theta,&ehp->seed,debug);
319 /* Scale the velocity according to the energy loss */
320 svmul(sqrt(1-omega/ekin),v[i],v[i]);
321 rvec_dec(dq,v[i]);
323 if (ekprime > 0) {
324 if (np >= ehp->maxparticle-2)
325 gmx_fatal(FARGS,"Increase -maxparticle flag to more than %d",
326 ehp->maxparticle);
327 if (ehp->bHole) {
328 np = create_pair(np,x,v,vold,mass,charge,x[i],
329 ekprime*ELECTRONVOLT,ehp,dq);
330 (*nhole)++;
332 else {
333 copy_rvec(x[i],center);
334 center[ZZ] += ehp->deltax;
335 rand_vector(1,vv,&ehp->seed);
336 np = create_electron(np,x,v,vold,vv,mass,charge,
337 x[i],ekprime*ELECTRONVOLT,&ehp->seed);
339 ener[eLATTICE] += (omega-ekprime)*ELECTRONVOLT;
340 (*nelec)++;
342 else
343 ener[eLATTICE] += omega*ELECTRONVOLT;
347 else {
348 add_scatter_event(&(s[i]),x[i],FALSE,ehp->dt*nstep,ekin);
349 if (debug)
350 fprintf(debug,"Elastic scattering event\n");
352 /* Scattering angle depends on energy only */
353 theta = get_theta_el(ekin,&ehp->seed,debug,NULL);
354 /* Rotate around theta with random delta phi */
355 rotate_theta(v[i],nv,theta,&ehp->seed,debug);
360 return np;
363 static void integrate_velocities(int nparticle,rvec vcur[],rvec vnext[],
364 rvec f[],real m[],real dt)
366 int i,k;
368 for(i=0; (i<nparticle); i++)
369 for(k=0; (k<DIM); k++)
370 vnext[i][k] = vcur[i][k] + f[i][k]*dt/m[i];
373 static void integrate_positions(int nparticle,rvec x[],rvec v[],real dt)
375 int i,k;
377 for(i=0; (i<nparticle); i++)
378 for(k=0; (k<DIM); k++)
379 x[i][k] += v[i][k]*dt;
382 static void print_header(FILE *fp,t_eh_params *ehp)
384 fprintf(fp,"Welcome to the electron-hole simulation!\n");
385 fprintf(fp,"The energies printed in this file are in eV\n");
386 fprintf(fp,"Coordinates are in nm because of fixed width format\n");
387 fprintf(fp,"Atomtypes are used for coloring in rasmol\n");
388 fprintf(fp,"O: electrons (red), N: holes (blue)\n");
389 fprintf(fp,"Parametes for this simulation\n");
390 fprintf(fp,"seed = %d maxstep = %d dt = %g\n",
391 ehp->seed,ehp->maxstep,ehp->dt);
392 fprintf(fp,"nsave = %d nana = %d Force = %s Scatter = %s Hole = %s\n",
393 ehp->nsave,ehp->nana,gmx_bool_names[ehp->bForce],
394 gmx_bool_names[ehp->bScatter],gmx_bool_names[ehp->bHole]);
395 if (ehp->bForce)
396 fprintf(fp,"Force constant for repulsion Alj = %g\n",ehp->Alj);
399 static void do_sim(FILE *fp,char *pdbfn,t_eh_params *ehp,
400 int *nelec,int *nhole,t_ana_struct *total,
401 t_histo *hmfp,t_ana_ener *ae,int serial)
403 FILE *efp;
404 int nparticle[2];
405 rvec *x,*v[2],*f,center,vv;
406 real *charge,*mass,*ener,*eparticle;
407 t_ana_struct *ana_struct;
408 t_ana_scat *ana_scat;
409 int step,i,cur = 0;
410 #define next (1-cur)
412 /* Open output file */
413 fprintf(fp,"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
414 fprintf(fp,"Simulation %d/%d\n",serial+1,ehp->nsim);
416 ana_struct = init_ana_struct(ehp->maxstep,ehp->nana,ehp->dt,
417 ehp->maxparticle);
418 /* Initiate arrays. The charge array determines whether a particle is
419 * a hole (+1) or an electron (-1)
421 snew(x,ehp->maxparticle); /* Position */
422 snew(v[0],ehp->maxparticle); /* Velocity */
423 snew(v[1],ehp->maxparticle); /* Velocity */
424 snew(f,ehp->maxparticle); /* Force */
425 snew(charge,ehp->maxparticle); /* Charge */
426 snew(mass,ehp->maxparticle); /* Mass */
427 snew(eparticle,ehp->maxparticle); /* Energy per particle */
428 snew(ana_scat,ehp->maxparticle); /* Scattering event statistics */
429 snew(ener,eNR); /* Eenergies */
431 clear_rvec(center);
432 /* Use first atom as center, it has coordinate 0,0,0 */
433 if (ehp->bScatter) {
434 /* Start with an Auger electron */
435 nparticle[cur]=0;
436 for(i=0; (i<ehp->nevent); i++) {
437 if (ehp->nevent == 1) {
438 clear_rvec(vv);
439 vv[ZZ] = 1;
441 else
442 rand_vector(1,vv,&ehp->seed);
443 nparticle[cur] = create_electron(nparticle[cur],x,v[cur],v[next],
444 vv,mass,charge,center,
445 ehp->Eauger*ELECTRONVOLT,&ehp->seed);
446 rand_vector(ehp->evdist*0.1,vv,&ehp->seed);
447 rvec_inc(center,vv);
450 else if (ehp->bForce) {
451 /* Start with two electron and hole pairs */
452 nparticle[cur] = create_pair(0,x,v[cur],v[next],mass,charge,center,
453 0.2*ehp->Eauger*ELECTRONVOLT,ehp,center);
454 center[ZZ] = 0.5; /* nm */
455 (*nelec)++;
456 (*nhole)++;
458 else {
459 fprintf(fp,"Nothing to do. Doei.\n");
460 return;
462 nparticle[next] = nparticle[cur];
463 for(step=0; (step<=ehp->maxstep); step++) {
464 if (ehp->bScatter)
465 nparticle[next] = scatter_all(fp,nparticle[cur],step,x,v[cur],v[next],
466 mass,charge,ener,eparticle,ehp,
467 nelec,nhole,ana_scat);
469 if (ehp->bForce)
470 calc_forces(nparticle[cur],x,f,charge,ener,ehp->Alj);
472 integrate_velocities(nparticle[next],v[cur],v[next],f,mass,ehp->dt);
474 calc_ekin(nparticle[next],v[cur],v[next],charge,mass,ener,eparticle);
475 ener[eTOT] = ener[eKIN] + ener[ePOT];
477 /* Produce output whenever the user says so, or when new
478 * particles have been created.
480 if ((step == ehp->maxstep) ||
481 ((ehp->nana != 0) && ((step % ehp->nana) == 0))) {
482 analyse_structure(ana_struct,(step*ehp->dt),center,x,
483 nparticle[next],charge);
484 add_ana_ener(ae,(step/ehp->nana),ener);
486 cur = next;
488 integrate_positions(nparticle[cur],x,v[cur],ehp->dt);
490 for(i=0; (i<nparticle[cur]); i++) {
491 analyse_scatter(&(ana_scat[i]),hmfp);
492 done_scatter(&(ana_scat[i]));
494 sfree(ener);
495 sfree(ana_scat);
496 sfree(eparticle);
497 sfree(mass);
498 sfree(charge);
499 sfree(f);
500 sfree(v[1]);
501 sfree(v[0]);
502 sfree(x);
503 dump_as_pdb(pdbfn,ana_struct);
504 add_ana_struct(total,ana_struct);
505 done_ana_struct(ana_struct);
506 sfree(ana_struct);
509 void do_sims(int NFILE,t_filenm fnm[],t_eh_params *ehp)
511 t_ana_struct *total;
512 t_ana_ener *ae;
513 t_histo *helec,*hmfp;
514 int *nelectron;
515 int i,imax,ne,nh;
516 real aver;
517 FILE *fp,*logfp;
518 char *pdbbuf,*ptr,*rptr;
520 ptr = ftp2fn(efPDB,NFILE,fnm);
521 rptr = strdup(ptr);
522 if ((ptr = strstr(rptr,".pdb")) != NULL)
523 *ptr = '\0';
524 snew(pdbbuf,strlen(rptr)+10);
526 total = init_ana_struct(ehp->maxstep,ehp->nana,ehp->dt,1);
527 hmfp = init_histo((int)ehp->Eauger,0,(int)ehp->Eauger);
528 helec = init_histo(500,0,500);
529 snew(ae,1);
531 logfp = ffopen(ftp2fn(efLOG,NFILE,fnm),"w");
532 print_header(logfp,ehp);
534 for(i=0; (i<ehp->nsim); i++) {
535 nh = ne = 0;
536 sprintf(pdbbuf,"%s-%d.pdb",rptr,i+1);
537 do_sim(logfp,pdbbuf,ehp,&ne,&nh,total,hmfp,ae,i);
538 add_histo(helec,ne,1);
539 fprintf(stderr,"\rSim: %d/%d",i+1,ehp->nsim);
541 fprintf(stderr,"\n");
542 ffclose(logfp);
544 sfree(rptr);
545 sfree(pdbbuf);
546 dump_ana_struct(opt2fn("-maxdist",NFILE,fnm),opt2fn("-nion",NFILE,fnm),
547 opt2fn("-gyr_com",NFILE,fnm),opt2fn("-gyr_origin",NFILE,fnm),
548 total,ehp->nsim);
549 dump_ana_ener(ae,ehp->nsim,ehp->dt*ehp->nana,
550 opt2fn("-ener",NFILE,fnm),total);
551 done_ana_struct(total);
553 dump_histo(helec,opt2fn("-histo",NFILE,fnm),
554 "Number of cascade electrons","N","",enormFAC,1.0/ehp->nsim);
555 dump_histo(hmfp,opt2fn("-mfp",NFILE,fnm),
556 "Mean Free Path","Ekin (eV)","MFP (nm)",enormNP,1.0);
559 int main(int argc,char *argv[])
561 const char *desc[] = {
562 "ehole performs a molecular dynamics simulation of electrons and holes",
563 "in an implicit lattice. The lattice is modeled through scattering cross",
564 "sections, for elastic and inelastic scattering.",
565 "A detailed description of the scatterning processes simulated in ehole",
566 "can be found in Timneanu et al. Chemical Physics 299 (2004) 277-283",
567 "The paper also includes a description how to calculate the input files.[PAR]",
568 "Description of the input files for ehole:[BR]",
569 "[TT]-sigel.dat[tt]: elastic cross section (per atom). Two columns: Impact electron energy (eV) vs Elastic cross section (A2).[BR]",
570 "[TT]-siginel.dat[tt]: inelastic cross section (per atom). Two columns: Impact electron energy (eV) vs Inelastic cross section (A2).[BR]",
571 "[TT]-band-ener.dat[tt]: Probability of finding an electron in the valence band.",
572 "Two columns: Impact electron energy (eV) vs Probability[BR]",
573 "[TT]-eloss.dat[tt]: Probability of energy loss due to inelastic scattering. Three columns: Impact electron energy (eV) vs Integrated probability vs Energy loss in inelastic scattering (eV).[BR]",
574 "[TT]-theta-el.dat[tt]: Probability of elastic scattering angle. Three columns: Impact electron energy (eV) vs Integrated probability vs Scattering angle (rad).[BR]",
575 "[TT]-qtrans.dat[tt]: Four columns: Impact electron energy (eV) vs Inelastic energy loss (eV) vs Integrated probability vs Scattering angle (rad).[PAR]",
576 "The program produces a number of output files. It is important that",
577 "the actual content is well-defined, sucht that no misunderstanding can",
578 "occur (famous last words...). Anyway, the program does a number of",
579 "simulations, and averages results over these. Here is a list of each of",
580 "the results and how they are computed:[BR]",
581 "[TT]-histo[tt] Distribution of nuber of liberated secondary electrons per simulation.[BR]",
582 "[TT]-maxdist[tt] The maximum distance from the origin that any electron in any simulation reaches.[BR]",
583 "[TT]-gyr_com[tt] The radius of gyration of the electron cloud with respect to its center of mass (contains 4 columns).[BR]",
584 "[TT]-gyr_origin[tt] The radius of gyration of the electron cloud with respect to the origin (contains 4 columns).[BR]",
585 "[TT]-mfp[tt] The mean free path of the electrons as a function of energy. If this is not a smooth curve you need to increase the number of simulations.[BR]",
586 "[TT]-nion[tt] The number of ions as a function of time, averaged over simulations.[BR]",
587 "[TT]-ener[tt] The energy terms in the simulation (note that there are multiple columns, so use xmgrace -nxy). This shows important information about the stability of the simulation, that is the total energy should be conserved. In this figure you can also inspect the kinetic energy per electron in order to check whether the electrons have thermalized.[BR]"
589 static t_eh_params ehp = {
590 100, /* Max number of particles. Is a parameter but should be dynamic */
591 100000, /* Number of integration steps */
592 1, /* nsave */
593 1, /* nana */
594 1, /* nsim */
595 1993, /* Random seed */
596 1, /* Number of events */
597 FALSE, /* Use forces */
598 TRUE, /* Use scattering */
599 FALSE, /* Creat holes */
600 1e-5, /* Time step */
601 0.05, /* Distance (nm) between electron and hole when creating them */
602 1.0, /* Dielectric constant */
603 0.1, /* Force constant for repulsion function */
604 250, /* Starting energy for the first Auger electron */
605 28.7, /* Fermi level (eV) of diamond. */
606 5.46, /* Band gap energy (eV) of diamond */
607 3.51, /* Density of the solid */
608 12.011, /* (Average) mass of the atom */
609 10000.0,/* Distance between events */
610 0.0 /* Size of the system */
612 static gmx_bool bTest = FALSE;
613 t_pargs pa[] = {
614 { "-maxparticle", FALSE, etINT, {&ehp.maxparticle},
615 "Maximum number of particles" },
616 { "-maxstep", FALSE, etINT, {&ehp.maxstep},
617 "Number of integration steps" },
618 { "-nsim", FALSE, etINT, {&ehp.nsim},
619 "Number of independent simulations writing to different output files" },
620 { "-nsave", FALSE, etINT, {&ehp.nsave},
621 "Number of steps after which to save output. 0 means only when particles created. Final step is always written." },
622 { "-nana", FALSE, etINT, {&ehp.nana},
623 "Number of steps after which to do analysis." },
624 { "-seed", FALSE, etINT, {&ehp.seed},
625 "Random seed" },
626 { "-dt", FALSE, etREAL, {&ehp.dt},
627 "Integration time step (ps)" },
628 { "-rho", FALSE, etREAL, {&ehp.rho},
629 "Density of the sample (kg/l). Default is for Diamond" },
630 { "-matom", FALSE, etREAL, {&ehp.matom},
631 "Mass (a.m.u.) of the atom in the solid. Default is C" },
632 { "-fermi", FALSE, etREAL, {&ehp.Efermi},
633 "Fermi energy (eV) of the sample. Default is for Diamond" },
634 { "-gap", FALSE, etREAL, {&ehp.Eband},
635 "Band gap energy (eV) of the sample. Default is for Diamond" },
636 { "-auger", FALSE, etREAL, {&ehp.Eauger},
637 "Impact energy (eV) of first electron" },
638 { "-dx", FALSE, etREAL, {&ehp.deltax},
639 "Distance between electron and hole when creating a pair" },
640 { "-test", FALSE, etBOOL, {&bTest},
641 "Test table aspects of the program rather than running it for real" },
642 { "-force", FALSE, etBOOL, {&ehp.bForce},
643 "Apply Coulomb/Repulsion forces" },
644 { "-hole", FALSE, etBOOL, {&ehp.bHole},
645 "Create electron-hole pairs rather than electrons only" },
646 { "-scatter", FALSE, etBOOL, {&ehp.bScatter},
647 "Do the scattering events" },
648 { "-nevent", FALSE, etINT, {&ehp.nevent},
649 "Number of initial Auger electrons" },
650 { "-evdist", FALSE, etREAL, {&ehp.evdist},
651 "Average distance (A) between initial electronss" },
652 { "-size", FALSE, etREAL, {&ehp.size},
653 "Size of the spherical system. If 0, then it is infinite" }
655 #define NPA asize(pa)
656 t_filenm fnm[] = {
657 { efLOG, "-g", "ehole", ffWRITE },
658 { efDAT, "-sigel", "sigel", ffREAD },
659 { efDAT, "-sigin", "siginel", ffREAD },
660 { efDAT, "-eloss", "eloss", ffREAD },
661 { efDAT, "-qtrans", "qtrans", ffREAD },
662 { efDAT, "-band", "band-ener", ffREAD },
663 { efDAT, "-thetael", "theta-el", ffREAD },
664 { efPDB, "-o", "ehole", ffWRITE },
665 { efXVG, "-histo", "histo", ffWRITE },
666 { efXVG, "-maxdist", "maxdist", ffWRITE },
667 { efXVG, "-gyr_com", "gyr_com", ffWRITE },
668 { efXVG, "-gyr_origin", "gyr_origin", ffWRITE },
669 { efXVG, "-mfp", "mfp", ffWRITE },
670 { efXVG, "-nion", "nion", ffWRITE },
671 { efXVG, "-ener", "ener", ffWRITE }
673 #define NFILE asize(fnm)
674 int seed;
676 CopyRight(stdout,argv[0]);
677 parse_common_args(&argc,argv,PCA_BE_NICE,NFILE,fnm,
678 NPA,pa,asize(desc),desc,0,NULL);
679 please_cite(stdout,"Timneanu2004a");
681 if (ehp.deltax <= 0)
682 gmx_fatal(FARGS,"Delta X should be > 0");
683 ehp.Alj = FACEL*pow(ehp.deltax,5);
684 ehp.rho = (ehp.rho/ehp.matom)*AVOGADRO*1e-21;
686 init_tables(NFILE,fnm,ehp.rho);
688 if (bTest)
689 test_tables(&ehp.seed,ftp2fn(efPDB,NFILE,fnm),ehp.rho);
690 else
691 do_sims(NFILE,fnm,&ehp);
693 thanx(stdout);
695 return 0;