int main(void) { int i,j; float e1,e2,f,x,y; static float a[NA+1]={0.0,3.0,0.2,0.5,1.0,0.7,0.3}; float dyda[NA+1],df[NA+1]; printf("\n%6s %8s %8s %7s %7s %7s %7s %7s\n", "x","y","dyda1","dyda2","dyda3","dyda4","dyda5","dyda6"); for (i=1;i<=NPT;i++) { x=0.3*i; fgauss(x,a,&y,dyda,NA); e1=exp(-SQR((x-a[2])/a[3])); e2=exp(-SQR((x-a[5])/a[6])); f=a[1]*e1+a[4]*e2; df[1]=e1; df[4]=e2; df[2]=a[1]*e1*2.0*(x-a[2])/(a[3]*a[3]); df[5]=a[4]*e2*2.0*(x-a[5])/(a[6]*a[6]); df[3]=a[1]*e1*2.0*SQR(x-a[2])/(a[3]*a[3]*a[3]); df[6]=a[4]*e2*2.0*SQR(x-a[5])/(a[6]*a[6]*a[6]); printf("from FGAUSS\n"); printf("%8.4f %8.4f",x,y); for (j=1;j<=6;j++) printf("%8.4f",dyda[j]); printf("\nindependent calc.\n"); printf("%8.4f %8.4f",x,f); for (j=1;j<=6;j++) printf("%8.4f",df[j]); printf("\n\n"); } return 0; }
void potdata::readpot(const char *parmin_file,const char *potin_file,const double vol) { FILE *in; double x0,x1,dx,dr; int nx; double r0x,r1x,drx; int nrx; char metalx[80]; int ipotx,modex; double pnx; double vol0; double *vatab,*vbtab,*vctab,*vdtab,*vetab,*p1tab,*altab,*vpairtab = 0; double *r0rwstab,*evol0tab; double (*C)[4]; double *y,*dy; double x,dxdv; double unused; double zval,rws,ivol,r0rws,rcrws,rmrws;//,mass int i,j; int L; char line[1024]; input_vol = vol; /* Read potential data */ in = fopen(parmin_file,"r"); do { fgets(line,sizeof(line),in); } while(line[strspn(line," \t")] == '#'); /* Test to see whether this is a one-line or two-line version of parmin */ if(sscanf(line,"%lf %lf %lf %lf %d",&ddl[1],&ddl[2],&ddl[3],&ddl[4],&L) == 5) { /* One-line version, call getparmindata to figure out volume table spacing. */ int nvol; getparmindata(potin_file,&nvol,&vol0,&x0,&x1); dx = (x1-x0)/(nvol-1); if(0) { printf("getparmindata() ==> nvol = %d, vol0 = %.6f, x0= %.6f, x1 = %.6f, dx = %.6f\n", nvol,vol0,x0,x1,dx); } } else { /* Two-line version, reparse this line, and read second line */ sscanf(line,"%lf %lf %lf %lf",&x0,&x1,&dx,&vol0); fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf %lf %d",&ddl[1],&ddl[2],&ddl[3],&ddl[4],&L); } double rws_scale = pow(3.0*vol0/(16.0*atan(1.0)),1.0/3.0); fclose(in); lang = L+1; lmax = 2*L+1; double s = ddl[1],p = ddl[2],d = ddl[3],f = ddl[4]; double ss = s*s, pp = p*p, dd = d*d, ff = f*f; anorm3 = s*ss + 2.0*( p*pp + d*dd + f*ff); anorm4 = ss*ss + 2.0*(pp*pp + dd*dd + ff*ff); /* for(i = 1; i<=lmax; i++) { for(j = 1; j<=lmax; j++) del0.m[i][j] = 0.0; del0[i][i] = 1.0; } Matrix::sz = lmax; */ nx = (int) ((x1-x0)/dx + 1.1); /* Really: 1+round((x1-x0)/dx) */ vatab = new double[nx]; vbtab = new double[nx]; vctab = new double[nx]; vdtab = new double[nx]; vetab = new double[nx]; p1tab = new double[nx]; altab = new double[nx]; r0rwstab = new double[nx]; evol0tab = new double[nx]; in = fopen(potin_file,"r"); int *tag = new int[nx]; for(i = 0; i<nx; i++) tag[i] = 0; int ii; for(ii = 0; ii<nx; ii++) { do { fgets(line,sizeof(line),in); } while(line[strspn(line," \t")] == '#'); metalx[0] = 0; /* Read element type, mode, and pn parameter */ { int nf = sscanf(line,"%s %d %d %lf",metalx,&ipotx,&modex,&pnx); if(nf < 3) { printf("Error in %s() @ %s:%d: Inconsistency in potential input file (%s) " "at record %d:\n" " Expected at least three fields. Number of fields = %d\n", __func__,__FILE__,__LINE__,potin_file,ii, nf); exit(1); } if(modex <= 4) { pnx = 1.0; } else if(modex <= 6) { if(nf != 4) { printf("Error in %s() @ %s:%d: Inconsistency in potential input file (%s) " "at record %d:\n" " mode = %d, number of fields = %d\n", __func__,__FILE__,__LINE__,potin_file,ii, modex,nf); exit(1); } } else { printf("Error in %s() @ %s:%d: Inconsistency in potential input file (%s): " "at record %d\n" " Invalid mode. mode = %d\n", __func__,__FILE__,__LINE__,potin_file,ii, modex); } } if(ii == 0) { sscanf(line,"%s %d %d %lf",metal,&ipot,&mode,&pn); if(modex <= 4) pn = pnx; } else { /* Check that {metal,ipot,mode}x == {metal,ipot,mode} */ if(strcmp(metal,metalx) != 0 || ipotx != ipot || modex != mode || pnx != pn) { printf("Error in %s() @ %s:%d: Inconsistency in potential input file (%s) " "at record %d:\n" "metalx != metal (%s != %s) or\n" "ipotx != ipot (%d != %d) or\n" "modex != mode (%d != %d) or\n" "pnx != pn (%.3f != %.3f).\n", __func__,__FILE__,__LINE__,potin_file,ii, metalx,metal, ipotx,ipot, modex,mode, pnx,pn); exit(1); } } //printf("LINE: %s\n",line); //printf("metal = \'%s\' ipot = %d mode = %d\n",metalx,ipotx,modex); fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf %lf",&zval,&ivol,&rws,&mass); /*{ double xi = x0 + i/((double) (nx-1)) * (x1-x0); double volguess = vol0 * xi*xi*xi; if(fabs(volguess/ivol - 1.0) > 1e-3) printf("Wrong volume guess, i=%d volgues=%15.5e ivol=%15.5e\n", i,volguess,ivol); }*/ double ifrac = (pow(ivol/vol0,1.0/3.0) - x0)/((x1-x0)/(nx-1)); i = (int) (ifrac + 0.1); if(fabs(i - ifrac) > 0.01) { printf("Volume point not in table... ii=%d i=%d ifrac=%15.5e vol=%15.5e\n", ii,i,ifrac,ivol); printf("vol0 = %15.5e zval = %15.5e mass = %15.5e\n",vol0,zval,mass); exit(1); } else if(tag[i] == 1) { printf("Duplicate volume point in table.... ii=%d i=%d ifrac=%15.5e vol=%15.5e\n", ii,i,ifrac,ivol); exit(1); } else tag[i] = 1; fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf %lf",&r0rwstab[i],&altab[i],&rcrws,&rmrws); fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf",&p1tab[i],&unused,&evol0tab[i]); fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf %lf %lf", &vatab[i],&vbtab[i],&vctab[i],&vdtab[i],&vetab[i]); if(ipot == 1) { vatab[i] *= vdtab[i]; vctab[i] *= vctab[i]; vetab[i] *= vetab[i]; } fgets(line,sizeof(line),in); fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf",&r0x,&r1x,&drx); nrx = (int) ((r1x-r0x)/drx + 1.1); /* Really: 1+round((r1-r0)/dr) */ if(ii == 0) { r0 = r0x; r1 = r1x; dr = drx; nr = nrx; vpairtab = new double[nx*nr]; } else { /* Check that {r0,r1,dr,nr}x == {r0,r1,dr,nr} */ } for(j = 0; j<nr; j++) { double rj,ktan,dvdvol; fgets(line,sizeof(line),in); sscanf(line,"%lf %lf %lf %lf", &rj,&vpairtab[i*nr+j],&ktan,&dvdvol); { /* Add screening and fl() part to pair energy table */ double al = altab[i]; double p1 = p1tab[i]; int bscreen = (al > 0.0); double xi = x0 + i/((double) (nx-1)) * (x1-x0); double rws = rws_scale * xi; double r0rws = r0rwstab[i]; double r00 = r0rws*rws,rp = 1.8*rws; if(bscreen == 0) r0rws = 10.0; double alp = al,alm = al; if(mode == 2 || mode == 4 || mode == 6) alm = 125.0; al = alp; double r = r0 + j*(r1-r0)/(nr-1); double rrws = r/rws; //double rsqr = r*r; // double fl(double r,int mode,double rp,double p1,double al,double r0) double flr = fl(r,mode,rp,p1,al,r00,pn); double fl2 = flr*flr; double v2a = vatab[i]*fl2*fl2; double v2b = vbtab[i]*fl2; double fscr = 1.0; if(bscreen == 1 && rrws >= r0rws) { double arg = rrws/r0rwstab[i]; double arg1 = arg - 1.0; double arg12 = arg1*arg1; double f,dp; if(mode <= 2) { f = fgauss(arg,al); dp=2.*al*arg*arg1; } else { f = hgauss(arg,al); double arg13 = arg1*arg12; dp=2.0*al*al*arg*arg13/(1.+al*arg12); } fscr = f*f; } double vpair_tmp = vpairtab[i*nr+j]; vpairtab[i*nr+j] = vpairtab[i*nr+j]*fscr + v2a - v2b; if(0) if(fabs(vol-ivol) < 0.01) { static FILE *xfile = NULL; if(j == 0) { xfile = fopen("mgpt5-pot.dat","w"); fprintf(xfile,"%%%% vol = %15.5e ivol = %15.5e i = %d ii = %d\n", vol,ivol,i,ii); } fprintf(xfile,"%15.5e %15.5e %15.5e %15.5e %15.5e %20.10e\n", r,vpair_tmp,fscr,v2a,v2b,flr); if(j == nr-1) fclose(xfile); } } } } fclose(in); for(i = 0; i<nx; i++) if(tag[i] == 0) { printf("Volume point missing in table. i = %d\n",i); exit(1); } /* Make table */ x = pow(vol/vol0,1.0/3.0); dxdv = 1.0/(3.0*vol0*x*x); C = new double[(nr > nx) ? nr : nx][4]; makespline(nx,1,vatab,C); evalspline(nx-1,x0,x1,C,x,&va,&dva,&unused); dva *= dxdv; makespline(nx,1,vbtab,C); evalspline(nx-1,x0,x1,C,x,&vb,&dvb,&unused); dvb *= dxdv; makespline(nx,1,vctab,C); evalspline(nx-1,x0,x1,C,x,&vc,&dvc,&unused); dvc *= dxdv; makespline(nx,1,vdtab,C); evalspline(nx-1,x0,x1,C,x,&vd,&dvd,&unused); dvd *= dxdv; makespline(nx,1,vetab,C); evalspline(nx-1,x0,x1,C,x,&ve,&dve,&unused); dve *= dxdv; makespline(nx,1,p1tab,C); evalspline(nx-1,x0,x1,C,x,&p1,&dp1,&unused); dp1 *= dxdv; makespline(nx,1,altab,C); evalspline(nx-1,x0,x1,C,x,&al,&dal,&unused); dal *= dxdv; if(mode == 2 || mode == 4 || mode == 6) { al = 125.0; dal = 0.0; } { double dr0rws; makespline(nx,1,r0rwstab,C); evalspline(nx-1,x0,x1,C,x,&r0rws,&dr0rws,&unused); dr0rws *= dxdv; rws = rws_scale*x; r00 = r0rws * rws; dr00 = dr0rws*rws + r0rws*rws_scale*dxdv; rp = 1.8 * rws; drp = 1.8 * rws_scale*dxdv; } makespline(nx,1,evol0tab,C); evalspline(nx-1,x0,x1,C,x,&evol0,&devol0,&unused); devol0 *= dxdv; if(1) { printf("%% READPOT PARAMETERS:\n"); printf("%% ddl = %15.5e %15.5e %15.5e %15.5e\n",ddl[1],ddl[2],ddl[3],ddl[4]); printf("%% anorm3 = %15.5e anorm4 = %15.5e\n",anorm3,anorm4); printf("%% x = %15.5e pn = %15.5e\n",x,pn); printf("%% va = %15.5e dva = %15.5e\n",va,dva); printf("%% vb = %15.5e dvb = %15.5e\n",vb,dvb); printf("%% vc = %15.5e dvc = %15.5e\n",vc,dvc); printf("%% vd = %15.5e dvd = %15.5e\n",vd,dvd); printf("%% ve = %15.5e dve = %15.5e\n",ve,dve); printf("%% p1 = %15.5e dp1 = %15.5e\n",p1,dp1); printf("%% al = %15.5e dal = %15.5e\n",al,dal); printf("%% rp = %15.5e drp = %15.5e\n",rp,drp); printf("%% r00= %15.5e dr00= %15.5e\n",r00,dr00); printf("\n"); } y = new double[nr]; dy = new double[nr]; for(j = 0; j<nr; j++) { double d2y; makespline(nx,nr,&vpairtab[j],C); evalspline(nx-1,x0,x1,C,x,&y[j],&dy[j],&d2y); dy[j] *= dxdv; } vpair_spline = new double[nr-1][4]; dvpair_spline = new double[nr-1][4]; makespline(nr,1,y,vpair_spline); makespline(nr,1,dy,dvpair_spline); rcrit = rcrws * rws; rmax = rmrws * rws; delete[] dy; delete[] y; delete[] C; delete[] evol0tab; delete[] r0rwstab; delete[] altab; delete[] p1tab; delete[] vetab; delete[] vdtab; delete[] vctab; delete[] vbtab; delete[] vatab; }