Пример #1
0
double run_soft_sphere(double reduced_density, double temp) {
  Functional f = SoftFluid(sigma, 1, 0);
  const double mu = find_chemical_potential(OfEffectivePotential(f), temp, reduced_density*pow(2,-5.0/2.0));
  printf("mu is %g for reduced_density = %g at temperature %g\n", mu, reduced_density, temp);

  //printf("Filling fraction is %g with functional %s at temperature %g\n", reduced_density, teff);
  //fflush(stdout);
  temperature = temp;
  //if (kT == 0) kT = ;1

  Lattice lat(Cartesian(xmax,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax));
  GridDescription gd(lat, dx);

  Grid softspherepotential(gd);
  softspherepotential.Set(soft_sphere_potential);

  f = SoftFluid(sigma, 1, mu); // compute approximate energy with chemical potential mu
  const double approx_energy = f(temperature, reduced_density*pow(2,-5.0/2.0))*xmax*ymax*zmax;
  const double precision = fabs(approx_energy*1e-9);

  f = OfEffectivePotential(SoftFluid(sigma, 1, mu) + ExternalPotential(softspherepotential));

  static Grid *potential = 0;
  potential = new Grid(gd);
  *potential = softspherepotential - temperature*log(reduced_density*pow(2,-5.0/2.0)/(1.0*radius*radius*radius))*VectorXd::Ones(gd.NxNyNz); // Bad starting guess
  printf("\tMinimizing to %g absolute precision from %g from %g...\n", precision, approx_energy, temperature);
  fflush(stdout);

  Minimizer min = Precision(precision,
                            PreconditionedConjugateGradient(f, gd, temperature,
                                potential,
                                QuadraticLineMinimizer));
  took("Setting up the variables");
  for (int i=0; min.improve_energy(true) && i<100; i++) {
  }

  took("Doing the minimization");
  min.print_info();

  Grid density(gd, EffectivePotentialToDensity()(temperature, gd, *potential));
  //printf("# per area is %g at filling fraction %g\n", density.sum()*gd.dvolume/dw/dw, reduced_density);

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

  sprintf(plotname, "papers/fuzzy-fmt/figs/radial-wca-%06.4f-%04.2f.dat", temp, reduced_density);
  z_plot(plotname, Grid(gd, pow(2,5.0/2.0)*density));
  free(plotname);

  {
    //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);

  }

  took("Plotting stuff");
  printf("density %g gives ff %g for reduced_density = %g and T = %g\n", density(0,0,gd.Nz/2),
         density(0,0,gd.Nz/2)*4*M_PI/3, reduced_density, temp);
  return density(0, 0, gd.Nz/2)*4*M_PI/3; // return bulk filling fraction
}
Пример #2
0
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++;
  }
}
Пример #3
0
double pairdist_fischer(const Grid &gsigma, const Grid &n, const Grid &nA, const Grid &n3,
                        const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) {
  // This implements the pair distribution function of Fischer and
  // Methfessel from the 1980 paper.  The py_rdf below should be the
  // true radial distribution function for a homogeneous hard-sphere
  // fluid with packing fraction eta.
  const Cartesian r01 = Cartesian(r0 - r1);
  const double r = sqrt(r01.dot(r01));
  const double eta = n3(Cartesian(0.5*(r0+r1)));
  return mc(eta, r, mc_r_step, g);
}
Пример #4
0
double run_walls(double reduced_density, const char *name, Functional fhs, double teff) {
  double kT = teff;
  if (kT == 0) kT = 1;

  Functional f = OfEffectivePotential(fhs);

  const double zmax = width + 2*spacing;
  Lattice lat(Cartesian(dw,0,0), Cartesian(0,dw,0), Cartesian(0,0,zmax));
  GridDescription gd(lat, dx);

  Grid constraint(gd);
  constraint.Set(notinwall);
  f = constrain(constraint, f);

  Grid potential(gd);
  potential = pow(2,-5.0/2.0)*(reduced_density*constraint + 1e-4*reduced_density*VectorXd::Ones(gd.NxNyNz));
  potential = -kT*potential.cwise().log();

  const double approx_energy = fhs(kT, reduced_density*pow(2,-5.0/2.0))*dw*dw*width;
  const double precision = fabs(approx_energy*1e-11);
  printf("\tMinimizing to %g absolute precision from %g from %g...\n", precision, approx_energy, kT);
  fflush(stdout);

  Minimizer min = Precision(precision,
                            PreconditionedConjugateGradient(f, gd, kT,
                                                            &potential,
                                                            QuadraticLineMinimizer));
  took("Setting up the variables");
  if (strcmp(name, "hard") != 0 && false) {
    printf("For now, SoftFluid doesn't work properly, so we're skipping the\n");
    printf("minimization at temperature %g.\n", teff);
  } else {
    for (int i=0;min.improve_energy(false) && i<100;i++) {
    }
  }
  took("Doing the minimization");
  min.print_info();

  Grid density(gd, EffectivePotentialToDensity()(kT, gd, potential));
  //printf("# per area is %g at filling fraction %g\n", density.sum()*gd.dvolume/dw/dw, eta);

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

  sprintf(plotname, "papers/fuzzy-fmt/figs/walls%s-%06.4f-%04.2f.dat", name, teff, reduced_density);
  z_plot(plotname, Grid(gd, density*pow(2,5.0/2.0)));
  free(plotname);

  took("Plotting stuff");
  printf("density %g gives ff %g for reduced density = %g and T = %g\n", density(0,0,gd.Nz/2),
         density(0,0,gd.Nz/2)*4*M_PI/3, reduced_density, teff);
  return density(0, 0, gd.Nz/2)*4*M_PI/3; // return bulk filling fraction
}
Пример #5
0
double pairdist_this_work_mc(const Grid &gsigma, const Grid &density, const Grid &nA, const Grid &n3,
                             const Grid &nbar_sokolowski,  Cartesian r0, Cartesian r1) {
  const Cartesian r01 = Cartesian(r0 - r1);
  const double r = sqrt(r01.dot(r01));
  const double eta0 = gsigma_to_eta(gsigma(r0));
  const double eta1 = gsigma_to_eta(gsigma(r1));
  return (mc(eta0, r, mc_r_step, g) + mc(eta1, r, mc_r_step, g))/2;
}
Пример #6
0
double notinwall(Cartesian r) {
  const double z = r.dot(Cartesian(0,0,1));
  if (fabs(z) > cavitysize/2) {
    return 0;
  } else {
    return 1;
  }
}
Пример #7
0
void Tile::initInteriorPolygon(int mazeWidth, int mazeHeight) {

    Meters halfWallWidth = Meters(P()->wallWidth()) / 2.0;
    Cartesian lowerLeftPoint = m_fullPolygon.getVertices().at(0);
    Cartesian upperLeftPoint = m_fullPolygon.getVertices().at(1);
    Cartesian upperRightPoint = m_fullPolygon.getVertices().at(2);
    Cartesian lowerRightPoint = m_fullPolygon.getVertices().at(3);

    m_interiorPolygon = Polygon({
        lowerLeftPoint + Cartesian(
            halfWallWidth * (getX() == 0 ? 2 : 1), halfWallWidth * (getY() == 0 ? 2 : 1)),
        upperLeftPoint + Cartesian(
            halfWallWidth * (getX() == 0 ? 2 : 1), halfWallWidth * (getY() == mazeHeight - 1 ? -2 : -1)),
        upperRightPoint + Cartesian(
            halfWallWidth * (getX() == mazeWidth - 1 ? -2 : -1), halfWallWidth * (getY() == mazeHeight - 1 ? -2 : -1)),
        lowerRightPoint + Cartesian(
            halfWallWidth * (getX() == mazeWidth - 1 ? -2 : -1), halfWallWidth * (getY() == 0 ? 2 : 1))});
}
Пример #8
0
int main(int, char **) {
  FILE *o = fopen("paper/figs/constrained-water.dat", "w");

  Functional f = OfEffectivePotential(SaftFluidSlow(water_prop.lengthscale,
                                                    water_prop.epsilonAB, water_prop.kappaAB,
                                                    water_prop.epsilon_dispersion,
                                                    water_prop.lambda_dispersion, water_prop.length_scaling, 0));
  double mu_satp = find_chemical_potential(f, water_prop.kT,
                                           water_prop.liquid_density);
  Lattice lat(Cartesian(width,0,0), Cartesian(0,width,0), Cartesian(0,0,zmax));
  GridDescription gd(lat, 0.1);

  Grid potential(gd);
  Grid constraint(gd);
  constraint.Set(notinwall);

  f = constrain(constraint,
                OfEffectivePotential(SaftFluidSlow(water_prop.lengthscale,
                                                   water_prop.epsilonAB, water_prop.kappaAB,
                                                   water_prop.epsilon_dispersion,
                                                   water_prop.lambda_dispersion, water_prop.length_scaling, mu_satp)));


  Minimizer min = Precision(0, PreconditionedConjugateGradient(f, gd, water_prop.kT, &potential,
                                                               QuadraticLineMinimizer));

  potential = water_prop.liquid_density*constraint
    + water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz);
  //potential = water_prop.liquid_density*VectorXd::Ones(gd.NxNyNz);
  potential = -water_prop.kT*potential.cwise().log();

  const int numiters = 50;
  for (int i=0;i<numiters && min.improve_energy(true);i++) {
    fflush(stdout);
    Grid density(gd, EffectivePotentialToDensity()(water_prop.kT, gd, potential));
    density.epsNative1d("paper/figs/1d-constrained-plot.eps",
			Cartesian(0,0,0), Cartesian(0,0,zmax),
			water_prop.liquid_density, 1, "Y axis: , x axis: ");
  }
  min.print_info();

  double energy = min.energy()/width/width;
  printf("Energy is %.15g\n", energy);

  double N = 0;
  {
    Grid density(gd, EffectivePotentialToDensity()(water_prop.kT, gd, potential));
    for (int i=0;i<gd.NxNyNz;i++) N += density[i]*gd.dvolume;
  }
  N = N/width/width;
  printf("N is %.15g\n", N);

    Grid density(gd, EffectivePotentialToDensity()(water_prop.kT, gd, potential));
    density.epsNative1d("paper/figs/1d-constrained-plot.eps", Cartesian(0,0,0), Cartesian(0,0,zmax), water_prop.liquid_density, 1, "Y axis: , x axis: ");
    //potential.epsNative1d("hard-wall-potential.eps", Cartesian(0,0,0), Cartesian(0,0,zmax), 1, 1);

    fclose(o);
}
Пример #9
0
double pairdist_sokolowski(const Grid &gsigma, const Grid &n, const Grid &nA, const Grid &n3,
                           const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) {
  // This implements the pair distribution function of Sokolowski and
  // Fischer from the 1992 paper.
  const Cartesian r01 = Cartesian(r0 - r1);
  const double r = sqrt(r01.dot(r01));

  const double eta0 = nbar_sokolowski(r0)*(4.0/3.0*M_PI);
  const double eta1 = nbar_sokolowski(r1)*(4.0/3.0*M_PI);
  const double eta = (eta0 + eta1)/2.0;

  return mc(eta, r, mc_r_step, g);
}
Пример #10
0
int main() {
  Lattice lat(Cartesian(0,.5,.5), Cartesian(.5,0,.5), Cartesian(.5,.5,0));
  Cartesian middle(0.5,0.5,0.5);
  Relative middlerel = lat.toRelative(middle);
  Reciprocal recip(0.2,0,0);
  int resolution = 20;
  Grid foo(lat, resolution, resolution, resolution),
    bar(lat, resolution, resolution, resolution);
  foo.Set(gaussian);
  foo.epsSlice("demo.eps", Cartesian(1,0,0), Cartesian(0,1,0),
               Cartesian(-.5,-.5,.5), 150);
  foo.epsNativeSlice("native.eps", Cartesian(1,0,0), Cartesian(0,1,0),
                     Cartesian(-.5,-.5,.5));
  
  //std::cout << "and here is the foo" << (foo + 2*bar + foo.cwise()*bar);
  std::cout << "middle and middlerel are:\n"
            << middle << std::endl << middlerel << std::endl
            << lat.toCartesian(middlerel) << std::endl;
  std::cout << "middle dot recip: " << recip * middle << std::endl;
  return 0;
}
Пример #11
0
std::pair<Cartesian, Cartesian> TileGraphicTextCache::getTileGraphicTextPosition(
        int x, int y, int numRows, int numCols, int row, int col) const {

    // Get the character position in the maze for the starting tile
    std::pair<Cartesian, Cartesian> textPosition = m_tileGraphicTextPositions.at(
        std::make_pair(
            std::make_pair(numRows, numCols),
            std::make_pair(row, col)
        )
    );

    // Now get the character position in the maze for *this* tile
    Meters tileLength = m_wallLength + m_wallWidth;
    Cartesian offset = Cartesian(tileLength * x, tileLength * y);
    Cartesian LL = textPosition.first + offset;
    Cartesian UR = textPosition.second + offset;

    return std::make_pair(LL, UR);
}
Пример #12
0
QPair<Cartesian, Cartesian> TileGraphicTextCache::getTileGraphicTextPosition(
        int x, int y, int numRows, int numCols, int row, int col) const {

    // Get the character position in the maze for the starting tile
    QPair<Cartesian, Cartesian> textPosition = m_tileGraphicTextPositions.value(
        {
            {numRows, numCols},
            {row, col}
        }
    );

    // Now get the character position in the maze for *this* tile
    Meters tileLength = m_wallLength + m_wallWidth;
    Cartesian offset = Cartesian(tileLength * x, tileLength * y);
    Cartesian LL = textPosition.first + offset;
    Cartesian UR = textPosition.second + offset;

    return {LL, UR};
}
Пример #13
0
void Tile::initWallPolygons(int mazeWidth, int mazeHeight) {

    Cartesian outerLowerLeftPoint = m_fullPolygon.getVertices().at(0);
    Cartesian outerUpperLeftPoint = m_fullPolygon.getVertices().at(1);
    Cartesian outerUpperRightPoint = m_fullPolygon.getVertices().at(2);
    Cartesian outerLowerRightPoint = m_fullPolygon.getVertices().at(3);

    Cartesian innerLowerLeftPoint = m_interiorPolygon.getVertices().at(0);
    Cartesian innerUpperLeftPoint = m_interiorPolygon.getVertices().at(1);
    Cartesian innerUpperRightPoint = m_interiorPolygon.getVertices().at(2);
    Cartesian innerLowerRightPoint = m_interiorPolygon.getVertices().at(3);

    std::vector<Cartesian> northWall;
    northWall.push_back(innerUpperLeftPoint);
    northWall.push_back(Cartesian(innerUpperLeftPoint.getX(), outerUpperLeftPoint.getY()));
    northWall.push_back(Cartesian(innerUpperRightPoint.getX(), outerUpperRightPoint.getY()));
    northWall.push_back(innerUpperRightPoint);
    m_wallPolygons.insert(std::make_pair(Direction::NORTH, Polygon(northWall)));

    std::vector<Cartesian> eastWall;
    eastWall.push_back(innerLowerRightPoint);
    eastWall.push_back(innerUpperRightPoint);
    eastWall.push_back(Cartesian(outerUpperRightPoint.getX(), innerUpperRightPoint.getY()));
    eastWall.push_back(Cartesian(outerLowerRightPoint.getX(), innerLowerRightPoint.getY()));
    m_wallPolygons.insert(std::make_pair(Direction::EAST, Polygon(eastWall)));

    std::vector<Cartesian> southWall;
    southWall.push_back(Cartesian(innerLowerLeftPoint.getX(), outerLowerLeftPoint.getY()));
    southWall.push_back(innerLowerLeftPoint);
    southWall.push_back(innerLowerRightPoint);
    southWall.push_back(Cartesian(innerLowerRightPoint.getX(), outerLowerRightPoint.getY()));
    m_wallPolygons.insert(std::make_pair(Direction::SOUTH, Polygon(southWall)));

    std::vector<Cartesian> westWall;
    westWall.push_back(Cartesian(outerLowerLeftPoint.getX(), innerLowerLeftPoint.getY()));
    westWall.push_back(Cartesian(outerUpperLeftPoint.getX(), innerUpperLeftPoint.getY()));
    westWall.push_back(innerUpperLeftPoint);
    westWall.push_back(innerLowerLeftPoint);
    m_wallPolygons.insert(std::make_pair(Direction::WEST, Polygon(westWall)));
}
Пример #14
0
void Tile::initCornerPolygons(int mazeWidth, int mazeHeight) {

    Cartesian outerLowerLeftPoint = m_fullPolygon.getVertices().at(0);
    Cartesian outerUpperLeftPoint = m_fullPolygon.getVertices().at(1);
    Cartesian outerUpperRightPoint = m_fullPolygon.getVertices().at(2);
    Cartesian outerLowerRightPoint = m_fullPolygon.getVertices().at(3);

    Cartesian innerLowerLeftPoint = m_interiorPolygon.getVertices().at(0);
    Cartesian innerUpperLeftPoint = m_interiorPolygon.getVertices().at(1);
    Cartesian innerUpperRightPoint = m_interiorPolygon.getVertices().at(2);
    Cartesian innerLowerRightPoint = m_interiorPolygon.getVertices().at(3);

    std::vector<Cartesian> lowerLeftCorner;
    lowerLeftCorner.push_back(outerLowerLeftPoint);
    lowerLeftCorner.push_back(Cartesian(outerLowerLeftPoint.getX(), innerLowerLeftPoint.getY()));
    lowerLeftCorner.push_back(innerLowerLeftPoint);
    lowerLeftCorner.push_back(Cartesian(innerLowerLeftPoint.getX(), outerLowerLeftPoint.getY()));
    m_cornerPolygons.push_back(Polygon(lowerLeftCorner));

    std::vector<Cartesian> upperLeftCorner;
    upperLeftCorner.push_back(Cartesian(outerUpperLeftPoint.getX(), innerUpperLeftPoint.getY()));
    upperLeftCorner.push_back(outerUpperLeftPoint);
    upperLeftCorner.push_back(Cartesian(innerUpperLeftPoint.getX(), outerUpperLeftPoint.getY()));
    upperLeftCorner.push_back(innerUpperLeftPoint);
    m_cornerPolygons.push_back(Polygon(upperLeftCorner));

    std::vector<Cartesian> upperRightCorner;
    upperRightCorner.push_back(innerUpperRightPoint);
    upperRightCorner.push_back(Cartesian(innerUpperRightPoint.getX(), outerUpperRightPoint.getY()));
    upperRightCorner.push_back(outerUpperRightPoint);
    upperRightCorner.push_back(Cartesian(outerUpperRightPoint.getX(), innerUpperRightPoint.getY()));
    m_cornerPolygons.push_back(Polygon(upperRightCorner));

    std::vector<Cartesian> lowerRightCorner;
    lowerRightCorner.push_back(Cartesian(innerLowerRightPoint.getX(), outerLowerRightPoint.getY()));
    lowerRightCorner.push_back(innerLowerRightPoint);
    lowerRightCorner.push_back(Cartesian(outerLowerRightPoint.getX(), innerLowerRightPoint.getY()));
    lowerRightCorner.push_back(outerLowerRightPoint);
    m_cornerPolygons.push_back(Polygon(lowerRightCorner));
}
Пример #15
0
void path_plot(const char *fname, const Grid &density, const Grid &constraint) {
    fflush(stdout);
    FILE *out = fopen(fname, "w");
    if (!out) {
        fprintf(stderr, "Unable to create file %s!\n", fname);
        // don't just abort?
        return;
    }
    fflush(stdout);
    const GridDescription gd = density.description();
    const double z0 = spacing + dx;
    double radius_path = 2.005;
    int num = 100;
    for (int i=0; i<int((width/2.0-radius_path)/dx+0.5); i++) {
        const double x_path = i*dx;
        Cartesian r = Cartesian(width/2-x_path,0,z0);
        Cartesian r_opp_side = Cartesian(width/2-x_path,0,gd.Nz*dx-z0);
        const double g2_path = density(r)*constraint(r_opp_side)/density(r_opp_side)/constraint(r);
        fprintf(out,"%g\t%g\t%g\t%g\n", x_path, g2_path, z0, width/2-x_path);
    }
    fflush(stdout);
    for (int i=0; i<num ; i++) {
        double theta = i*M_PI/num/2.0;
        const double x_path = i*M_PI/num/2.0*radius_path + 8.0;
        Cartesian r = Cartesian(radius_path*cos(theta),0,z0+radius_path*sin(theta));
        Cartesian r_opp_side = Cartesian(radius_path*cos(theta),0,gd.Nz*dx-z0-radius_path*sin(theta));
        const double g2_path = density(r)*constraint(r_opp_side)/density(r_opp_side)/constraint(r);
        fprintf(out,"%g\t%g\t%g\t%g\n", x_path, g2_path, z0+radius_path*sin(theta), radius_path*cos(theta));
    }
    fflush(stdout);
    for (int i=0; i<int(8.0/dx+0.5); i++) {
        double r1z = i*dx;
        const double x_path = i*dx + radius_path*M_PI/2.0 + 10.0-radius_path;
        Cartesian r = Cartesian(0,0,r1z+radius_path+z0);
        Cartesian r_opp_side = Cartesian(0,0,gd.Nz*dx-r1z-radius_path-z0);
        const double g2_path = density(r)*constraint(r_opp_side)/density(r_opp_side)/constraint(r);
        fprintf(out,"%g\t%g\t%g\t%g\n", x_path, g2_path, r1z+radius_path+z0, 0.0);
    }
    fflush(stdout);
    fclose(out);
}
Пример #16
0
double N_from_mu(Minimizer *min, Grid *potential, const Grid &constraint, double mu) {
  Functional f = constrain(constraint, OfEffectivePotential(HS + IdealGas()
                                                            + ChemicalPotential(mu)));
  double Nnow = 0;
  min->minimize(f, potential->description());
  for (int i=0;i<numiters && min->improve_energy(false);i++) {
    Grid density(potential->description(), EffectivePotentialToDensity()(1, potential->description(), *potential));
    Nnow = density.sum()*potential->description().dvolume;
    printf("Nnow is %g vs %g\n", Nnow, N);
    fflush(stdout);
    
    density.epsNativeSlice("papers/contact/figs/box.eps", 
                           Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), 
                           Cartesian(0,-ymax/2-1,-zmax/2-1));
    density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", 
                           Cartesian(xmax+2,0,zmax+2),  Cartesian(0,ymax+2,0),
                           Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1));
    //sleep(3);
  }
  return Nnow;
}
Пример #17
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;
}
Пример #18
0
int main(int argc, char *argv[]) {
  if (argc == 5) {
    if (sscanf(argv[1], "%lg", &xmax) != 1) {
      printf("Got bad x argument: %s\n", argv[1]);
      return 1;
    }
    if (sscanf(argv[2], "%lg", &ymax) != 1) {
      printf("Got bad y argument: %s\n", argv[2]);
      return 1;
    }
    if (sscanf(argv[3], "%lg", &zmax) != 1) {
      printf("Got bad z argument: %s\n", argv[3]);
      return 1;
    }
    if (sscanf(argv[4], "%lg", &N) != 1) {
      printf("Got bad N argument: %s\n", argv[4]);
      return 1;
    }
    using_default_box = false;
    printf("Box is %g x %g x %g hard sphere diameters, and it holds %g of them\n", xmax, ymax, zmax, N);
  }

  char *datname = (char *)malloc(1024);
  sprintf(datname, "papers/contact/figs/box-%02.0f,%02.0f,%02.0f-%02.0f-energy.dat", xmax, ymax, zmax, N);
  
  FILE *o = fopen(datname, "w");

  const double myvolume = (xmax+2)*(ymax+2)*(zmax+2);
  const double meandensity = N/myvolume;

  Functional f = OfEffectivePotential(HS + IdealGas());
  double mu = find_chemical_potential(f, 1, meandensity);
  f = OfEffectivePotential(HS + IdealGas()
                           + ChemicalPotential(mu));

  Lattice lat(Cartesian(xmax+3,0,0), Cartesian(0,ymax+3,0), Cartesian(0,0,zmax+3));
  GridDescription gd(lat, 0.05);
    
  Grid potential(gd);
  Grid constraint(gd);
  constraint.Set(notinwall);
  took("Setting the constraint");

  printf("xmax = %g\nymax = %g\nzmax = %g\nmeandensity=%g\n", xmax, ymax, zmax, meandensity);
  f = constrain(constraint, f);
  constraint.epsNativeSlice("papers/contact/figs/box-constraint.eps",
   			      Cartesian(0,ymax+4,0), Cartesian(0,0,zmax+4), 
   			      Cartesian(0,-ymax/2-2,-zmax/2-2));
  printf("Constraint has become a graph!\n");
  
  potential = meandensity*constraint + 1e-4*meandensity*VectorXd::Ones(gd.NxNyNz);
  potential = -potential.cwise().log();
    
  Minimizer min = Precision(1e-6, 
                            PreconditionedConjugateGradient(f, gd, 1, 
                                                            &potential,
                                                            QuadraticLineMinimizer));
    
  double mumax = mu, mumin = mu, dmu = 4.0/N;
  double Nnow = N_from_mu(&min, &potential, constraint, mu);
  const double fraccuracy = 1e-3;
  if (fabs(Nnow/N - 1) > fraccuracy) {
    if (Nnow > N) {
      while (Nnow > N) {
        mumin = mumax;
        mumax += dmu;
        dmu *= 2;
        
        Nnow = N_from_mu(&min, &potential, constraint, mumax);
        // Grid density(gd, EffectivePotentialToDensity()(1, gd, potential));
        // density = EffectivePotentialToDensity()(1, gd, potential);
        // density.epsNativeSlice("papers/contact/figs/box.eps", 
        //                        Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), 
        //                        Cartesian(0,-ymax/2-1,-zmax/2-1));
        // density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", 
        //                        Cartesian(xmax+2,0,zmax+2),  Cartesian(0,ymax+2,0),
        //                        Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1));
        printf("mumax %g gives N %g\n", mumax, Nnow);
        took("Finding N from mu");
      }
      printf("mu is between %g and %g\n", mumin, mumax);
    } else {
      while (Nnow < N) {
        mumax = mumin;
        if (mumin > dmu) {
          mumin -= dmu;
          dmu *= 2;
        } else if (mumin > 0) {
          mumin = -mumin;
        } else {
          mumin *= 2;
        }
        
        Nnow = N_from_mu(&min, &potential, constraint, mumin);
        // density = EffectivePotentialToDensity()(1, gd, potential);
        // density.epsNativeSlice("papers/contact/figs/box.eps", 
        //                        Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), 
        //                        Cartesian(0,-ymax/2-1,-zmax/2-1));
        // density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", 
        //                        Cartesian(xmax+2,0,zmax+2),  Cartesian(0,ymax+2,0),
        //                        Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1));
        printf("mumin %g gives N %g\n", mumin, Nnow);
        took("Finding N from mu");
      }
      printf("mu is between %g and %g\n", mumin, mumax);
    }
    
    while (fabs(N/Nnow-1) > fraccuracy) {
      mu = 0.5*(mumin + mumax);
      Nnow = N_from_mu(&min, &potential, constraint, mu);
      // density = EffectivePotentialToDensity()(1, gd, potential);
      // density.epsNativeSlice("papers/contact/figs/box.eps", 
      //                        Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), 
      //                        Cartesian(0,-ymax/2-1,-zmax/2-1));
      // density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", 
      //                        Cartesian(xmax+2,0,zmax+2),  Cartesian(0,ymax+2,0),
      //                        Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1));
      printf("Nnow is %g vs %g with mu %g\n", Nnow, N, mu);
      took("Finding N from mu");
      if (Nnow > N) {
        mumin = mu;
      } else {
        mumax = mu;
      }
    }
  }
  printf("N final is %g (vs %g) with mu = %g\n", Nnow, N, mu);

  double energy = min.energy();
  printf("Energy is %.15g\n", energy);

  Grid density(gd, EffectivePotentialToDensity()(1, gd, potential));
  double mean_contact_density = ContactDensitySimplest(1.0).integral(1, density)/myvolume;
  
  fprintf(o, "%g\t%g\t%g\t%.15g\t%.15g\n", xmax, ymax, zmax, energy, mean_contact_density);
  
  Grid energy_density(gd, f(1, gd, potential));
  Grid contact_density(gd, ContactDensitySimplest(1.0)(1, gd, density));
  Grid n0(gd, ShellConvolve(1)(1, density));
  Grid wu_contact_density(gd, FuWuContactDensity(1.0)(1, gd, density));
  char *plotname = (char *)malloc(1024);
  sprintf(plotname, "papers/contact/figs/box-100c--%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N);
  plot_grids_100_center(plotname, density, energy_density, contact_density);
  sprintf(plotname, "papers/contact/figs/box-100s--%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N);
  plot_grids_100_side(plotname, density, energy_density, contact_density);
  sprintf(plotname, "papers/contact/figs/box-110c--%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N);
  plot_grids_110(plotname, density, energy_density, contact_density);
  sprintf(plotname, "papers/contact/figs/box-x-%02.0f,%02.0f,%02.0f-%02.0f.dat", xmax, ymax, zmax, N);
  x_plot(plotname, density, energy_density, contact_density, wu_contact_density);
  free(plotname);
  density.epsNativeSlice("papers/contact/figs/box.eps", 
                         Cartesian(0,ymax+2,0), Cartesian(0,0,zmax+2), 
                         Cartesian(0,-ymax/2-1,-zmax/2-1));
  density.epsNativeSlice("papers/contact/figs/box-diagonal.eps", 
                         Cartesian(xmax+2,0,zmax+2),  Cartesian(0,ymax+2,0),
                         Cartesian(-xmax/2-1,-ymax/2-1,-zmax/2-1));
  
  took("Plotting stuff");
  
  fclose(o);
}
Пример #19
0
double pairdist_this_work_short(const Grid &gsigma, const Grid &density, const Grid &nA, const Grid &n3,
                                const Grid &nbar_sokolowski, Cartesian r0, Cartesian r1) {
  const Cartesian r01 = Cartesian(r0 - r1);
  const double r = sqrt(r01.dot(r01));
  return (short_range_radial_distribution(gsigma(r0), r) + short_range_radial_distribution(gsigma(r1), r))/2;
}
Пример #20
0
void run_with_eta(double eta, const char *name, Functional fhs) {
  // Generates a data file for the pair distribution function, for filling fraction eta
  // and distance of first sphere from wall of z0. Data saved in a table such that the
  // columns are x values and rows are z1 values.
  printf("Now starting run_with_eta with eta = %g name = %s\n",
         eta, name);
  Functional f = OfEffectivePotential(fhs + IdealGas());
  double mu = find_chemical_potential(f, 1, eta/(4*M_PI/3));
  f = OfEffectivePotential(fhs + IdealGas()
                           + ChemicalPotential(mu));
  Lattice lat(Cartesian(width,0,0), Cartesian(0,width,0), Cartesian(0,0,width));
  GridDescription gd(lat, dx);
  Grid potential(gd);
  Grid constraint(gd);
  constraint.Set(notinsphere);
  f = constrain(constraint, f);
  potential = (eta*constraint + 1e-4*eta*VectorXd::Ones(gd.NxNyNz))/(4*M_PI/3);
  potential = -potential.cwise().log();

  const double approx_energy = (fhs + IdealGas() + ChemicalPotential(mu))(1, eta/(4*M_PI/3))*uipow(width,3);
  const double precision = fabs(approx_energy*1e-10);
  //printf("Minimizing to %g absolute precision...\n", precision);
  { // Put mimizer in block so as to free it when we finish minimizing to save memory.
    Minimizer min = Precision(precision,
                              PreconditionedConjugateGradient(f, gd, 1,
                                                              &potential,
                                                              QuadraticLineMinimizer));
    for (int i=0;min.improve_energy(true) && i<100;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);
    }
    took("Doing the minimization");
  }
  Grid density(gd, EffectivePotentialToDensity()(1, gd, potential));
  Grid gsigma(gd, gSigmaA(1.0)(1, gd, density));
  Grid nA(gd, ShellConvolve(2)(1, density)/(4*M_PI*4));
  Grid n3(gd, StepConvolve(1)(1, density));
  Grid nbar_sokolowski(gd, StepConvolve(1.6)(1, density));
  nbar_sokolowski /= (4.0/3.0*M_PI*ipow(1.6, 3));
  // Create the walls directory if it doesn't exist.
  if (mkdir("papers/pair-correlation/figs/walls", 0777) != 0 && errno != EEXIST) {
    // We failed to create the directory, and it doesn't exist.
    printf("Failed to create papers/pair-correlation/figs/walls: %s",
           strerror(errno));
    exit(1); // fail immediately with error code
  }

  // here you choose the values of z0 to use
  // dx is the resolution at which we compute the density.
  char *plotname = new char[4096];
  for (double z0 = 2.1; z0 < 4.5; z0 += 2.1) {
    // For each z0, we now pick one of our methods for computing the
    // pair distribution function:
    for (int version = 0; version < numplots; version++) {
      sprintf(plotname,
              "papers/pair-correlation/figs/triplet%s-%s-%04.2f-%1.2f.dat",
              name, fun[version], eta, z0);
      FILE *out = fopen(plotname,"w");
      FILE *xfile = fopen("papers/pair-correlation/figs/triplet-x.dat","w");
      FILE *zfile = fopen("papers/pair-correlation/figs/triplet-z.dat","w");
      // the +1 for z0 and z1 are to shift the plot over, so that a sphere touching the wall
      // is at z = 0, to match with the monte carlo data
      const Cartesian r0(0,0,z0);
      for (double x = 0; x < 4; x += dx) {
        for (double z1 = -4; z1 <= 9; z1 += dx) {
          const Cartesian r1(x,0,z1);
          double g2 = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
          double n_bulk = (3.0/4.0/M_PI)*eta;
          double g3 = g2*density(r0)*density(r1)/n_bulk/n_bulk;
          fprintf(out, "%g\t", g3);
          fprintf(xfile, "%g\t", x);
          fprintf(zfile, "%g\t", z1);
        }
        fprintf(out, "\n");
        fprintf(xfile, "\n");
        fprintf(zfile, "\n");
      }
      fclose(out);
      fclose(xfile);
      fclose(zfile);
    }
  }
  delete[] plotname;
  took("Dumping the triplet dist plots");
  const double ds = 0.01; // step size to use in path plots, FIXME increase for publication!
  const double delta = .1; //this is the value of radius of the
                           //particle as it moves around the contact
                           //sphere on its path
  char *plotname_path = new char[4096];
  for (int version = 0; version < numplots; version++) {
    sprintf(plotname_path,
            "papers/pair-correlation/figs/triplet%s-path-%s-%04.2f.dat",
            name, fun[version], eta);
    FILE *out_path = fopen(plotname_path, "w");
    if (!out_path) {
      fprintf(stderr, "Unable to create file %s!\n", plotname_path);
      return;
    }

    sprintf(plotname_path,
            "papers/pair-correlation/figs/triplet-back-contact-%s-%04.2f.dat",
            fun[version], eta);
    FILE *out_back = fopen(plotname_path, "w");
    if (!out_back) {
      fprintf(stderr, "Unable to create file %s!\n", plotname_path);
      return;
    }
    fprintf(out_path, "# unused\tg3\tz\tx\n");
    fprintf(out_back, "# unused\tg3\tz\tx\n");

    const Cartesian r0(0,0, 2.0+delta);
    const double max_theta = M_PI*2.0/3;
    for (double z = 7; z >= 2*(2.0 + delta); z-=ds) {
      const Cartesian r1(0,0,z);
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    for (double z = -7; z <= -(2.0 + delta); z+=ds) {
      const Cartesian r1(0,0,z);
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    const double dtheta = ds/2;
    for (double theta = 0; theta <= max_theta; theta += dtheta){
      const Cartesian r1((2.0+delta)*sin(theta), 0, (2.0+delta)*(1+cos(theta)));
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    for (double theta = 0; theta <= max_theta; theta += dtheta){
      const Cartesian r1((2.0+delta)*sin(theta), 0,-(2.0+delta)*cos(theta));
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    for (double x = (2.0+delta)*sqrt(3)/2; x<=6; x+=ds){
      const Cartesian r1(x, 0, 1.0+delta/2);
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
      fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    fclose(out_path);
    fclose(out_back);
  }
  for (int version = 0; version < numplots; version++) {
    sprintf(plotname_path,
            "papers/pair-correlation/figs/triplet-path-inbetween-%s-%04.2f.dat",
            fun[version], eta);
    FILE *out_path = fopen(plotname_path, "w");
    if (!out_path) {
      fprintf(stderr, "Unable to create file %s!\n", plotname_path);
      return;
    }
    sprintf(plotname_path,
            "papers/pair-correlation/figs/triplet-back-inbetween-%s-%04.2f.dat",
            fun[version], eta);
    FILE *out_back = fopen(plotname_path, "w");
    if (!out_back) {
      fprintf(stderr, "Unable to create file %s!\n", plotname_path);
      return;
    }
    fprintf(out_path, "# unused\tg3\tz\tx\n");
    fprintf(out_back, "# unused\tg3\tz\tx\n");

    const Cartesian r0(0,0, 4.0+2*delta);
    const double max_theta = M_PI;
    for (double z = 11; z >= 3*(2.0 + delta); z-=ds) {
      const Cartesian r1(0,0,z);
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    for (double z = -10; z <= -(2.0 + delta); z+=ds) {
      const Cartesian r1(0,0,z);
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    const double dtheta = ds/2;
    for (double theta = 0; theta <= max_theta; theta += dtheta){
      const Cartesian r1((2.0+delta)*sin(theta), 0, (2.0+delta)*(2+cos(theta)));
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    for (double theta = 0; theta <= max_theta; theta += dtheta){
      const Cartesian r1((2.0+delta)*sin(theta), 0, -(2.0+delta)*cos(theta));
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    for (double x = 0; x>=-6; x-=ds){
      const Cartesian r1(x, 0, 2.0+delta);
      double g2_path = pairdists[version](gsigma, density, nA, n3, nbar_sokolowski, r0, r1);
      double n_bulk = (3.0/4.0/M_PI)*eta;
      double g3 = g2_path*density(r0)*density(r1)/n_bulk/n_bulk;
      fprintf(out_path,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
      fprintf(out_back,"0\t%g\t%g\t%g\n", g3, r1[2], r1[0]);
    }
    fclose(out_path);
    fclose(out_back);
  }
  delete[] plotname_path;
}
Пример #21
0
#include "generated/phi1.h"
#include "generated/phi1-Veff.h"
#include "generated/phi1-plus.h"
#include "generated/phi2.h"
#include "generated/phi2-Veff.h"
#include "generated/phi3rf.h"
#include "generated/phi3rf-Veff.h"
#include "generated/almostrf.h"
#include "generated/almostrfnokt.h"

#include "handymath.h"

int errors = 0;

double a = 5;
Lattice lat(Cartesian(0,a,a), Cartesian(a,0,a), Cartesian(a,a,0));
//Lattice lat(Cartesian(1.4*rmax,0,0), Cartesian(0,1.4*rmax,0), Cartesian(0,0,1.4*rmax));
GridDescription gd(lat, 0.2);

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);
Пример #22
0
QVector<float> TransformationMatrix::getZoomedMapTransformationMatrix(
    QPair<double, double> physicalMazeSize,
    QPair<int, int> zoomedMapPosition,
    QPair<int, int> zoomedMapSize,
    QPair<int, int> windowSize,
    double screenPixelsPerMeter,
    double zoomedMapScale,
    bool rotateZoomedMap,
    const Coordinate& initialMouseTranslation,
    const Coordinate& currentMouseTranslation,
    const Angle& currentMouseRotation) {

    // The purpose of this function is to produce a 4x4 matrix which,
    // when applied to the physical coordinate within the vertex shader,
    // transforms it into an OpenGL coordinate for the zoomed map. Note that
    // the zoomed map will likely not contain the entirety of the maze, so the
    // pixel coordinates will be outside of the map.

    // Step 1: Calculate the scaling matrix
    double physicalWidth = physicalMazeSize.first;
    double physicalHeight = physicalMazeSize.second;

    // Note that this is not literally the number of pixels per meter of the
    // screen. Rather, it's our desired number of pixels per simulation meter.
    double pixelsPerMeter = screenPixelsPerMeter * zoomedMapScale;
    double pixelWidth = pixelsPerMeter * physicalWidth;
    double pixelHeight = pixelsPerMeter * physicalHeight;

    QPair<double, double> openGlOrigin =
        mapPixelCoordinateToOpenGlCoordinate({0, 0}, windowSize);
    QPair<double, double> openGlMazeSize =
        mapPixelCoordinateToOpenGlCoordinate({pixelWidth, pixelHeight}, windowSize);

    double openGlWidth = openGlMazeSize.first - openGlOrigin.first;
    double openGlHeight = openGlMazeSize.second - openGlOrigin.second;

    double horizontalScaling = openGlWidth / physicalWidth;
    double verticalScaling = openGlHeight / physicalHeight;

    QVector<float> scalingMatrix = {
        static_cast<float>(horizontalScaling),                                 0.0, 0.0, 0.0,
                                          0.0, static_cast<float>(verticalScaling), 0.0, 0.0,
                                          0.0,                                 0.0, 1.0, 0.0,
                                          0.0,                                 0.0, 0.0, 1.0,
    };

    // Step 2: Construct the translation matrix. We must ensure that the mouse
    // starts (static translation) and stays (dynamic translation) at the
    // center of the screen.

    // Part A: Find the static translation, i.e., the translation that puts the
    // center of the mouse (i.e., the midpoint of the line connecting its
    // wheels) in the center of the zoomed map. 
    double centerXPixels = initialMouseTranslation.getX().getMeters() * pixelsPerMeter;
    double centerYPixels = initialMouseTranslation.getY().getMeters() * pixelsPerMeter;
    double zoomedMapCenterXPixels = zoomedMapPosition.first + 0.5 * zoomedMapSize.first;
    double zoomedMapCenterYPixels = zoomedMapPosition.second + 0.5 * zoomedMapSize.second;
    double staticTranslationXPixels = zoomedMapCenterXPixels - centerXPixels;
    double staticTranslationYPixels = zoomedMapCenterYPixels - centerYPixels;
    QPair<double, double> staticTranslation =
        mapPixelCoordinateToOpenGlCoordinate({staticTranslationXPixels, staticTranslationYPixels}, windowSize);

    // Part B: Find the dynamic translation, i.e., the current translation of the mouse.
    Cartesian mouseTranslationDelta = Cartesian(currentMouseTranslation) - initialMouseTranslation;
    double dynamicTranslationXPixels = mouseTranslationDelta.getX().getMeters() * pixelsPerMeter;
    double dynamicTranslationYPixels = mouseTranslationDelta.getY().getMeters() * pixelsPerMeter;
    QPair<double, double> dynamicTranslation =
        mapPixelCoordinateToOpenGlCoordinate({dynamicTranslationXPixels, dynamicTranslationYPixels}, windowSize);

    // Combine the transalations and form the translation matrix
    double horizontalTranslation = staticTranslation.first -  dynamicTranslation.first + openGlOrigin.first;
    double verticalTranslation = staticTranslation.second - dynamicTranslation.second + openGlOrigin.second;
    QVector<float> translationMatrix = {
        1.0, 0.0, 0.0, static_cast<float>(horizontalTranslation), 
        0.0, 1.0, 0.0,   static_cast<float>(verticalTranslation),
        0.0, 0.0, 1.0,                                       0.0,
        0.0, 0.0, 0.0,                                       1.0,
    };

    // Step 3: Construct a few other transformation matrices needed for
    // rotating the maze. In order to properly rotate the maze, we must first
    // translate the center of the mouse to the origin. Then we have to unscale
    // it, rotate it, scale it, and then translate it back to the proper
    // location. Hence all of the matrices.

    // We subtract Degrees(90) here since we want forward to face NORTH
    double theta = (Degrees(currentMouseRotation) - Degrees(90)).getRadiansZeroTo2pi();
    QVector<float> rotationMatrix = {
        static_cast<float>( std::cos(theta)), static_cast<float>(std::sin(theta)), 0.0, 0.0,
        static_cast<float>(-std::sin(theta)), static_cast<float>(std::cos(theta)), 0.0, 0.0,
                                    0.0,                            0.0, 1.0, 0.0,
                                    0.0,                            0.0, 0.0, 1.0,
    };

    QVector<float> inverseScalingMatrix = {
        static_cast<float>(1.0/horizontalScaling),                                     0.0, 0.0, 0.0,
                                              0.0, static_cast<float>(1.0/verticalScaling), 0.0, 0.0,
                                              0.0,                                     0.0, 1.0, 0.0,
                                              0.0,                                     0.0, 0.0, 1.0,
    };

    QPair<double, double> zoomedMapCenterOpenGl =
        mapPixelCoordinateToOpenGlCoordinate({zoomedMapCenterXPixels, zoomedMapCenterYPixels}, windowSize);

    QVector<float> translateToOriginMatrix = {
        1.0, 0.0, 0.0,  static_cast<float>(zoomedMapCenterOpenGl.first),
        0.0, 1.0, 0.0, static_cast<float>(zoomedMapCenterOpenGl.second),
        0.0, 0.0, 1.0,                                              0.0,
        0.0, 0.0, 0.0,                                              1.0,
    };

    QVector<float> inverseTranslateToOriginMatrix = {
        1.0, 0.0, 0.0,  static_cast<float>(-zoomedMapCenterOpenGl.first),
        0.0, 1.0, 0.0, static_cast<float>(-zoomedMapCenterOpenGl.second),
        0.0, 0.0, 1.0,                                               0.0,
        0.0, 0.0, 0.0,                                               1.0,
    };

    QVector<float> zoomedMapCameraMatrix = multiply4x4Matrices(translationMatrix, scalingMatrix);
    if (rotateZoomedMap) {
        zoomedMapCameraMatrix =
            multiply4x4Matrices(translateToOriginMatrix,
            multiply4x4Matrices(scalingMatrix,
            multiply4x4Matrices(rotationMatrix,
            multiply4x4Matrices(inverseScalingMatrix,
            multiply4x4Matrices(inverseTranslateToOriginMatrix,
                                zoomedMapCameraMatrix)))));
    }

    return zoomedMapCameraMatrix;
}
Пример #23
0
double run_walls(double eta, const char *name, Functional fhs, double teff) {
  //printf("Filling fraction is %g with functional %s at temperature %g\n", eta, name, teff);
  //fflush(stdout);
  double kT = teff;
  if (kT == 0) kT = 1;

  Functional f = OfEffectivePotential(fhs);

  const double zmax = width + 2*spacing;
  Lattice lat(Cartesian(dw,0,0), Cartesian(0,dw,0), Cartesian(0,0,zmax));
  GridDescription gd(lat, dx);

  Grid constraint(gd);
  constraint.Set(notinwall);
  f = constrain(constraint, f);

  // We reuse the potential, which should give us a better starting
  // guess on each calculation.
  static Grid *potential = 0;
  if (strcmp(name, "hard") == 0) {
    // start over for each potential
    delete potential;
    potential = 0;
  }
  if (!potential) {
    potential = new Grid(gd);
    *potential = (eta*constraint + 1e-4*eta*VectorXd::Ones(gd.NxNyNz))/(4*M_PI/3);
    *potential = -kT*potential->cwise().log();
  }

  // FIXME below I use the HS energy because of issues with the actual
  // functional.
  const double approx_energy = fhs(kT, eta/(4*M_PI/3))*dw*dw*width;
  const double precision = fabs(approx_energy*1e-5);
  printf("\tMinimizing to %g absolute precision from %g from %g...\n", precision, approx_energy, kT);
  fflush(stdout);

  Minimizer min = Precision(precision,
                            PreconditionedConjugateGradient(f, gd, kT,
                                                            potential,
                                                            QuadraticLineMinimizer));
  took("Setting up the variables");
  for (int i=0;min.improve_energy(false) && i<100;i++) {
  }
  took("Doing the minimization");
  min.print_info();

  Grid density(gd, EffectivePotentialToDensity()(kT, gd, *potential));
  //printf("# per area is %g at filling fraction %g\n", density.sum()*gd.dvolume/dw/dw, eta);
  
  char *plotname = (char *)malloc(1024);

  sprintf(plotname, "papers/fuzzy-fmt/figs/walls%s-%06.4f-%04.2f.dat", name, teff, eta);
  z_plot(plotname, Grid(gd, 4*M_PI*density/3));
  free(plotname);

  {
    GridDescription gdj = density.description(); 
    double sep =  gdj.dz*gdj.Lat.a3().norm();
    int div = gdj.Nz;
    int mid = int (div/2.0);
    double Ntot_per_A = 0;
    double mydist = 0;
   
    for (int j=0; j<mid; j++){
      Ntot_per_A += density(0,0,j)*sep;
      mydist += sep;
    }
    
    double Extra_per_A = Ntot_per_A - eta/(4.0/3.0*M_PI)*width/2;
    
    FILE *fout = fopen("papers/fuzzy-fmt/figs/wallsfillingfracInfo.txt", "a");
    fprintf(fout, "walls%s-%04.2f.dat  -  If you want to match the bulk filling fraction of figs/walls%s-%04.2f.dat, than the number of extra spheres per area to add is %04.10f.  So you'll want to multiply %04.2f by your cavity volume and divide by (4/3)pi.  Then add %04.10f times the Area of your cavity to this number\n",
	    name, eta, name, eta, Extra_per_A, eta, Extra_per_A);
    
    int wallslen = 20;
    double Extra_spheres =  (eta*wallslen*wallslen*wallslen/(4*M_PI/3) + Extra_per_A*wallslen*wallslen);  
    fprintf (fout, "For filling fraction %04.02f and walls of length %d you'll want to use %.0f spheres.\n\n", eta, wallslen, Extra_spheres);
    
    fclose(fout); 
  }
  
  {
    //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);
  }
  
  took("Plotting stuff");
  printf("density %g gives ff %g for eta = %g and T = %g\n", density(0,0,gd.Nz/2),
         density(0,0,gd.Nz/2)*4*M_PI/3, eta, teff);
  return density(0, 0, gd.Nz/2)*4*M_PI/3; // return bulk filling fraction
}
Пример #24
0
int main(int argc, char *argv[]) {
  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\n", diameter);
  }
  
  const double ptransition  =(3.0*M_PI-4.0)*(diameter/2.0)/2.0;
  const double dmax = ptransition + 0.6*nm;
  double zmax = 2*diameter+dmax+2*nm;
  double ymax = 2*diameter+dmax+2*nm;

  char *datname = new char[1024];
  snprintf(datname, 1024, "papers/water-saft/figs/four-rods-in-water-%04.1fnm.dat", diameter/nm);
  
  FILE *o = fopen(datname, "w");
  delete[] datname;

  Functional f = OfEffectivePotential(WaterSaft(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, 0));
  double n_1atm = pressure_to_density(f, new_water_prop.kT, atmospheric_pressure,
                                      0.001, 0.01);

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

  f = OfEffectivePotential(WaterSaft(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, mu_satp));
  
  const double EperVolume = f(new_water_prop.kT, -new_water_prop.kT*log(n_1atm));
  const double EperCell = EperVolume*(zmax*ymax - 4*0.25*M_PI*diameter*diameter)*width;

  //Functional X = Xassociation(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);
  
  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));
  //dmax, dstep already in bohrs (so it doesn't need to be converted from nm)
  double dstep = 0.25*nm;
  for (distance=0.0*nm; distance<=dmax; distance += dstep) {

    if ((distance >= ptransition - 0.5*nm) && (distance <= ptransition + 0.05*nm)) {
      if (distance >= ptransition - 0.25*nm) {
        dstep = 0.03*nm;
      } else {
        dstep = 0.08*nm;
      }
    } else {
      dstep = 0.25*nm;
    }

    Lattice lat(Cartesian(width,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax));
    GridDescription gd(lat, 0.2);
    printf("Grid is %d x %d x %d\n", gd.Nx, gd.Ny, gd.Nz);
    Grid potential(gd);
    Grid constraint(gd);
    constraint.Set(notinwall);
    
    f = OfEffectivePotential(WaterSaft(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, mu_satp));
    f = constrain(constraint, f);
    
    printf("Diameter is %g bohr (%g nm)\n", diameter, diameter/nm);
    printf("Distance between rods = %g bohr (%g nm)\n", distance, distance/nm);


    potential = new_water_prop.liquid_density*constraint
      + 400*new_water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz);
    //potential = new_water_prop.liquid_density*VectorXd::Ones(gd.NxNyNz);
    potential = -new_water_prop.kT*potential.cwise().log();

    const double surface_tension = 5e-5; // crude guess from memory...
    const double surfprecision = 1e-5*(4*M_PI*diameter)*width*surface_tension; // five digits accuracy
    const double bulkprecision = 1e-12*fabs(EperCell); // but there's a limit on our precision for small rods
    const double precision = bulkprecision + surfprecision;
    printf("Precision limit from surface tension is to %g based on %g and %g\n",
           precision, surfprecision, bulkprecision);
    Minimizer min = Precision(precision, PreconditionedConjugateGradient(f, gd, new_water_prop.kT,
                                                                     &potential,
                                                                     QuadraticLineMinimizer));
    const int numiters = 200;
    for (int i=0;i<numiters && min.improve_energy(false);i++) {
      fflush(stdout);
      // {
      //   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 potential2(gd);
    Grid constraint2(gd);
    constraint2.Set(notinmiddle);

    potential2 = new_water_prop.liquid_density*(constraint2.cwise()*constraint)
      + 400*new_water_prop.vapor_density*VectorXd::Ones(gd.NxNyNz);
    potential2 = -new_water_prop.kT*potential2.cwise().log();

    Minimizer min2 = Precision(1e-12, PreconditionedConjugateGradient(f, gd, new_water_prop.kT,
                                                                     &potential2,
                                                                     QuadraticLineMinimizer));
    for (int i=0;i<numiters && min2.improve_energy(false);i++) {
      fflush(stdout);
      // {
      //   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);
      // }
    }
    char *plotnameslice = new char[1024];
    snprintf(plotnameslice, 1024, "papers/water-saft/figs/four-rods-%04.1f-%04.2f.dat", diameter/nm, distance/nm);

    printf("The bulk energy per cell should be %g\n", EperCell);
    double energy;
    if (min.energy() < min2.energy()) {
      energy = (min.energy() - EperCell)/width;
      Grid density(gd, EffectivePotentialToDensity()(new_water_prop.kT, gd, potential));
      printf("Using liquid in middle initially.\n");
      plot_grids_yz_directions(plotnameslice, density);

      {
        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);
      }

    } else {
      energy = (min2.energy() - EperCell)/width;
      Grid density(gd, EffectivePotentialToDensity()(new_water_prop.kT, gd, potential2));
      printf("Using vapor in middle initially.\n");    
      plot_grids_yz_directions(plotnameslice, density);

      {
        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);
      }

    }
    
    printf("Liquid energy is %.15g. Vapor energy is %.15g\n", min.energy(), min2.energy());

    fprintf(o, "%g\t%.15g\n", distance/nm, energy);

    //Grid entropy(gd, S(new_water_prop.kT, potential));
    //Grid Xassoc(gd, X(new_water_prop.kT, density));
    //plot_grids_y_direction(plotnameslice, density, energy_density, entropy, Xassoc);
    //Grid energy_density(gd, f(new_water_prop.kT, gd, potential));    
    delete[] plotnameslice;
  }
  fclose(o);

  {
    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);
  }
}
Пример #25
0
int main(int, char **argv) {
  const double kT = 1e-3;
  Lattice lat(Cartesian(0,5,5), Cartesian(5,0,5), Cartesian(5,5,0));
  Cartesian plotcorner(-5, -5, 0), plotx(10,0,0), ploty(0,10,0);
  int resolution = 200;
  GridDescription gd(lat, resolution, resolution, resolution);
  Grid foo(gd), bar(gd), ref(gd);
  printf("Running Set(gaussian)...\n");
  foo.Set(gaussian);
  const double integrate_foo = Identity().integral(kT, foo);
  printf("Original integrates to %.15g\n", integrate_foo);
  printf("Original Maximum is %g\n", foo.maxCoeff());
  int retval = 0;
  if (integrate_foo < 0) {
    printf("Integral of original is negative (which may throw off tests):  %g\n", integrate_foo);
    retval++;
  }
  //mkdir("tests/vis", 0777);
  //foo.epsNativeSlice("tests/vis/unblurred.eps", plotx, ploty, plotcorner);

  printf("Running Gaussian(10)...\n");
  bar = Gaussian(10)(kT, foo);
  printf("Gaussian(10) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs(Identity().integral(kT, bar)/integrate_foo-1) > 1e-6) {
    printf("Error in Gaussian(10) is too large:  %g\n", Identity().integral(kT, bar)/integrate_foo-1);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/gaussian-width-10.eps", plotx, ploty, plotcorner);

  printf("Gaussian(1) integrates to %g\n", Identity().integral(kT, bar));
  printf("Running Gaussian(1)...\n");
  bar = Gaussian(1)(kT, foo);
  if (fabs(Identity().integral(kT, bar)/integrate_foo-1) > 1e-6) {
    printf("Error in Gaussian(1) is too large:  %g\n", Identity().integral(kT, bar)/integrate_foo-1);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/gaussian-width-1.eps", plotx, ploty, plotcorner);

  printf("Running StepConvolve(1)...\n");
  bar = StepConvolve(1)(kT, foo);
  printf("StepConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("StepConvolve(1) Maximum is %g\n", bar.maxCoeff());
  if (fabs(bar.maxCoeff()/integrate_foo-1) > 1e-6) {
    printf("FAIL: Max of StepConvolve(1) is wrong:  %g\n", bar.maxCoeff()/integrate_foo - 1);
    retval++;
  }
  printf("StepConvolve(1) Minimum is %g\n", bar.minCoeff());
  if (bar.minCoeff()/integrate_foo < -1e-9) {
    printf("Min of StepConvolve(1) is wrong:  %g\n", bar.minCoeff()/integrate_foo);
    retval++;
  }
  const double fourpiover3 = 4*M_PI/3;
  if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpiover3)/fourpiover3) > 1e-6) {
    printf("Integral of StepConvolve(1) is wrong:  %g\n",
           (Identity().integral(kT, bar)/integrate_foo-fourpiover3)/fourpiover3);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/step-1.eps", plotx, ploty, plotcorner);

  printf("Running StepConvolve(2)...\n");
  bar = StepConvolve(2)(kT, foo);
  printf("StepConvolve(2) Maximum is %g\n", bar.maxCoeff());
  printf("StepConvolve(2) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpiover3*8)/fourpiover3/8) > 1e-6) {
    printf("Integral of StepConvolve(2) is wrong:  %g\n", (Identity().integral(kT, bar)/integrate_foo-fourpiover3*8)/fourpiover3/8);
    retval++;
  }
  if (fabs((bar.maxCoeff()-integrate_foo)/integrate_foo) > 1e-6) {
    printf("Max of StepConvolve(2) is wrong:  %g\n", (bar.maxCoeff()-integrate_foo)/integrate_foo);
    retval++;
  }
  printf("StepConvolve(2) Minimum is %g\n", bar.minCoeff());
  if (bar.minCoeff()/integrate_foo < -1e-9) {
    printf("Min of StepConvolve(2) is wrong:  %g\n", bar.minCoeff()/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/step-2.eps", plotx, ploty, plotcorner);

  printf("Running StepConvolve(3)...\n");
  bar = StepConvolve(3)(kT, foo);
  printf("StepConvolve(3) Maximum is %g\n", bar.maxCoeff());
  printf("StepConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpiover3*27)/fourpiover3/27) > 1e-6) {
    printf("Integral of StepConvolve(3) is wrong:  %g\n",
           (Identity().integral(kT, bar)/integrate_foo-fourpiover3*27)/fourpiover3/27);
    retval++;
  }
  if (fabs((bar.maxCoeff()-integrate_foo)/integrate_foo) > 1e-6) {
    printf("Max of StepConvolve(3) is wrong:  %g\n", (bar.maxCoeff()-integrate_foo)/integrate_foo);
    retval++;
  }
  printf("StepConvolve(3) Minimum is %g\n", bar.minCoeff());
  if (fabs(bar.minCoeff()/integrate_foo) < -1e-9) {
    printf("Min of StepConvolve(3) is wrong:  %g\n", bar.minCoeff()/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/step-3.eps", plotx, ploty, plotcorner);


  const double fourpi = 4*M_PI;
  printf("Running ShellConvolve(1)...\n");
  bar = ShellConvolve(1)(kT, foo);
  printf("ShellConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("ShellConvolve(1) Maximum is %g\n", bar.maxCoeff());
  if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpi)/fourpi) > 1e-6) {
    printf("Integral of ShellConvolve(1) is wrong:  %g\n",
           (Identity().integral(kT, bar)/integrate_foo-fourpi)/fourpi);
    retval++;
  }
  printf("ShellConvolve(1) Minimum is %g\n", bar.minCoeff());
  if (bar.minCoeff()/integrate_foo < -1e-9) {
    printf("Min of ShellConvolve(1) is wrong:  %g\n", bar.minCoeff()/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/shell-1.eps", plotx, ploty, plotcorner);


  printf("Running ShellPrimeConvolve(1)...\n");
  bar = ShellPrimeConvolve(1)(kT, foo);
  printf("ShellPrimeConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("ShellPrimeConvolve(1) Maximum is %g\n", bar.maxCoeff());
  //bar.epsNativeSlice("tests/vis/shellPrime-1.eps", plotx, ploty, plotcorner);

  printf("Running ShellConvolve(3)...\n");
  bar = ShellConvolve(3)(kT, foo);
  printf("ShellConvolve(3) Maximum is %g\n", bar.maxCoeff());
  printf("ShellConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs((Identity().integral(kT, bar)/integrate_foo-fourpi*9)/fourpi/9) > 1e-6) {
    printf("Integral of ShellConvolve(3) is wrong:  %g\n",
           (Identity().integral(kT, bar)/integrate_foo-fourpi*9)/fourpi/9);
    retval++;
  }
  printf("ShellConvolve(3) Minimum is %g\n", bar.minCoeff());
  if (bar.minCoeff()/integrate_foo < -1e-9) {
    printf("Min of ShellConvolve(3) is wrong:  %g\n", bar.minCoeff()/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/shell-3.eps", plotx, ploty, plotcorner);

  printf("Running yShellConvolve(1)...\n");
  bar = yShellConvolve(1)(kT, foo);
  printf("yShellConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("yShellConvolve(1) Maximum is %g\n", bar.maxCoeff());
  printf("yShellConvolve(1) Minimum is %g\n", bar.minCoeff());
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) {
    printf("Integral of yShellConvolve(1) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo-fourpi);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/y-shell-1.eps", plotx, ploty, plotcorner);
  Functional ysh = yShellConvolve(1), sh = ShellConvolve(1);
  {
    Grid scalarsh(gd, ShellConvolve(1)(kT, foo));
    if (bar.maxCoeff() > scalarsh.maxCoeff()) {
      printf("FAIL: max of vector shell greater than scalar shell!\n");
      retval++;
    }
    if (-bar.minCoeff() > scalarsh.maxCoeff()) {
      printf("FAIL: min of vector shell greater in magnitude than scalar shell!\n");
      retval++;
    }
  }

  printf("Running xShellConvolve(3)...\n");
  ref = ShellConvolve(3)(kT, foo);
  bar = xShellConvolve(3)(kT, foo);
  printf("xShellConvolve(3) Maximum is %g\n", bar.maxCoeff());
  printf("xShellConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) {
    printf("Integral of xShellConvolve(3) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo);
    retval++;
  }
  double mymax = ref.maxCoeff();
  if (fabs(bar.maxCoeff() - mymax)/mymax > 2e-3) {
    printf("problem with xShellConvolve max: %g != %g (error of %g)\n",
           bar.maxCoeff(), mymax, (bar.maxCoeff() - mymax)/mymax);
    retval++;
    exit(1);
  }
  if (fabs((bar.minCoeff() + mymax)/mymax) > 2e-3) {
    printf("problem with xShellConvolve min: %g != minus %g (error of %g)\n",
           bar.minCoeff(), mymax, (bar.minCoeff() + mymax)/mymax);
    retval++;
    exit(1);
  }
  //bar.epsNativeSlice("tests/vis/x-shell-3.eps", plotx, ploty, plotcorner);
  for (int i=0;i<gd.NxNyNz;i++) {
    if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-11) {
      printf("FAIL: x shell is bigger in magnitude than shell by %g out of %g compared with %g!\n",
             fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax);
      retval++;
    }
  }

  printf("Running VectorDensityX(3)...\n");
  ref = n2Density(3)(kT, foo);
  bar = VectorDensityX(3)(kT, foo);
  printf("VectorDensityX(3) Maximum is %g\n", bar.maxCoeff());
  printf("VectorDensityX(3) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) {
    printf("Integral of VectorDensityX(3) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/x-vector-3.eps", plotx, ploty, plotcorner);
  mymax = ref.maxCoeff();
  if (fabs(bar.maxCoeff() - mymax)/mymax > 2e-3) {
    printf("problem with VectorDensityX max: %g != %g (error of %g)\n",
           bar.maxCoeff(), mymax, (bar.maxCoeff() - mymax)/mymax);
    retval++;
    exit(1);
  }
  if (fabs((bar.minCoeff() + mymax)/mymax) > 2e-3) {
    printf("problem with VectorDensityX min: %g != minus %g (error of %g)\n",
           bar.minCoeff(), mymax, (bar.minCoeff() + mymax)/mymax);
    retval++;
    exit(1);
  }
  for (int i=0;i<gd.NxNyNz;i++) {
    if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-11) {
      printf("FAIL: x shell is bigger in magnitude than shell by %g out of %g compared with %g!\n",
             fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax);
      retval++;
    }
  }

  printf("Running xyShellConvolve(1)...\n");
  ref = xShellConvolve(1)(kT, foo);
  bar = xyShellConvolve(1)(kT, foo);
  printf("xyShellConvolve(1) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("xyShellConvolve(1) Maximum is %g\n", bar.maxCoeff());
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) {
    printf("Integral of xyShellConvolve(1) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo-fourpi);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/xy-shell-1.eps", plotx, ploty, plotcorner);
  mymax = ref.maxCoeff();
  for (int i=0;i<gd.NxNyNz;i++) {
    if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-11) {
      printf("FAIL: xy shell is bigger in magnitude than x shell by %g out of %g!\n",
             fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]));
      retval++;
    }
  }

  printf("Running xxShellConvolve(2)...\n");
  ref = xShellConvolve(2)(kT, foo).cwise().abs() + 1./3*ShellConvolve(2)(kT, foo);
  bar = xxShellConvolve(2)(kT, foo);
  printf("xxShellConvolve(2) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("xxShellConvolve(2) Maximum is %g\n", bar.maxCoeff());
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-14) {
    printf("FAIL: Integral of xxShellConvolve(2) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/xx-shell-2.eps", plotx, ploty, plotcorner);
  //bar.epsNativeSlice("tests/vis/xx-shell-2.eps", Cartesian(0,10,0), Cartesian(0,0,10), Cartesian(0,0,0));
  mymax = ref.maxCoeff();
  for (int i=0;i<gd.NxNyNz;i++) {
    if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-12) {
      printf("FAIL: xx shell is bigger in magnitude than x shell by %g out of %g compared with %g!\n",
             fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax);
      retval++;
    }
  }

  printf("Running TensorDensityXX(2)...\n");
  ref = VectorDensityX(2)(kT, foo).cwise().abs() + 1./3*n2Density(2)(kT, foo);
  bar = TensorDensityXX(2)(kT, foo);
  printf("TensorDensityXX(2) integrates to %.15g\n", Identity().integral(kT, bar));
  printf("TensorDensityXX(2) Maximum is %g\n", bar.maxCoeff());
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-14) {
    printf("FAIL: Integral of xxShellConvolve(2) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/xx-tensor-2.eps", plotx, ploty, plotcorner);
  mymax = ref.maxCoeff();
  double shellmax = n2Density(3)(kT, foo).maxCoeff();
  if (fabs(bar.maxCoeff() - 2*shellmax/3)/(2*shellmax/3) > 1e-2) {
    printf("problem with TensorDensityXX max: %g != %g (error of %g)\n",
           bar.maxCoeff(), 2*shellmax/3, (bar.maxCoeff() - 2*shellmax/3)/(2*shellmax/3));
    retval++;
    exit(1);
  }
  for (int i=0;i<gd.NxNyNz;i++) {
    if ((fabs(bar[i]) - fabs(ref[i]))/mymax > 1e-12) {
      printf("FAIL: xx shell is bigger in magnitude than x shell by %g out of %g compared with %g!\n",
             fabs(bar[i]) - fabs(ref[i]), fabs(ref[i]), mymax);
      retval++;
    }
  }
  printf("Running zxShellConvolve(3)...\n");
  Functional zxsh = zxShellConvolve(3);
  bar = zxsh(kT, foo);
  printf("zxShellConvolve(3) Maximum is %g\n", bar.maxCoeff());
  printf("zxShellConvolve(3) integrates to %.15g\n", Identity().integral(kT, bar));
  if (fabs(Identity().integral(kT, bar)/integrate_foo) > 1e-6) {
    printf("Integral of zxShellConvolve(3) is wrong:  %g\n",
           Identity().integral(kT, bar)/integrate_foo);
    retval++;
  }
  //bar.epsNativeSlice("tests/vis/zx-shell-3.eps", plotx, ploty, Cartesian(-5,-5,0.5));

  if (retval == 0) printf("\n%s passes!\n", argv[0]);
  else printf("\n%s fails %d tests!\n", argv[0], retval);
  return retval;
}
Пример #26
0
std::map<
    std::pair<std::pair<int, int>, std::pair<int, int>>,
    std::pair<Cartesian, Cartesian>> TileGraphicTextCache::buildPositionCache(
        double borderFraction, TileTextAlignment tileTextAlignment) {

    // The tile graphic text could look like either of the following, depending
    // on the layout, boarder, and max size
    //
    //                    col
    //     *-*---------------------------*-*    *-*---------------------------*-*
    //     *-*--------------------------[B]*    *-*--------------------------[B]*
    //     | |                           | |    | |                           | |
    //     | |   *------------------[D]  | |    | |   *------------------[D]  | |
    //     | |   |    |    |    |    |   | |    | |   |                   |   | |
    //     | |   |    |    |    |    |   | |    | |   |                   |   | |
    //     | |   |    | 00 | 01 |    |   | |    | |   |----|----|----|----|   | |
    // row | |   |    |____|____|    |   | | or | |   |    |    |    |    |   | |
    //     | |   |    |    |    |    |   | |    | |   | 00 | 01 | 02 | 03 |   | |
    //     | |   |    |    |    |    |   | |    | |  [E]---|----|----|----|   | |
    //     | |   |    | 10 | 11 |    |   | |    | |   |                   |   | |
    //     | |   |    |    |    |    |   | |    | |   |                   |   | |
    //     | |  [C]--[E]-------------*   | |    | |  [C]------------------*   | |
    //     | |                           | |    | |                           | |
    //     *[A]--------------------------*-*    *[A]--------------------------*-*
    //     *-*---------------------------*-*    *-*---------------------------*-*

    std::map<
        std::pair<std::pair<int, int>, std::pair<int, int>>,
        std::pair<Cartesian, Cartesian>> positionCache;

    int maxRows = m_tileGraphicTextMaxSize.first;
    int maxCols = m_tileGraphicTextMaxSize.second;

    // First we get the unscaled diagonal
    Cartesian A = Cartesian(m_wallWidth / 2.0, m_wallWidth / 2.0);
    Cartesian B = A + Cartesian(m_wallLength, m_wallLength);
    Cartesian C = A + Cartesian(m_wallLength, m_wallLength) * borderFraction;
    Cartesian D = B - Cartesian(m_wallLength, m_wallLength) * borderFraction;
    Cartesian CD = D - C;

    // We assume that each character is twice as tall as it is wide, and we scale accordingly
    Meters characterWidth = CD.getX() / static_cast<double>(maxCols);
    Meters characterHeight = CD.getY() / static_cast<double>(maxRows);
    if (characterWidth * 2.0 < characterHeight) {
        characterHeight = characterWidth * 2.0;
    }
    else {
        characterWidth = characterHeight / 2.0;
    }

    // Now we get the scaled diagonal (note that we'll only shrink in at most one direction)
    Cartesian scalingOffset = Cartesian(
        (CD.getX() - characterWidth * maxCols) / 2.0,
        (CD.getY() - characterHeight * maxRows) / 2.0
    );
    Cartesian E = C + scalingOffset;

    // For all numbers of rows displayed
    for (int numRows = 0; numRows <= maxRows; numRows += 1) {

        // For all numbers of columns displayed
        for (int numCols = 0; numCols <= maxCols; numCols += 1) {

            // For each visible row and col
            for (int row = 0; row <= maxRows; row += 1) {
                for (int col = 0; col <= maxCols; col += 1) {

                    Cartesian LL = Cartesian(Meters(0), Meters(0));
                    Cartesian UR = Cartesian(Meters(0), Meters(0));

                    if (row < numRows && col < numCols) {

                        double rowOffset = 0.0;
                        if (ContainerUtilities::setContains(CENTER_STAR_ALIGNMENTS, tileTextAlignment)) {
                            rowOffset = static_cast<double>(maxRows - numRows) / 2.0;
                        }
                        else if (ContainerUtilities::setContains(UPPER_STAR_ALIGNMENTS, tileTextAlignment)) {
                            rowOffset = static_cast<double>(maxRows - numRows);
                        }

                        double colOffset = 0.0;
                        if (ContainerUtilities::setContains(STAR_CENTER_ALIGNMENTS, tileTextAlignment)) {
                            colOffset = static_cast<double>(maxCols - numCols) / 2.0;
                        }
                        else if (ContainerUtilities::setContains(STAR_RIGHT_ALIGNMENTS, tileTextAlignment)) {
                            colOffset = static_cast<double>(maxCols - numCols);
                        }

                        LL = Cartesian(
                            Meters(E.getX() + characterWidth * (col + colOffset)),
                            Meters(E.getY() + characterHeight * ((numRows - row - 1) + rowOffset))
                        );
                        UR = Cartesian(
                            Meters(E.getX() + characterWidth * (col + colOffset + 1)),
                            Meters(E.getY() + characterHeight * ((numRows - row - 1) + rowOffset + 1))
                        );
                    }

                    positionCache.insert(
                        std::make_pair(
                            std::make_pair(
                                // The number of rows/cols to be drawn
                                std::make_pair(numRows, numCols),
                                // The row and col of the current character
                                std::make_pair(row, col)
                            ),
                            // The lower left and upper right texture coordinate
                            std::make_pair(LL, UR)
                        )
                    );
                }
            }
        }
    }

    return positionCache;
}
Пример #27
0
int main(int, char **) {
    for (double eta = 0.3; eta < 0.35; eta += 0.1) {
        // Generates a data file for the pair distribution function, for filling fraction eta
        // and distance of first sphere from wall of z0. Data saved in a table such that the
        // columns are x values and rows are z1 values.
        printf("Now starting sphere_with_wall with eta = %g\n",eta);
        Lattice lat(Cartesian(width,0,0), Cartesian(0,width,0), Cartesian(0,0,width+2*spacing));
        GridDescription gd(lat, dx); //the resolution here dramatically affects our memory use

        Functional f = OfEffectivePotential(WB + IdealGas());
        double mu = find_chemical_potential(f, 1, eta/(4*M_PI/3));
        f = OfEffectivePotential(WB + IdealGas()
                                 + ChemicalPotential(mu));

        Grid potential(gd);
        Grid constraint(gd);

        constraint.Set(*notinwall_or_sphere);
        constraint.epsNativeSlice("myconstraint.eps",
                                  Cartesian(0, 0, 2*(width+2*spacing)),
                                  Cartesian(2*width, 0, 0),
                                  Cartesian(0, 0, 0));

        f = constrain(constraint, f);

        potential = (eta*constraint + 1e-4*eta*VectorXd::Ones(gd.NxNyNz))/(4*M_PI/3);
        potential = -potential.cwise().log();

        const double approx_energy = (WB + IdealGas() + ChemicalPotential(mu))(1, eta/(4*M_PI/3))*dw*dw*width;
        const double precision = fabs(approx_energy*1e-4);
        //printf("Minimizing to %g absolute precision...\n", precision);
        Minimizer min = Precision(precision,
                                  PreconditionedConjugateGradient(f, gd, 1,
                                          &potential,
                                          QuadraticLineMinimizer));
        {
            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);
        }

        for (int i=0; min.improve_energy(true) && i<100; 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);
        }
        Grid density(gd, EffectivePotentialToDensity()(1, gd, potential));

        char *plotname = new char[1024];
        sprintf(plotname, "papers/pair-correlation/figs/walls/wallsWB-sphere-dft-%04.2f.dat", eta);
        pair_plot(plotname, density);
        delete[] plotname;

        char *plotname_path = new char[1024];
        sprintf(plotname_path, "papers/pair-correlation/figs/walls/wallsWB-sphere-dft-path-%04.2f.dat", eta);
        path_plot(plotname_path, density, constraint);
        delete[] plotname_path;
        fflush(stdout);
        {
            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);
        }
        fflush(stdout);
    }
    fflush(stdout);
    // Just create this file so make knows we have run.
    if (!fopen("papers/pair-correlation/figs/walls_sphere.dat", "w")) {
        printf("Error creating walls.dat!\n");
        return 1;
    }
    fflush(stdout);
    return 1;
}
Пример #28
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)));
}
Пример #29
0
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)));
}
Пример #30
0
int main(int, char **argv) {
  {
    // Here I set this test to continue running on its current cpu.
    // This is a slightly hokey trick to try to avoid any timings
    // variation due to NUMA and the process bouncing from one CPU to
    // another.  Ideally we'd figure out a better way to decide on
    // which CPU to use for real jobs.
    cpu_set_t cpus;
    CPU_ZERO(&cpus);
    CPU_SET(sched_getcpu(), &cpus);
    int err = sched_setaffinity(0, sizeof(cpu_set_t), &cpus);
    if (err != 0) {
      printf("Error from sched_setaffinity: %d\n", err);
    }
  }
  // Let's figure out which machine we're running on (since we only
  // want to test CPU time if we have timings for this particular
  // machine).
  gethostname(hn, 80);

  const double kT = hughes_water_prop.kT; // room temperature in Hartree
  const double eta_one = 3.0/(4*M_PI*R*R*R);
  const double nliquid = 0.324*eta_one;
  Functional n = EffectivePotentialToDensity();
  const double mu = find_chemical_potential(HardSpheres(R)(n) + IdealGasOfVeff(), kT, nliquid);

  // Here we set up the lattice.
  const double rmax = rcav*2;
  Lattice lat(Cartesian(0,rmax,rmax), Cartesian(rmax,0,rmax), Cartesian(rmax,rmax,0));
  //Lattice lat(Cartesian(1.4*rmax,0,0), Cartesian(0,1.4*rmax,0), Cartesian(0,0,1.4*rmax));
  GridDescription gd(lat, 0.2);

  last_time = get_time();
  Grid external_potential(gd);
  // Do some pointless stuff so we can get some sort of gauge as to
  // how fast this CPU is, for comparison with other tests.
  for (int i=0; i<10; i++) {
    // Do this more times, to get a more consistent result...
    external_potential = external_potential.Ones(gd.NxNyNz);
    external_potential = external_potential.cwise().exp();
    external_potential = 13*external_potential + 3*external_potential.cwise().square();
    external_potential.fft(); // compute and toss the fft...
  }
  // And now let's set the external_potential up as we'd like it.
  external_potential.Set(incavity);
  external_potential *= 1e9;
  check_peak("Setting", "external potential", NULL, 7, 8);

  Grid constraint(gd);
  constraint.Set(notincavity);
  //Functional f1 = f0 + ExternalPotential(external_potential);
  Functional ff = constrain(constraint, IdealGasOfVeff() + (HardSpheres(R) + ChemicalPotential(mu))(n));
  
  Grid potential(gd, external_potential + 0.005*VectorXd::Ones(gd.NxNyNz));

  double eps = hughes_water_prop.epsilonAB;
  double kappa = hughes_water_prop.kappaAB;

  ff = OfEffectivePotential(SaftFluid2(R, eps, kappa, hughes_water_prop.epsilon_dispersion,
                                       hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, mu));
  check_a_functional("SaftFluid2", ff, potential);

  //ff = OfEffectivePotential(SaftFluid(R, eps, kappa, hughes_water_prop.epsilon_dispersion,
  //                                    hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, mu));
  //check_a_functional("SaftFluid", ff, potential);

  //ff = Association2(R, eps, kappa, hughes_water_prop.epsilon_dispersion,
  //                  hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling);
  //check_a_functional("Association2", ff, potential);

  //ff = Association(R, eps, kappa, hughes_water_prop.epsilon_dispersion,
  //                 hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling);
  //check_a_functional("Association", ff, potential);

  //ff = Dispersion2(R, hughes_water_prop.epsilon_dispersion,
  //                 hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling);
  //check_a_functional("Dispersion2", ff, potential);

  //ff = Dispersion(R, hughes_water_prop.epsilon_dispersion,
  //                hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling);
  //check_a_functional("Dispersion", ff, potential);

  ff = constrain(constraint, (HardSpheresWBnotensor(R) + ChemicalPotential(mu))(n) + IdealGasOfVeff());
  check_a_functional("HardSpheresWBnotensor", ff, potential);

  //ff = constrain(constraint, (HardSpheresNoTensor(R) + ChemicalPotential(mu))(n) + IdealGasOfVeff());
  //check_a_functional("HardSphereNoTensor", ff, potential);

  ff = constrain(constraint, (HardSpheresNoTensor2(R) + ChemicalPotential(mu))(n) + IdealGasOfVeff());
  check_a_functional("HardSpheresNoTensor2", ff, potential);

  if (numoops == 0) {
    printf("\n%s has no oopses!\n", argv[0]);
  } else {
    printf("\n%s sort of fails %d tests!\n", argv[0], numoops);
  }
  if (retval == 0) {
    printf("\n%s passes!\n", argv[0]);
  } else {
    printf("\n%s fails %d tests!\n", argv[0], retval);
    return retval;
  }
}