Example #1
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);
}
Example #2
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)));
}
Example #3
0
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);
}