Esempio n. 1
0
void DP(double *q1, double *q2, int *n1, int *N1, double *lam1, int *Disp, double *yy) {
	int i, j, k, l, n, M, N, Eidx, Fidx, Ftmp, Fmin, Num, *Path, *xy, x, y, cnt;
	const int scl = 5;
	double *q1L, *q2L, *D1, *D2, *tmp1, *tmp2, *E, Etmp, Emin, t, a, b, lam=0;

	n = *n1;
	N = *N1;
	lam = *lam1;

	M = scl*(N-1)+1;

	q1L = malloc(n*M*sizeof(double));
	q2L = malloc(n*M*sizeof(double));

	D1 = malloc(4*N*sizeof(double));
	tmp1 = D1 + N;
	D2 = D1 + 2*N;
	tmp2 = D2 + N;

	for (i = 0; i < n; ++i) {

		for (j = 0; j < N; ++j) {
			tmp1[j] = q1[n*j + i];
			tmp2[j] = q2[n*j + i];
		}

		spline(D1, tmp1, N);
		spline(D2, tmp2, N);

		// for each point in fine discretization
		for (j = 0; j < M; ++j) {
			lookupspline(&t, &k, j/(M-1.0), 1, N);
			q1L[n*j + i] = evalspline(t, D1+k, tmp1+k);
			q2L[n*j + i] = evalspline(t, D2+k, tmp2+k);
		}
	}

	free(D1);

	E = calloc(N*N, sizeof(double));
	Path = malloc(2*N*N*sizeof(int));

	for (i = 0; i < N; ++i) {
		E[N*i + 0] = 50000000000;
		E[N*0 + i] = 50000000000;
		Path[N*(N*0 + i) + 0] = -1;
		Path[N*(N*0 + 0) + i] = -1;
		Path[N*(N*1 + i) + 0] = -1;
		Path[N*(N*1 + 0) + i] = -1;
	}
	E[N*0 + 0] = 0;

	for (j = 1; j < N; ++j) {
		for (i = 1; i < N; ++i) {

			Emin = 100000;
			Eidx = 0;

			for (Num = 0; Num < NNBRS; ++Num) {
				k = i - Nbrs[Num][0];
				l = j - Nbrs[Num][1];

				if (k >= 0 && l >= 0) {
					Etmp = E[N*l + k] + CostFn2(q1L,q2L,k,l,i,j,n,scl,lam);
					if (Num == 0 || Etmp < Emin) {
						Emin = Etmp;
						Eidx = Num;
					}
				}
			}

			E[N*j + i] = Emin;
			Path[N*(N*0 + j) + i] = i - Nbrs[Eidx][0];
			Path[N*(N*1 + j) + i] = j - Nbrs[Eidx][1];
		}
	}

	free(E);
	free(q2L);

	xy = malloc(2*N*sizeof(int));
	xy[2*0 + 0] = N-1;
	xy[2*0 + 1] = N-1;

	cnt = 1;
	while (x = xy[2*(cnt-1) + 0], x > 0) {
		y = xy[2*(cnt-1) + 1];

		xy[2*cnt + 1] = Path[N*(N*0 + x) + y];
		xy[2*cnt + 0] = Path[N*(N*1 + x) + y];
		++cnt;
	}

	free(Path);

	qsort(xy, cnt, 2*sizeof(int), xycompare);

	for (i = 0; i < N; ++i) {

		Fmin = 100000;
		Fidx = 0;

		for (j = 0; j < cnt; ++j) {
			x = xy[2*j + 0];
			Ftmp = fabs(i - x);
			if (j == 0 || Ftmp < Fmin) {
				Fmin = Ftmp;
				Fidx = j;
			}
		}

		x = xy[2*Fidx + 0];
		y = xy[2*Fidx + 1];

		if (x == i) {
			yy[i] = y;
		}
		else {
			if (x > i) {
				a = x - i;
				b = i - xy[2*(Fidx-1) + 0];
				yy[i] = (a*xy[2*(Fidx-1) + 1] + b*y)/(a+b);
			}
			else {
				a = i - x;
				b = xy[2*(Fidx+1) + 0] - i;
				yy[i] = (a*xy[2*(Fidx+1) + 1] + b*y)/(a+b);
			}
		}

		yy[i] = (yy[i]-yy[0])/(N-1);
	}

	free(xy);
}
Esempio n. 2
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;
}