예제 #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);
}
예제 #2
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;
  }
}