예제 #1
0
파일: saft.cpp 프로젝트: Chris-Haglund/deft
void test_energy(const char *name, Functional f, double kT,
                 double true_energy, double fraccuracy = 1e-15) {
  printf("\n************");
  for (unsigned i=0;i<strlen(name);i++) printf("*");
  printf("\n* Testing %s *\n", name);
  for (unsigned i=0;i<strlen(name);i++) printf("*");
  printf("************\n\n");

  Lattice lat(Cartesian(0,.5,.5), Cartesian(.5,0,.5), Cartesian(.5,.5,0));
  int resolution = 20;
  GridDescription gd(lat, resolution, resolution, resolution);
  Grid density(gd);
  density = 1e-3*(-500*r2(gd)).cwise().exp()
    + 1e-7*VectorXd::Ones(gd.NxNyNz);

  retval += f.run_finite_difference_test(name, kT, density);

  double e = f.integral(kT, density);
  printf("Energy = %.16g\n", e);
  printf("Fractional error = %g\n", (e - true_energy)/fabs(true_energy));
  if (e < true_energy) {
    printf("FAIL: the energy is too low! (it is %.16g)\n", e);
    retval++;
  }
  if (!(fabs((e - true_energy)/true_energy) < fraccuracy)) {
    printf("FAIL: Error in the energy is too big!\n");
    retval++;
  }
}
예제 #2
0
int check_functional_value(const char *name,
                            const Functional &f, Vector v,
                            double energy,
                            double fraccuracy = 1e-15) {
  int errors = 0;
  printf("\n************");
  for (unsigned i=0;i<strlen(name);i++) printf("*");
  printf("\n* Testing %s *\n", name);
  for (unsigned i=0;i<strlen(name);i++) printf("*");
  printf("************\n\n");

  double fv = f.energy(v);
  print_double("Energy of Vector:  ", fv);
  printf("\n");
  f.printme("  ");

  if (fabs(fv/energy - 1) > fraccuracy) {
    printf("fv = %g\n", fv);
    printf("expected = %g\n", energy);
    printf("FAIL: Error in f(n) is %g\n", fv/energy - 1);
    errors++;
  }
  return errors;
}
예제 #3
0
void compare_functionals(const Functional &f1, const Functional &f2,
                         double kT, const Grid &n, double fraccuracy = 1e-15,
                         double x = 0.001, double fraccuracydoub = 1e-15) {
  printf("\n************");
  for (unsigned i=0;i<f1.get_name().size();i++) printf("*");
  printf("\n* Testing %s *\n", f1.get_name().c_str());
  for (unsigned i=0;i<f1.get_name().size();i++) printf("*");
  printf("************\n\n");

  printf("First energy:\n");
  double f1n = f1.integral(kT, n);
  print_double("first energy is:               ", f1n);
  printf("\n");
  f1.print_summary("", f1n, f1.get_name().c_str());
  printf("Second energy:\n");
  double f2n = f2.integral(kT, n);
  print_double("second energy is:              ", f2n);
  printf("\n");
  f2.print_summary("", f2n, f2.get_name().c_str());
  if (fabs(f1n/f2n - 1) > fraccuracy) {
    printf("E1 = %g\n", f1n);
    printf("E2 = %g\n", f2n);
    printf("FAIL: Error in f(n) is %g\n", f1n/f2n - 1);
    errors++;
  }
  Grid gr1(gd), gr2(gd);
  gr1.setZero();
  gr2.setZero();
  f1.integralgrad(kT, n, &gr1);
  f2.integralgrad(kT, n, &gr2);
  double err = (gr1-gr2).cwise().abs().maxCoeff();
  double mag = gr1.cwise().abs().maxCoeff();
  if (err/mag > fraccuracy) {
    printf("FAIL: Error in grad %s is %g as a fraction of %g\n", f1.get_name().c_str(), err/mag, mag);
    errors++;
  }
  errors += f1.run_finite_difference_test(f1.get_name().c_str(), kT, n);

  double f1x = f1(kT, x);
  double f2x = f2(kT, x);
  if (1 - fabs(f1x/f2x) > fraccuracydoub) {
    printf("FAIL: Error in double %s is %g as a fraction of %g\n", f1.get_name().c_str(),
           1 - fabs(f1x/f2x), f2x);
    errors++;
  }
  
  double f1p = f1.derive(kT, x);
  double f2p = f2.derive(kT, x);
  if (1 - fabs(f1p/f2p) > fraccuracydoub) {
    printf("FAIL: Error in derive double %s is %g as a fraction of %g\n", f1.get_name().c_str(),
           1 - fabs(f1p/f2p), f2p);
    errors++;
  }
  
  //errors += f2.run_finite_difference_test("other version", n);
}
예제 #4
0
double surface_tension(Minimizer min, Functional f0, LiquidProperties prop,
                       bool verbose, const char *plotname) {
  int numptspersize = 100;
  int size = 64;
  const int gas_size = 10;
  Lattice lat(Cartesian(1,0,0), Cartesian(0,1,0), Cartesian(0,0,size*prop.lengthscale));
  GridDescription gd(lat, 1, 1, numptspersize*size);
  Grid potential(gd);

  // Set the density to range from vapor to liquid
  const double Veff_liquid = -prop.kT*log(prop.liquid_density);
  const double Veff_gas = -prop.kT*log(prop.vapor_density);
  for (int i=0; i<gd.NxNyNz*gas_size/size; i++) potential[i] = Veff_gas;
  for (int i=gd.NxNyNz*gas_size/size; i<gd.NxNyNz; i++) potential[i] = Veff_liquid;

  // Enable the following line for debugging...
  //f0.run_finite_difference_test("f0", prop.kT, potential);
  min.minimize(f0, gd, &potential);
  while (min.improve_energy(verbose))
    if (verbose) {
      printf("Working on liberated interface...\n");
      fflush(stdout);
    }
  const double Einterface = f0.integral(prop.kT, potential);
  double Ninterface = 0;
  Grid interface_density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential));
  for (int i=0;i<gd.NxNyNz;i++) Ninterface += interface_density[i]*gd.dvolume;
  if (verbose) printf("Got interface energy of %g.\n", Einterface);
  
  for (int i=0; i<gd.NxNyNz; i++) potential[i] = Veff_gas;
  min.minimize(f0, gd, &potential);
  while (min.improve_energy(verbose))
    if (verbose) {
      printf("Working on gas...\n");
      fflush(stdout);
    }
  const double Egas = f0.integral(prop.kT, potential);
  double Ngas = 0;
  {
    Grid density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential));
    for (int i=0;i<gd.NxNyNz;i++) Ngas += density[i]*gd.dvolume;
  }
  
  for (int i=0; i<gd.NxNyNz; i++) potential[i] = Veff_liquid;
  if (verbose) {
    printf("\n\n\nWorking on liquid...\n");
    fflush(stdout);
  }
  min.minimize(f0, gd, &potential);
  while (min.improve_energy(verbose))
    if (verbose) {
      printf("Working on liquid...\n");
      fflush(stdout);
    }
  const double Eliquid = f0.integral(prop.kT, potential);
  double Nliquid = 0;
  {
    Grid density(gd, EffectivePotentialToDensity()(prop.kT, gd, potential));
    for (int i=0;i<gd.NxNyNz;i++) Nliquid += density[i]*gd.dvolume;
  }
  
  const double X = Ninterface/Nliquid; // Fraction of volume effectively filled with liquid.
  const double surface_tension = (Einterface - Eliquid*X - Egas*(1-X))/2;
  if (verbose) {
    printf("\n\n");
    printf("interface energy is %.15g\n", Einterface);
    printf("gas energy is %.15g\n", Egas);
    printf("liquid energy is %.15g\n", Eliquid);
    printf("Ninterface/liquid/gas = %g/%g/%g\n", Ninterface, Nliquid, Ngas);
    printf("X is %g\n", X);
    printf("surface tension is %.10g\n", surface_tension);
  }
  if (plotname)
    interface_density.Dump1D(plotname, Cartesian(0,0,0),
                             Cartesian(0,0,size*prop.lengthscale));
  return surface_tension;
}
예제 #5
0
파일: sphere.cpp 프로젝트: droundy/deft
int main(int argc, char *argv[]) {
  clock_t start_time = clock();
  if (argc > 1) {
    if (sscanf(argv[1], "%lg", &diameter) != 1) {
      printf("Got bad argument: %s\n", argv[1]);
      return 1;
    }
    diameter *= nm;
    using_default_diameter = false;
  }
  printf("Diameter is %g bohr = %g nm\n", diameter, diameter/nm);
  const double padding = 1*nm;
  xmax = ymax = zmax = diameter + 2*padding;

  char *datname = (char *)malloc(1024);
  sprintf(datname, "papers/hughes-saft/figs/sphere-%04.2fnm-energy.dat", diameter/nm);
  
  Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
						hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
						hughes_water_prop.epsilon_dispersion,
						hughes_water_prop.lambda_dispersion,
						hughes_water_prop.length_scaling, 0));
  double n_1atm = pressure_to_density(f, hughes_water_prop.kT, atmospheric_pressure,
				      0.001, 0.01);

  double mu_satp = find_chemical_potential(f, hughes_water_prop.kT, n_1atm);

  f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
				     hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
				     hughes_water_prop.epsilon_dispersion,
				     hughes_water_prop.lambda_dispersion,
				     hughes_water_prop.length_scaling, mu_satp));
  Functional S = OfEffectivePotential(EntropySaftFluid2(new_water_prop.lengthscale,
                                                        new_water_prop.epsilonAB,
                                                        new_water_prop.kappaAB,
                                                        new_water_prop.epsilon_dispersion,
                                                        new_water_prop.lambda_dispersion,
                                                        new_water_prop.length_scaling));
  
  const double EperVolume = f(hughes_water_prop.kT, -hughes_water_prop.kT*log(n_1atm));
  const double EperNumber = EperVolume/n_1atm;
  const double SperNumber = S(hughes_water_prop.kT, -hughes_water_prop.kT*log(n_1atm))/n_1atm;
  const double EperCell = EperVolume*(zmax*ymax*xmax - (M_PI/6)*diameter*diameter*diameter);

  //for (diameter=0*nm; diameter<3.0*nm; diameter+= .1*nm) {
    Lattice lat(Cartesian(xmax,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax));
    GridDescription gd(lat, 0.2);
    
    Grid potential(gd);
    Grid constraint(gd);
    constraint.Set(notinwall);
    
    f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
				       hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
				       hughes_water_prop.epsilon_dispersion,
				       hughes_water_prop.lambda_dispersion,
				       hughes_water_prop.length_scaling, mu_satp));
    f = constrain(constraint, f);
    //constraint.epsNativeSlice("papers/hughes-saft/figs/sphere-constraint.eps",
    // 			      Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
    // 			      Cartesian(0,ymax/2,zmax/2));
    //printf("Constraint has become a graph!\n");
   
    potential = hughes_water_prop.liquid_density*constraint
      + 100*hughes_water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz);
    //potential = hughes_water_prop.liquid_density*VectorXd::Ones(gd.NxNyNz);
    potential = -hughes_water_prop.kT*potential.cwise().log();
    
    double energy;
    {
      const double surface_tension = 5e-5; // crude guess from memory...
      const double surfprecision = 1e-4*M_PI*diameter*diameter*surface_tension; // four digits precision
      const double bulkprecision = 1e-12*fabs(EperCell); // but there's a limit on our precision for small spheres
      const double precision = bulkprecision + surfprecision;
      Minimizer min = Precision(precision,
                                PreconditionedConjugateGradient(f, gd, hughes_water_prop.kT, 
                                                                &potential,
                                                                QuadraticLineMinimizer));
      
      printf("\nDiameter of sphere = %g bohr (%g nm)\n", diameter, diameter/nm);
      
      const int numiters = 200;
      for (int i=0;i<numiters && min.improve_energy(true);i++) {
        //fflush(stdout);
        //Grid density(gd, EffectivePotentialToDensity()(hughes_water_prop.kT, gd, potential));
        
        //density.epsNativeSlice("papers/hughes-saft/figs/sphere.eps", 
        //			     Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
        //			     Cartesian(0,ymax/2,zmax/2));
        
        //sleep(3);

        double peak = peak_memory()/1024.0/1024;
        double current = current_memory()/1024.0/1024;
        printf("Peak memory use is %g M (current is %g M)\n", peak, current);
      }
      
      double peak = peak_memory()/1024.0/1024;
      double current = current_memory()/1024.0/1024;
      printf("Peak memory use is %g M (current is %g M)\n", peak, current);
      
      energy = min.energy();
      printf("Total energy is %.15g\n", energy);
      // Here we free the minimizer with its associated data structures.
    }

    {
      double peak = peak_memory()/1024.0/1024;
      double current = current_memory()/1024.0/1024;
      printf("Peak memory use is %g M (current is %g M)\n", peak, current);
    }

    double entropy = S.integral(hughes_water_prop.kT, potential);
    Grid density(gd, EffectivePotentialToDensity()(hughes_water_prop.kT, gd, potential));
    printf("Number of water molecules is %g\n", density.integrate());
    printf("The bulk energy per cell should be %g\n", EperCell);
    printf("The bulk energy based on number should be %g\n", EperNumber*density.integrate());
    printf("The bulk entropy is %g/N\n", SperNumber);
    Functional otherS = EntropySaftFluid2(hughes_water_prop.lengthscale,
                                          hughes_water_prop.epsilonAB,
                                          hughes_water_prop.kappaAB,
                                          hughes_water_prop.epsilon_dispersion,
                                          hughes_water_prop.lambda_dispersion,
                                          hughes_water_prop.length_scaling);
    printf("The bulk entropy (haskell) = %g/N\n", otherS(hughes_water_prop.kT, n_1atm)/n_1atm);
    //printf("My entropy is %g when I would expect %g\n", entropy, entropy - SperNumber*density.integrate());
    double hentropy = otherS.integral(hughes_water_prop.kT, density);
    otherS.print_summary("   ", hentropy, "total entropy");
    printf("My haskell entropy is %g, when I would expect = %g, difference is %g\n", hentropy,
           otherS(hughes_water_prop.kT, n_1atm)*density.integrate()/n_1atm,
           hentropy - otherS(hughes_water_prop.kT, n_1atm)*density.integrate()/n_1atm);

    FILE *o = fopen(datname, "w");
    //fprintf(o, "%g\t%.15g\n", diameter/nm, energy - EperCell);
    fprintf(o, "%g\t%.15g\t%.15g\t%.15g\t%.15g\n", diameter/nm, energy - EperNumber*density.integrate(), energy - EperCell,
            hughes_water_prop.kT*(entropy - SperNumber*density.integrate()),
            hughes_water_prop.kT*(hentropy - otherS(hughes_water_prop.kT, n_1atm)*density.integrate()/n_1atm));
    fclose(o);

    char *plotname = (char *)malloc(1024);

    sprintf(plotname, "papers/hughes-saft/figs/sphere-%04.2f.dat", diameter/nm);
    plot_grids_y_direction(plotname, density);

    free(plotname);

    //density.epsNativeSlice("papers/hughes-saft/figs/sphere.eps",
		//	   Cartesian(0,ymax,0), Cartesian(0,0,zmax),
		//	   Cartesian(0,ymax/2,zmax/2));
    
    double peak = peak_memory()/1024.0/1024;
    printf("Peak memory use is %g M\n", peak);
  
    double oldN = density.integrate();
    density = n_1atm*VectorXd::Ones(gd.NxNyNz);;
    double hentropyb = otherS.integral(hughes_water_prop.kT, density);
    printf("bulklike thingy has %g molecules\n", density.integrate());
    otherS.print_summary("   ", hentropyb, "bulk-like entropy");
    printf("entropy difference is %g\n", hentropy - hentropyb*oldN/density.integrate());
  // }
  clock_t end_time = clock();
  double seconds = (end_time - start_time)/double(CLOCKS_PER_SEC);
  double hours = seconds/60/60;
  printf("Entire calculation took %.0f hours %.0f minutes\n", hours, 60*(hours-floor(hours)));
}
예제 #6
0
파일: eos.cpp 프로젝트: exianshine/deft
int main(int, char **argv) {
  Functional n = EffectivePotentialToDensity();
  double Veff = -hughes_water_prop.kT*log(hughes_water_prop.liquid_density);

  const double nmin = 1e-11, nmax = 0.007;

  {
    double ngas = 2e-5;
    double mu = find_chemical_potential(IdealGasOfVeff(), hughes_water_prop.kT, ngas);
    test_eos("ideal gas", IdealGasOfVeff() + ChemicalPotential(mu)(n), ngas, ngas*hughes_water_prop.kT);
  }

  test_eos("quadratic", 0.5*sqr(n) - n, 1.0, 0.5, 2e-6);
  test_pressure("quadratic(2)", 0.5*sqr(n) - n, 2, 2);
  test_pressure("quadratic(3)", 0.5*sqr(n) - n, 3, 4.5);

  {
    //FILE *o = fopen("ideal-gas.dat", "w");
    //equation_of_state(o, IdealGasOfVeff(), hughes_water_prop.kT, nmin, nmax);
    //fclose(o);
  }

  {
    FILE *o = fopen("dispersion.dat", "w");
    //equation_of_state(o, DispersionSAFT(hughes_water_prop.lengthscale, hughes_water_prop.kT,
    //                                    hughes_water_prop.epsilon_dispersion,
    //                                    hughes_water_prop.lambda_dispersion)(n),
    //                  hughes_water_prop.kT, nmin, nmax);
    fclose(o);
    printf("Got dispersion!\n");

    Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
                                                  hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                                                  hughes_water_prop.epsilon_dispersion,
                                                  hughes_water_prop.lambda_dispersion,
                                                  hughes_water_prop.length_scaling, 0));


    const double n_1atm = pressure_to_density(f, hughes_water_prop.kT, atmospheric_pressure,
					      0.001, 0.01);
    printf("density at 1 atmosphere is %g\n", n_1atm);
    printf("error in density at 1 atmosphere is %g\n", n_1atm/hughes_water_prop.liquid_density - 1);
    if (fabs(n_1atm/hughes_water_prop.liquid_density - 1) > 0.01) {
      printf("FAIL! error in water density is too big! %g\n",
             n_1atm/hughes_water_prop.liquid_density - 1);
      retval++;
    }

    test_pressure("saft at 1 atm", f, n_1atm, atmospheric_pressure);

    {
      printf("working onfoo\n");
      double nv = coexisting_vapor_density(f, hughes_water_prop.kT, hughes_water_prop.liquid_density);
      printf("predicted vapor density: %g\n", nv);
      printf("actual vapor density:    %g\n", hughes_water_prop.vapor_density);
    }

    if (0) {
      o = fopen("saft-fluid.dat", "w");
      double mu = f.derive(hughes_water_prop.kT, Veff)*hughes_water_prop.kT/hughes_water_prop.liquid_density; // convert from derivative w.r.t. V
      equation_of_state(o, f + ChemicalPotential(mu)(n), hughes_water_prop.kT, nmin, nmax);
      fclose(o);
    }

    {
      double nl, nv, mu;
      saturated_liquid_vapor(f, hughes_water_prop.kT, 1e-14, 0.0017, 0.0055, &nl, &nv, &mu, 1e-5);
      printf("saturated water density is %g\n", nl);
      printf("1 atm water density ? is %g\n", hughes_water_prop.liquid_density);
      if (fabs(nl/hughes_water_prop.liquid_density - 1) > 0.1) {
        printf("FAIL: error in saturated water density is too big! %g\n",
               nl/hughes_water_prop.liquid_density - 1);
        retval++;
      }

      printf("predicted saturated vapor density: %g\n", nv);
      printf("actual vapor density:    %g\n", hughes_water_prop.vapor_density);
      //double mu = f.derive(-hughes_water_prop.kT*log(nl))*hughes_water_prop.kT/nl; // convert from derivative w.r.t. V
      //o = fopen("saft-fluid-saturated.dat", "w");
      //equation_of_state(o, f + ChemicalPotential(mu)(n), hughes_water_prop.kT, nmin, 1.1*nl);
      //fclose(o);

      double pv = pressure(f, hughes_water_prop.kT, nv);
      printf("vapor pressure is %g\n", pv);
      if (fabs(pv/hughes_water_prop.kT/nv - 1) > 1e-3) {
        printf("FAIL: error in vapor pressure, steam isn't ideal gas? %g\n",
               pv/hughes_water_prop.kT/nv - 1);
        retval++;
      }
    }

    {
      o = fopen("room-temperature.dat", "w");
      Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
                                                        hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                                                        hughes_water_prop.epsilon_dispersion,
                                                        hughes_water_prop.lambda_dispersion,
                                                        hughes_water_prop.length_scaling, 0));
      double mufoo = find_chemical_potential(f, hughes_water_prop.kT,
                                             hughes_water_prop.liquid_density);
      f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
                                             hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                                             hughes_water_prop.epsilon_dispersion,
                                             hughes_water_prop.lambda_dispersion,
                                             hughes_water_prop.length_scaling, mufoo));
      double nl, nv, mu;
      saturated_liquid_vapor(f, hughes_water_prop.kT, 1e-14, 0.0017, 0.0055, &nl, &nv, &mu, 1e-5);
      for (double dens=0.1*nv; dens<=1.2*nl; dens *= 1.01) {
        double V = -hughes_water_prop.kT*log(dens);
        double Vl = -hughes_water_prop.kT*log(nl);
        fprintf(o, "%g\t%g\t%g\n",
                dens, f(hughes_water_prop.kT, V), f(hughes_water_prop.kT, Vl) - (dens-nl)*mu);
      }
      fclose(o);
      printf("Finished plotting room-temperature.dat...\n");
    }
  }

  {
    FILE *o = fopen("hard-sphere-fluid.dat", "w");
    Functional f = HardSpheresWBnotensor(hughes_water_prop.lengthscale)(n) + IdealGasOfVeff();
    double mu = f.derive(hughes_water_prop.kT, Veff)*hughes_water_prop.kT/hughes_water_prop.liquid_density; // convert from derivative w.r.t. V
    equation_of_state(o, f + ChemicalPotential(mu)(n), hughes_water_prop.kT, nmin, nmax);
    fclose(o);
  }

  if (retval == 0) {
    printf("\n%s passes!\n", argv[0]);
  } else {
    printf("\n%s fails %d tests!\n", argv[0], retval);
    return retval;
  }
}
예제 #7
0
int main(int argc, char *argv[]) {
  clock_t start_time = clock();
  if (argc == 3) {
    if (sscanf(argv[2], "%lg", &temperature) != 1) {
      printf("Got bad argument: %s\n", argv[2]);
      return 1;
    }
    temperature *= kB;
    bool good_element = false;
    for (int i=0; i<numelements; i++) {
      if (strcmp(elements[i], argv[1]) == 0) {
        sigma = sigmas[i];
        epsilon = epsilons[i];
        good_element = true;
      }
    }
    if (!good_element) {
      printf("Bad element: %s\n", argv[1]);
      return 1;
    }
  } else {
    printf("Need element and temperature.\n");
    return 1;
  }
  char *datname = (char *)malloc(1024);
  sprintf(datname, "papers/water-saft/figs/hughes-lj-%s-%gK-energy.dat", argv[1], temperature/kB);
  
  Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
                                                hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                                                hughes_water_prop.epsilon_dispersion,
                                                hughes_water_prop.lambda_dispersion,
                                                hughes_water_prop.length_scaling, 0));
  double n_1atm = pressure_to_density(f, temperature, lj_pressure,
                                      0.001, 0.01);

  double mu = find_chemical_potential(f, temperature, n_1atm);

  f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
                                     hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                                     hughes_water_prop.epsilon_dispersion,
                                     hughes_water_prop.lambda_dispersion,
                                     hughes_water_prop.length_scaling, mu));
  
  Functional S = OfEffectivePotential(EntropySaftFluid2(hughes_water_prop.lengthscale,
                                                        hughes_water_prop.epsilonAB,
                                                        hughes_water_prop.kappaAB,
                                                        hughes_water_prop.epsilon_dispersion,
                                                        hughes_water_prop.lambda_dispersion,
                                                        hughes_water_prop.length_scaling));
  
  const double EperVolume = f(temperature, -temperature*log(n_1atm));
  const double EperNumber = EperVolume/n_1atm;
  const double SperNumber = S(temperature, -temperature*log(n_1atm))/n_1atm;
  const double EperCell = EperVolume*(zmax*ymax*xmax - (4*M_PI/3)*sigma*sigma*sigma);
  
  Lattice lat(Cartesian(xmax,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax));
  GridDescription gd(lat, 0.20);
    
  Grid potential(gd);
  Grid externalpotential(gd);
  externalpotential.Set(externalpotentialfunction);
    
  f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale,
                                     hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                                     hughes_water_prop.epsilon_dispersion,
                                     hughes_water_prop.lambda_dispersion,
                                     hughes_water_prop.length_scaling, mu) + ExternalPotential(externalpotential));

  Functional X = WaterX(hughes_water_prop.lengthscale,
                        hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                        hughes_water_prop.epsilon_dispersion,
                        hughes_water_prop.lambda_dispersion,
                        hughes_water_prop.length_scaling, mu);
  
  Functional HB = HughesHB(hughes_water_prop.lengthscale,
                           hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB,
                           hughes_water_prop.epsilon_dispersion,
                           hughes_water_prop.lambda_dispersion,
                           hughes_water_prop.length_scaling, mu);

  externalpotential.epsNativeSlice("papers/water-saft/figs/hughes-lj-potential.eps",
                                   Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
                                   Cartesian(0,ymax/2,zmax/2));
  printf("Done outputting hughes-lj-potential.eps\n");

  potential = 0*externalpotential - temperature*log(n_1atm)*VectorXd::Ones(gd.NxNyNz); // ???
    
  double energy;
  {
    const double surface_tension = 5e-5; // crude guess from memory...
    const double surfprecision = 1e-4*M_PI*sigma*sigma*surface_tension; // four digits precision
    const double bulkprecision = 1e-12*fabs(EperCell); // but there's a limit on our precision
    const double precision = (bulkprecision + surfprecision)*1e-6;
    Minimizer min = Precision(precision,
                              PreconditionedConjugateGradient(f, gd, temperature, 
                                                              &potential,
                                                              QuadraticLineMinimizer));
      
      
    const int numiters = 200;
    for (int i=0;i<numiters && min.improve_energy(true);i++) {
      double peak = peak_memory()/1024.0/1024;
      double current = current_memory()/1024.0/1024;
      printf("Peak memory use is %g M (current is %g M)\n", peak, current);
      fflush(stdout);
      {
        char* name = new char[1000];
        sprintf(name, "papers/water-saft/figs/hughes-lj-%s-%gK-density-%d.eps", argv[1], temperature/kB, i);
        Grid density(gd, EffectivePotentialToDensity()(temperature, gd, potential));
        density.epsNativeSlice(name,
                               Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
                               Cartesian(0,ymax/2,zmax/2));
      }
      Grid gradient(gd, potential);
      gradient *= 0;
      f.integralgrad(temperature, potential, &gradient); 
      char* gradname = new char[1000];
      sprintf(gradname, "papers/water-saft/figs/hughes-lj-%s-%gK-gradient-%d.eps", argv[1], temperature/kB, i);
      gradient.epsNativeSlice(gradname,
                              Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
                              Cartesian(0,ymax/2,zmax/2));

      Grid density(gd, EffectivePotentialToDensity()(temperature, gd, potential));
      char *plotname = (char *)malloc(1024);
      sprintf(plotname, "papers/water-saft/figs/hughes-lj-%s-%gK-%d.dat", argv[1], temperature/kB, i);
      plot_grids_y_direction(plotname, density, gradient);

      // Grid gradient(gd, potential);
      // gradient *= 0;
      // f.integralgrad(temperature, potential, &gradient);
      // sprintf(name, "papers/water-saft/figs/lj-%s-%d-gradient-big.eps", argv[1], i);
      // gradient.epsNativeSlice("papers/water-saft/figs/lj-gradient-big.eps",
      //                         Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
      //                         Cartesian(0,ymax/2,zmax/2));
      // sprintf(name, "papers/water-saft/figs/lj-%s-%d-big.dat", argv[1], i);
      // plot_grids_y_direction(name, density, gradient);
    }
    double peak = peak_memory()/1024.0/1024;
    double current = current_memory()/1024.0/1024;
    printf("Peak memory use is %g M (current is %g M)\n", peak, current);
    
    energy = min.energy();
    printf("Total energy is %.15g\n", energy);
    // Here we free the minimizer with its associated data structures.
  }

  {
    double peak = peak_memory()/1024.0/1024;
    double current = current_memory()/1024.0/1024;
    printf("Peak memory use is %g M (current is %g M)\n", peak, current);
  }

  Grid gradient(gd, potential);
  gradient *= 0;
  f.integralgrad(temperature, potential, &gradient);
  gradient.epsNativeSlice("papers/water-saft/figs/hughes-lj-gradient.eps",
                          Cartesian(0,ymax,0), Cartesian(0,0,zmax), 
                          Cartesian(0,ymax/2,zmax/2));

  double entropy = S.integral(temperature, potential);
  Grid density(gd, EffectivePotentialToDensity()(temperature, gd, potential));
  // Grid zeroed_out_density(gd, density.cwise()*constraint); // this is zero inside the sphere!
  Grid X_values(gd, X(temperature, gd, density));
  //Grid H_bonds_grid(gd, zeroed_out_density.cwise()*(4*(VectorXd::Ones(gd.NxNyNz)-X_values)));
  //const double broken_H_bonds = (HB(temperature, n_1atm)/n_1atm)*zeroed_out_density.integrate() - H_bonds_grid.integrate();
  //printf("Number of water molecules is %g\n", density.integrate());
  printf("The bulk energy per cell should be %g\n", EperCell);
  printf("The bulk energy based on number should be %g\n", EperNumber*density.integrate());
  printf("The bulk entropy is %g/N\n", SperNumber);
  Functional otherS = EntropySaftFluid2(hughes_water_prop.lengthscale,
                                        hughes_water_prop.epsilonAB,
                                        hughes_water_prop.kappaAB,
                                        hughes_water_prop.epsilon_dispersion,
                                        hughes_water_prop.lambda_dispersion,
                                        hughes_water_prop.length_scaling);
  printf("The bulk entropy (haskell) = %g/N\n", otherS(temperature, n_1atm)/n_1atm);
  //printf("My entropy is %g when I would expect %g\n", entropy, entropy - SperNumber*density.integrate());
  double hentropy = otherS.integral(temperature, density);
  otherS.print_summary("   ", hentropy, "total entropy");
  printf("My haskell entropy is %g, when I would expect = %g, difference is %g\n", hentropy,
         otherS(temperature, n_1atm)*density.integrate()/n_1atm,
         hentropy - otherS(temperature, n_1atm)*density.integrate()/n_1atm);

  FILE *o = fopen(datname, "w");
  fprintf(o, "%g\t%.15g\t%.15g\t%.15g\n", temperature/kB, energy - EperNumber*density.integrate(),
          temperature*(entropy - SperNumber*density.integrate()),
          temperature*(hentropy - otherS(temperature, n_1atm)*density.integrate()/n_1atm));
  fclose(o);

  char *plotname = (char *)malloc(1024);
  sprintf(plotname, "papers/water-saft/figs/hughes-lj-%s-%gK.dat", argv[1], temperature/kB);
  //plot_grids_y_direction(plotname, density, X_values);
  plot_grids_y_direction(plotname, density, gradient);

  free(plotname);

  double peak = peak_memory()/1024.0/1024;
  printf("Peak memory use is %g M\n", peak);

  double oldN = density.integrate();
  density = n_1atm*VectorXd::Ones(gd.NxNyNz);;
  double hentropyb = otherS.integral(temperature, density);
  printf("bulklike thingy has %g molecules\n", density.integrate());
  otherS.print_summary("   ", hentropyb, "bulk-like entropy");
  printf("entropy difference is %g\n", hentropy - hentropyb*oldN/density.integrate());

  clock_t end_time = clock();
  double seconds = (end_time - start_time)/double(CLOCKS_PER_SEC);
  double hours = seconds/60/60;
  printf("Entire calculation took %.0f hours %.0f minutes\n", hours, 60*(hours-floor(hours)));
}
예제 #8
0
파일: memory.cpp 프로젝트: exianshine/deft
void check_a_functional(const char *name, Functional f, const Grid &x) {
  const double kT = hughes_water_prop.kT; // room temperature in Hartree

  printf("\n***********");
  for (unsigned i=0;i<strlen(name) + 4;i++) printf("*");
  printf("\n* Working on %s *\n", name);
  for (unsigned i=0;i<strlen(name) + 4;i++) printf("*");
  printf("***********\n\n");
  fflush(stdout);

  double memE, cpuE, memG, cpuG, memP, cpuP, memPonly, cpuPonly;

  FILE *out;
  {
    char *fname = new char[1024];
    snprintf(fname, 1024, "tests/bench/good/%s.%s", name, hn);
    FILE *good = fopen(fname, "r");
    bool nocpu = false;
    if (majorfaults) {
      printf("Refusing to test cpu times, since there is swapping going on! (%g M)\n", majorfaults);
      nocpu = true;
    }
    if (!good || fscanf(good, " mem cpu %lg %lg %lg %lg %lg %lg %lg %lg",
                        &memE, &cpuE,
                        &memG, &cpuG,
                        &memP, &cpuP,
                        &memPonly, &cpuPonly) != 8) {
      printf("Unable to open file %s, will not check cpu times!\n", fname);
      nocpu = true;
    } else {
      fclose(good);
    }
    snprintf(fname, 1024, "tests/bench/good/%s.kipu", name);
    good = fopen(fname, "r");
    if (!good) {
      printf("Unable to open file %s, so I have to fail!\n", fname);
      exit(1);
    }
    if (fscanf(good, " mem cpu %lg %*g %lg %*g %lg %*g %lg %*g",
               &memE, &memG, &memP, &memPonly) != 4) {
      printf("Unable to read file %s\n", fname);
      exit(1);
    }
    fclose(good);
    if (nocpu) {
      cpuE = cpuG = cpuP = cpuPonly = 0;
    }
    snprintf(fname, 1024, "tests/bench/%s.%s", name, hn);
    out = fopen(fname, "w");
    if (!out) {
      printf("Unable to create file %s\n", fname);
      exit(1);
    }
    fprintf(out, "mem\tcpu\n");
    delete[] fname;
  }

  reset_peak_memory();
  last_time = get_time();

  f.integral(kT, x);
  //printf("\n\nEnergy of %s is %g\n", name, f.integral(x));
  check_peak("Energy", name, out, memE-0.1, memE+0.1, cpuE);

  Grid mygrad(x);
  mygrad.setZero();
  f.integralgrad(kT, x, &mygrad);
  //printf("Grad of %s is: %g\n", name, out, mygrad.norm());

  check_peak("Gradient", name, out, memG-0.1, memG+0.1, cpuG);
  
  {
    Grid mypgrad(x);
    mygrad.setZero();
    mypgrad.setZero();
    f.integralgrad(kT, x, &mygrad, &mypgrad);
  }
  check_peak("Gradient and preconditioned gradient", name, out, memP-0.1, memP+0.1, cpuP);

  f.integralpgrad(kT, x, &mygrad);
  check_peak("Preconditioned gradient", name, out, memPonly-0.1, memPonly+0.1, cpuPonly);

  fclose(out);
}