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 }
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); }
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 }
void TForm2::testMinimize() { double *params = new1D(2, 0.0); MinimizerFunction *mf = new MinimizerFunction(params, 2); Minimizer *m = new Minimizer(mf); m->DoMinimize(); double* pOut = mf->getParameters(); p1Edit->Text = UnicodeString(pOut[0]); p2Edit->Text = UnicodeString(pOut[1]); delete m; delete mf; delete1D(params); }
bool ConjugateGradientType::improve_energy(bool verbose) { iter++; //printf("I am running ConjugateGradient::improve_energy\n"); const double E0 = energy(); if (E0 != E0) { // There is no point continuing, since we're starting with a NaN! // So we may as well quit here. if (verbose) { printf("The initial energy is a NaN, so I'm quitting early from ConjugateGradientType::improve_energy.\n"); f.print_summary("has nan:", E0); fflush(stdout); } return false; } double gdotd; { const VectorXd g = -grad(); // Let's immediately free the cached gradient stored internally! invalidate_cache(); // Note: my notation vaguely follows that of // [wikipedia](http://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method). // I use the Polak-Ribiere method, with automatic direction reset. // Note that we could save some memory by using Fletcher-Reeves, and // it seems worth implementing that as an option for // memory-constrained problems (then we wouldn't need to store oldgrad). double beta = g.dot(g - oldgrad)/oldgradsqr; oldgrad = g; if (beta < 0 || beta != beta || oldgradsqr == 0) beta = 0; oldgradsqr = oldgrad.dot(oldgrad); direction = g + beta*direction; gdotd = oldgrad.dot(direction); if (gdotd < 0) { direction = oldgrad; // If our direction is uphill, reset to gradient. if (verbose) printf("reset to gradient...\n"); gdotd = oldgrad.dot(direction); } } Minimizer lm = linmin(f, gd, kT, x, direction, -gdotd, &step); for (int i=0; i<100 && lm.improve_energy(verbose); i++) { if (verbose) lm.print_info("\t"); } if (verbose) { //lm->print_info(); print_info(); printf("grad*dir/oldgrad*dir = %g\n", grad().dot(direction)/gdotd); } return (energy() < E0); }
bool PreconditionedConjugateGradientType::improve_energy(bool verbose) { iter++; //printf("I am running ConjugateGradient::improve_energy\n"); const double E0 = energy(); if (isnan(E0)) { // There is no point continuing, since we're starting with a NaN! // So we may as well quit here. if (verbose) { printf("The initial energy is a NaN, so I'm quitting early.\n"); fflush(stdout); } return false; } double beta; { // Note: my notation vaguely follows that of // [wikipedia](http://en.wikipedia.org/wiki/Nonlinear_conjugate_gradient_method). // I use the Polak-Ribiere method, with automatic direction reset. // Note that we could save some memory by using Fletcher-Reeves, and // it seems worth implementing that as an option for // memory-constrained problems (then we wouldn't need to store oldgrad). pgrad(); // compute pgrad first, since that computes both. beta = -pgrad().dot(-grad() - oldgrad)/oldgradsqr; oldgrad = -grad(); if (beta < 0 || beta != beta || oldgradsqr == 0) beta = 0; if (verbose) printf("beta = %g\n", beta); oldgradsqr = -pgrad().dot(oldgrad); direction = -pgrad() + beta*direction; // Let's immediately free the cached gradient stored internally! invalidate_cache(); } // free g and pg! const double gdotd = oldgrad.dot(direction); Minimizer lm = linmin(f, gd, kT, x, direction, -gdotd, &step); for (int i=0; i<100 && lm.improve_energy(verbose); i++) { if (verbose) lm.print_info("\t"); } if (verbose) { //lm->print_info(); print_info(); printf("grad*oldgrad = %g\n", grad().dot(direction)/gdotd); } return (energy() < E0 || beta != 0); }
int main (int argc, char ** argv) { H.init ("Test: circle packing", argc, argv, "s=4"); Map m (13); m << Edge(0,1) << Edge(0,3) << Edge(0,5) << Edge(1,2) << Edge(1,4) << Edge(1,6) << Edge(1,3) << Edge(1,0) << Edge(2,7) << Edge(2,4) << Edge(2,1) << Edge(3,0) << Edge(3,1) << Edge(3,6) << Edge(3,5) << Edge(4,1) << Edge(4,2) << Edge(4,7) << Edge(4,6) << Edge(5,0) << Edge(5,3) << Edge(5,6) << Edge(5,8) << Edge(5,10) << Edge(6,1) << Edge(6,4) << Edge(6,7) << Edge(6,9) << Edge(6,11) << Edge(6,8) << Edge(6,5) << Edge(6,3) << Edge(7,12) << Edge(7,9) << Edge(7,6) << Edge(7,4) << Edge(7,2) << Edge(8,5) << Edge(8,6) << Edge(8,11) << Edge(8,10) << Edge(9,6) << Edge(9,7) << Edge(9,12) << Edge(9,11) << Edge(10,5) << Edge(10,8) << Edge(10,11) << Edge(11,10) << Edge(11,8) << Edge(11,6) << Edge(11,9) << Edge(11,12) << Edge(12,11) << Edge(12,9) << Edge(12,7); for (int i=0; i<int(H['s']); ++i) m.barycentric(); m.inscribe(m.face(Edge(1,m.v[1]->adj.back()))); m.balance(); m.show(); Vector<double> x(3*m.n); double r = 1.0/sqrt(m.n); for (int i=0; i<m.n; ++i) { x[3*i] = m.v[i]->z.real() / (1-r); x[3*i+1] = m.v[i]->z.imag() / (1-r); x[3*i+2] = .8*r; } Minimizer<double> MM (3*m.n, [&m](const Vector<double> &x, Vector<double> &g) { return Map_fg_circle_disk (x,g,&m); }); MM.cb = cb; MM.minimize_qn (x); x = MM.x; std::cerr << "Number of vertices: " << m.n << std::endl; std::cerr << "Final value of f: " << MM.fx << std::endl; std::cerr << "Final square gradient: " << inner_prod(MM.gx,MM.gx) << std::endl; for (int i=0; i<m.n; ++i) { m.v[i]->z = cpx (x[3*i], x[3*i+1]); m.v[i]->r = x[3*i+2]; } Figure f; m.plot_circles(f); f.add (new Circle(cpx(0.0,0.0),1.0)); f.show(); f.pause(); f.output (); }
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; }
int main() { // MPI int my_rank = 0; #ifdef RUN_MPI MPI_Init(NULL, NULL); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); #endif string run = "O2"; clock_t begin = clock(); if (run == "CH4_potential"){ double d0 = 1.0910338084437818; // gives 1 ånsgtrøm bond length double dexp = 1.086*d0; // experimental value rowvec posC = {0.0, 0.0, 0.0}; rowvec posH1 = {d0, d0, d0}; rowvec posH2 = {-dexp, -dexp, dexp}; rowvec posH3 = {dexp, -dexp, -dexp}; rowvec posH4 = {-dexp, dexp, -dexp}; rowvec charges = {6.0, 1.0, 1.0, 1.0, 1.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(5,3); nucleiPositions.row(0) = posC; nucleiPositions.row(1) = posH1; nucleiPositions.row(2) = posH2; nucleiPositions.row(3) = posH3; nucleiPositions.row(4) = posH4; BasisFunctions *basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/C_631Gs.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gs.dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gs.dat", 2); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gs.dat", 3); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gs.dat", 4); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UHF solver(system); double dmin = 0.8*d0; double dmax = 4.6*d0; double delta = 0.025*d0; double d = dmin; ofstream ofile; if (my_rank == 0){ ofile.open("../../Results/CH4_potential/UHF_spin_631Gs.dat"); ofile << "Basis set: 6-31G*" << endl; ofile << "Distance (a.u.) <S^2>" << endl; } while (d < dmax){ posH1 = {d, d, d}; nucleiPositions.row(1) = posH1; system->setNucleiPositions(nucleiPositions); solver.solve(); if (my_rank == 0){ ofile << d*sqrt(3) << " "; ofile << solver.getSpinExpectation() << endl; } d += delta; } } else if (run == "CH4"){ double d = 1.1835680518387328; rowvec posC = {0.0, 0.0, 0.0}; rowvec posH1 = {d, d, d}; rowvec posH2 = {-d, -d, d}; rowvec posH3 = {d, -d, -d}; rowvec posH4 = {-d, d, -d}; rowvec charges = {6.0, 1.0, 1.0, 1.0, 1.0}; int nElectrons = 9; mat nucleiPositions = zeros<mat>(5,3); nucleiPositions.row(0) = posC; nucleiPositions.row(1) = posH1; nucleiPositions.row(2) = posH2; nucleiPositions.row(3) = posH3; nucleiPositions.row(4) = posH4; BasisFunctions *basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/C_631Gss.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 2); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 3); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 4); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UHF solver(system); solver.solve(); if (my_rank == 0){ cout << "Energy: " << setprecision(9) << solver.getEnergy() << endl; //cout << "Orbital energies: " << solver.getFockEnergy()(0) << endl; } } else if (run == "CN"){ double d = 2.333811596; rowvec posC = {-d/2, 0.0, 0.0}; rowvec posN = {d/2, 0.0, 0.0}; rowvec charges = {6.0, 7.0}; int nElectrons = 13; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posC; nucleiPositions.row(1) = posN; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/C_STO3G.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/N_STO3G.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UMP solver(system,3,4); solver.solve(); if (my_rank == 0){ cout << setprecision(7) << solver.getEnergy() << endl; } } else if (run == "NH4"){ double d = 1.1150365517919136; rowvec posN = {0.0, 0.0, 0.0}; rowvec posH1 = {d, d, d}; rowvec posH2 = {-d, -d, d}; rowvec posH3 = {d, -d, -d}; rowvec posH4 = {-d, d, -d}; rowvec charges = {7.0, 1.0, 1.0, 1.0, 1.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(5,3); nucleiPositions.row(0) = posN; nucleiPositions.row(1) = posH1; nucleiPositions.row(2) = posH2; nucleiPositions.row(3) = posH3; nucleiPositions.row(4) = posH4; BasisFunctions *basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/N_631++Gs.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631++Gss.dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631++Gss.dat", 2); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631++Gss.dat", 3); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631++Gss.dat", 4); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UMP solver(system,3,2); solver.solve(); if (my_rank == 0){ cout << "Energy: " << setprecision(10) << solver.getEnergyHF() + solver.getEnergy2order() + solver.getEnergy3order()<< endl; } } else if (run == "NH3"){ rowvec posN = {0.0, 0.0, 0.0}; rowvec posH1 = {1.7718820838495062, 0.0, 0.72111225265774803}; rowvec posH2 = {-0.88594104192475265, 1.5344948971241812, 0.72111225265774803}; rowvec posH3 = {-0.88594104192475265, -1.5344948971241812, 0.72111225265774803}; rowvec charges = {7.0, 1.0, 1.0, 1.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(4,3); nucleiPositions.row(0) = posN; nucleiPositions.row(1) = posH1; nucleiPositions.row(2) = posH2; nucleiPositions.row(3) = posH3; BasisFunctions *basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/N_631Gss.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 2); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 3); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); RHF solver(system); solver.solve(); if (my_rank == 0){ cout << "Energy: " << solver.getEnergy() << endl; cout << "Orbital energies: " << solver.getFockEnergy()(0) << endl; } } else if (run == "CH3"){ double d = 2.0273; double s = sin(2*M_PI/3); double c = cos(2*M_PI/3); rowvec posC = {0.0, 0.0, 0.0}; rowvec posH1 = {d, 0.0, 0.0}; rowvec posH2 = {c*d, s*d, 0.0}; rowvec posH3 = {c*d, -s*d, 0.0}; rowvec charges = {6.0, 1.0, 1.0, 1.0}; int nElectrons = 9; mat nucleiPositions = zeros<mat>(4,3); nucleiPositions.row(0) = posC; nucleiPositions.row(1) = posH1; nucleiPositions.row(2) = posH2; nucleiPositions.row(3) = posH3; BasisFunctions *basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/C_6311++G(3df,3pd).dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_6311++G(3df,3pd).dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_6311++G(3df,3pd).dat", 2); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_6311++G(3df,3pd).dat", 3); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UHF solver(system); cout << "Hey2" << endl; solver.solve(); if (my_rank == 0){ cout << "Energy: " << setprecision(10) << solver.getEnergy()<< endl; cout << "S: " << solver.getSpinExpectation() << endl; } } else if (run == "H2O"){ rowvec posO = {0.0, 0.0, 0.0}; rowvec posH1 = {1.809, 0.0, 0.0}; rowvec posH2 = {-0.45354874635597853, 1.7512208697588434, 0.0}; rowvec charges = {8.0, 1.0, 1.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(3,3); nucleiPositions.row(0) = posO; nucleiPositions.row(1) = posH1; nucleiPositions.row(2) = posH2; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/O_631Gss.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 2); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); RHF solver(system); solver.solve(); if (my_rank == 0){ cout << "Energy: " << solver.getEnergy() << endl; cout << "Orbital energies: " << solver.getFockEnergy()(0) << endl; } } else if (run =="H2"){ double d = 3.779451977; rowvec posH1 = {-d/2, 0.0, 0.0}; rowvec posH2 = {d/2, 0.0, 0.0}; rowvec charges = {1.0, 1.0}; int nElectrons = 2; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posH1; nucleiPositions.row(1) = posH2; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_STO3G.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_STO3G.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UHF solver(system); solver.solve(); if (my_rank == 0){ cout << "Energy: " << solver.getEnergy() << endl; // field<mat> C = solver.getCoeff(); // rowvec R1 = {-6.0, -3.0, -3.0}; // rowvec R2 = {6.0, 3.0, 3.0}; // double dx = 8.0/100; // Density density(basisFunctions, R1, R2, dx, dx, dx); // density.printMolecularOrbital(C, 1,"../../Results/H2_potential/orbitals_d2p0/orbital2_UHF.dat"); } } else if (run == "H2_potential") { rowvec charges = {1.0, 1.0}; int nElectrons = 2; mat nucleiPositions = zeros<mat>(2,3); BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_STO3G.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_STO3G.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UMP solver(system, 3); double dmin = 0.5; double dmax = 6.0; int nPoints = 551; double delta = (dmax - dmin)/(nPoints-1); double d, energy; rowvec3 posH1, posH2; ofstream ofile; ofile.open("../../Results/H2_potential/UHF_631Gsstest.dat"); ofile << "Basis set: 6-31G**" << endl; ofile << "Distance UHF UMP2 UMP3" << endl; for (int i = 0; i < nPoints; i++){ d = dmin + i*delta; posH1 = {-d/2, 0, 0}; posH2 = {d/2, 0, 0}; nucleiPositions.row(0) = posH1; nucleiPositions.row(1) = posH2; system->setNucleiPositions(nucleiPositions); solver.solve(); ofile << d << " "; energy = solver.getEnergyHF(); ofile << setprecision(10) << energy << " "; energy += solver.getEnergy2order(); ofile << setprecision(10) << energy << " "; energy += solver.getEnergy3order(); ofile << setprecision(10) << energy << endl; } } else if (run == "HF"){ double d0 = 1.733; rowvec posH = {-0.5*d0, 0.0, 0.0}; rowvec posF= {0.5*d0, 0.0, 0.0}; rowvec charges = {1.0, 9.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posH; nucleiPositions.row(1) = posF; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/F_631Gss.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); RHF solver(system); solver.solve(); if (my_rank == 0){ cout << "Energy: " << solver.getEnergy() << endl; cout << "Orbital energies: " << solver.getFockEnergy()(0) << endl; } } else if (run == "HF_potential") { double d0 = 1.889725989; // 1 ångstrøm rowvec posH = {-0.5*d0, 0.0, 0.0}; rowvec posF= {0.5*d0, 0.0, 0.0}; rowvec charges = {1.0, 9.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posH; nucleiPositions.row(1) = posF; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_631Gss.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/F_631Gss.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); UHF solver(system); double dmin = 0.7*d0; double dmax = 3.7*d0; double delta = 0.025*d0; double d = dmin; ofstream ofile; if (my_rank == 0){ ofile.open("../../Results/FH_potential/UHF_spin_631Gss.dat"); ofile << "Basis set: 6-31G**" << endl; ofile << "Distance (a.u.) <S^2>" << endl; } while (d <= dmax){ posH = {-0.5*d, 0.0, 0.0}; posF = {0.5*d, 0.0, 0.0}; nucleiPositions.row(0) = posH; nucleiPositions.row(1) = posF; system->setNucleiPositions(nucleiPositions); solver.solve(); if (my_rank == 0){ ofile << d << " "; ofile << solver.getSpinExpectation() << endl; } d += delta; } delete system; delete basisFunctions; } else if (run =="O2") { double d = 2.282; rowvec posO1 = {-0.5*d, 0.0, 0.0}; rowvec posO2= {0.5*d, 0.0, 0.0}; rowvec charges = {8.0, 8.0}; int nElectronsUp = 9; int nElectronsDown = 7; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posO1; nucleiPositions.row(1) = posO2; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/O_631Gs.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/O_631Gs.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectronsUp, nElectronsDown); UHF solver(system); solver.solve(); if (my_rank == 0){ cout << "Energy: " << setprecision(9) << solver.getEnergy() << endl; cout << "Spin-up orbital energies: " << solver.getFockEnergy()(0) << endl; cout << "Spin-down orbital energies: " << solver.getFockEnergy()(1) << endl; // rowvec3 R1 = {-3.0, -3.0, -3.0}; // rowvec3 R2 = -R1; // double dx = 0.06; // Density density(basisFunctions, R1, R2, dx, dx, dx); // density.printMolecularOrbital(solver.getCoeff(), 0, "../../Results/O2_orbs/1_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 1, "../../Results/O2_orbs/2_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 2, "../../Results/O2_orbs/3_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 3, "../../Results/O2_orbs/4_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 4, "../../Results/O2_orbs/5_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 5, "../../Results/O2_orbs/6_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 6, "../../Results/O2_orbs/7_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 7, "../../Results/O2_orbs/8_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 8, "../../Results/O2_orbs/9_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 9, "../../Results/O2_orbs/10_up.dat",0); // density.printMolecularOrbital(solver.getCoeff(), 10, "../../Results/O2_orbs/11_up.dat",0); } delete system; delete basisFunctions; } else if (run == "N2"){ double d = 2.116115162; rowvec posN1 = {-0.5*d, 0.0, 0.0}; rowvec posN2= {0.5*d, 0.0, 0.0}; rowvec charges = {7.0, 7.0}; int nElectrons = 14; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posN1; nucleiPositions.row(1) = posN2; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/N_6311Gs.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/N_6311Gs.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); RMP solver(system,2); solver.solve(); if (my_rank == 0){ cout << "Energy: " << setprecision(9) << solver.getEnergyHF() + solver.getEnergy2order() + solver.getEnergy3order() << endl; } delete system; delete basisFunctions; } else if (run == "FCl") { double d = 3.154519593; rowvec posF = {-0.5*d, 0.0, 0.0}; rowvec posCl= {0.5*d, 0.0, 0.0}; rowvec charges = {9.0, 17.0}; int nElectrons = 26; mat nucleiPositions = zeros<mat>(2,3); nucleiPositions.row(0) = posF; nucleiPositions.row(1) = posCl; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/F_6311Gs.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/Cl_6311Gs.dat", 1); System *system; system = new System(basisFunctions, nucleiPositions, charges, nElectrons); RMP solver(system,2); solver.solve(); if (my_rank == 0){ cout << "Energy: " << setprecision(9) << solver.getEnergyHF() + solver.getEnergy2order() << endl; } } else if (run == "H2O_Minimize"){ rowvec O = {0.0,0.0,0.0}; rowvec H1 = {1.0,0.0,0.0}; rowvec H2 = {0.0,1.0,0.0}; rowvec charges = {8.0,1.0,1.0}; int nElectrons = 10; mat nucleiPositions = zeros<mat>(3,3); nucleiPositions.row(0) = O; nucleiPositions.row(1) = H1; nucleiPositions.row(2) = H2; BasisFunctions* basisFunctions = new BasisFunctions; basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/O_431G.dat", 0); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_431G.dat", 1); basisFunctions->addContracteds("../../HartreeFock/inFiles/basisSets/H_431G.dat", 2); System *system = new System(basisFunctions, nucleiPositions, charges, nElectrons); RMP *solver = new RMP(system,1); HartreeFockFunc *func = new HartreeFockFunc(solver, system); Minimizer *minimizer = new Minimizer(func); minimizer->solve(); if (my_rank == 0){ cout << system->getNucleiPositions() << endl; cout << setprecision(7) << system->getNucleiPositions()(1,0) << endl; cout << "Energy min.: " << setprecision(14) << minimizer->getMinValue() << endl; cout << "Energy max.: " << setprecision(14) << minimizer->getMaxValue() << endl; } } else { if (my_rank == 0){ cout << "No valid run selected." << endl; } } clock_t end = clock(); if (my_rank == 0){ cout << "Elapsed time: "<< (double(end - begin))/CLOCKS_PER_SEC << endl; } #ifdef RUN_MPI MPI_Finalize(); #endif return 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))); }
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; }
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); }
int FitNullModel(Matrix& mat_Xnull, Matrix& mat_y, const EigenMatrix& kinshipU, const EigenMatrix& kinshipS){ // sanity check if (mat_Xnull.rows != mat_y.rows) return -1; if (mat_Xnull.rows != kinshipU.mat.rows()) return -1; if (mat_Xnull.rows != kinshipS.mat.rows()) return -1; // type conversion G_to_Eigen(mat_Xnull, &this->ux); G_to_Eigen(mat_y, &this->uy); this->lambda = kinshipS.mat; const Eigen::MatrixXf& U = kinshipU.mat; // rotate this->ux = U.transpose() * this->ux; this->uy = U.transpose() * this->uy; // get beta, sigma and delta // where delta = sigma2_e / sigma2_g double loglik[101]; int maxIndex = -1; double maxLogLik = 0; for (int i = 0; i <= 100; ++i ){ delta = exp(-10 + i * 0.2); getBetaSigma2(delta); loglik[i] = getLogLikelihood(delta); #ifdef DEBUG fprintf(stderr, "%d\tdelta=%g\tll=%lf\n", i, delta, loglik[i]); fprintf(stderr, "beta(0)=%lf\tsigma2=%lf\n", beta(0), sigma2); #endif if (std::isnan(loglik[i])) { continue; } if (maxIndex < 0 || loglik[i] > maxLogLik) { maxIndex = i; maxLogLik = loglik[i]; } } if (maxIndex < -1) { fprintf(stderr, "Cannot optimize\n"); return -1; } #if 0 fprintf(stderr, "maxIndex = %d\tll=%lf\t\tbeta(0)=%lf\tsigma2=%lf\n", maxIndex, maxLogLik, beta(0), sigma2); #endif if (maxIndex == 0 || maxIndex == 100) { // on the boundary // do not try maximize it. } else { gsl_function F; F.function = goalFunction; F.params = this; Minimizer minimizer; double lb = exp(-10 + (maxIndex-1) * 0.2); double ub = exp(-10 + (maxIndex+1) * 0.2); double start = exp(-10 + maxIndex * 0.2); if (minimizer.minimize(F, start, lb, ub)) { fprintf(stderr, "Minimization failed, fall back to initial guess.\n"); this->delta = start; } else { this->delta = minimizer.getX(); #ifdef DEBUG fprintf(stderr, "minimization succeed when delta = %g, sigma2 = %g\n", this->delta, this->sigma2); #endif } } // store some intermediate results #ifdef DEBUG fprintf(stderr, "delta = sigma2_e/sigma2_g, and sigma2 is sigma2_g\n"); fprintf(stderr, "maxIndex = %d, delta = %g, Try brent\n", maxIndex, delta); fprintf(stderr, "beta[0][0] = %g\t sigma2_g = %g\tsigma2_e = %g\n", beta(0,0), this->sigma2, delta * sigma2); #endif // if (this->test == MetaCov::LRT) { // this->nullLikelihood = getLogLikelihood(this->delta); // } else if (this->test == MetaCov::SCORE) { // this->uResid = this->uy - this->ux * this->beta; // } return 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; }
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); } }
int FitNullModel(Matrix& mat_Xnull, Matrix& mat_y, const EigenMatrix& kinshipU, const EigenMatrix& kinshipS){ // type conversion Eigen::MatrixXf x; Eigen::MatrixXf y; G_to_Eigen(mat_Xnull, &x); G_to_Eigen(mat_y, &y); this->lambda = kinshipS.mat; const Eigen::MatrixXf& U = kinshipU.mat; // rotate this->ux = U.transpose() * x; this->uy = U.transpose() * y; // get beta, sigma2_g and delta // where delta = sigma2_e / sigma2_g double loglik[101]; int maxIndex = -1; double maxLogLik = 0; for (int i = 0; i <= 100; ++i ){ double d = exp(-10 + i * 0.2); getBetaSigma2(d); loglik[i] = getLogLikelihood(d); // fprintf(stderr, "%d\tdelta=%g\tll=%lf\n", i, delta, loglik[i]); if (std::isnan(loglik[i])) { continue; } if (maxIndex < 0 || loglik[i] > maxLogLik) { maxIndex = i; maxLogLik = loglik[i]; } } if (maxIndex < -1) { fprintf(stderr, "Cannot optimize\n"); return -1; } if (maxIndex == 0 || maxIndex == 100) { // on the boundary // do not try maximize it. } else { gsl_function F; F.function = goalFunction; F.params = this; Minimizer minimizer; double lb = exp(-10 + (maxIndex-1) * 0.2); double ub = exp(-10 + (maxIndex+1) * 0.2); double start = exp(-10 + maxIndex * 0.2); if (minimizer.minimize(F, start, lb, ub)) { // fprintf(stderr, "Minimization failed, fall back to initial guess.\n"); this->delta = start; } else { this->delta = minimizer.getX(); // fprintf(stderr, "minimization succeed when delta = %g, sigma2_g = %g\n", this->delta, this->sigma2_g); } } // store some intermediate results // fprintf(stderr, "maxIndex = %d, delta = %g, Try brent\n", maxIndex, delta); // fprintf(stderr, "beta[%d][%d] = %g\n", (int)beta.rows(), (int)beta.cols(), beta(0,0)); this->h2 = 1.0 /(1.0 + this->delta); this->sigma2 = this->sigma2_g * this->h2; // we derive different formular to replace original eqn (7) this->gamma = (this->lambda.array() / (this->lambda.array() + this->delta)).sum() / this->sigma2_g / (this->ux.rows() - 1 ) ; // fprintf(stderr, "gamma = %g\n", this->gamma); // transformedY = \Sigma^{-1} * (y_tilda) and y_tilda = y - X * \beta // since \Sigma = (\sigma^2_g * h^2 ) * (U * (\lambda + delta) * U') // transformedY = 1 / (\sigma^2_g * h^2 ) * (U * (\lambda+delta)^{-1} * U' * (y_tilda)) // = 1 / (\sigma^2_g * h^2 ) * (U * \lambda^{-1} * (uResid)) // since h^2 = 1 / (1+delta) // transformedY = (1 + delta/ (\sigma^2_g ) * (U * \lambda^{-1} * (uResid)) Eigen::MatrixXf resid = y - x * (x.transpose() * x).eval().ldlt().solve(x.transpose() * y); // this is y_tilda this->transformedY.noalias() = U.transpose() * resid; this->transformedY = (this->lambda.array() + this->delta).inverse().matrix().asDiagonal() * this->transformedY; this->transformedY = U * this->transformedY; this->transformedY /= this->sigma2_g; // fprintf(stderr, "transformedY(0,0) = %g\n", transformedY(0,0)); this->ySigmaY= (resid.array() * transformedY.array()).sum(); return 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))); }
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 }
void TForm2::testRigidFit() { int nPoints = 4; double aIn = .3; double bIn = .8; double gIn = .7; double xIn = 0; double yIn = 0; double zIn = 0; double sa = sin(aIn); double sb = sin(bIn); double sg = sin(gIn); double ca = cos(aIn); double cb = cos(bIn); double cg = cos(gIn); //rotation matrix double r00 = ca*cb; double r01 = ca*sb*sg - sa*cg; double r02 = ca*sb*cg + sa*sg; double r10 = sa*cb; double r11 = sa*sb*sg + ca*cg; double r12 = sa*sb*cg - ca*sg; double r20 = -sb; double r21 = cb*sg; double r22 = cb*cg; double **orig = new2D(nPoints, 3, 0.0); orig[0][0] = 0.0; orig[0][1] = 0.0; orig[0][2] = 0.0; orig[1][0] = 1.0; orig[1][1] = 0.0; orig[1][2] = 0.0; orig[2][0] = 0.0; orig[2][1] = 1.0; orig[2][2] = 0.0; orig[3][0] = 0.0; orig[3][1] = 0.0; orig[3][2] = 1.0; double **current = new2D(nPoints, 3, 0.0); for(int i=0; i<nPoints; i++) { double x = orig[i][0]; double y = orig[i][1]; double z = orig[i][2]; double tx = r00*x + r01*y + r02*z; double ty = r10*x + r11*y + r12*z; double tz = r20*x + r21*y + (r22)*z; current[i][0] = tx + xIn; current[i][1] = ty + yIn; current[i][2] = tz + zIn; printf("current[i][0]: %g\n", current[i][0]); printf("current[i][1]: %g\n", current[i][1]); printf("current[i][2]: %g\n\n", current[i][2]); } double **error = new2D(nPoints,3,1.0); double params[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; double *spread = new1D<double>(6, 0.0); spread[0] = 3.14/2.0; spread[1] = 3.14/2.0; spread[2] = 3.14/2.0; spread[3] = 1.0; spread[4] = 1.0; spread[5] = 1.0; RigidDeltaFunction *df = new RigidDeltaFunction(orig, current, error, nPoints, 3, params, 6); df->setStartingSpread(spread); Minimizer *m = new Minimizer(df); m->nmax = 1000; m->DoMinimize(); double* pOut = df->getParameters(); printf("a: %g\n", pOut[0]); printf("b: %g\n", pOut[1]); printf("g: %g\n", pOut[2]); printf("x0: %g\n", pOut[3]); printf("y0: %g\n", pOut[4]); printf("z0: %g\n", pOut[5]); delete2D(error, nPoints); delete2D(current, nPoints); delete2D(orig, nPoints); delete1D(spread); delete df; }
void TForm2::testEyeFit() { double monitorWidth = 326.0; //mm double monitorHeight = 260.0; //mm double cameraWidth = 352; //pixels double cameraHeight = 240; //pixels int nPoints = 0; /* FILE *fp = fopen("C:\\Users\\mgrivich\\data.csv", "r"); while(fgets(str,sizeof(str),fp) != NULL) { i++; } */ // rewind(fp); std::ifstream ifs; ifs.open ( "C:\\Users\\mgrivich\\data.csv"); // declare file stream: http://www.cplusplus.com/reference/iostream/ifstream/ string value; while (ifs.good()) { getline(ifs, value); nPoints++; } nPoints--; double **coords = new2D(nPoints, 2, 0.0); double **data = new2D(nPoints, 2, 0.0); double **error = new2D(nPoints,2,0.0); ifs.clear(); ifs.seekg(0); for(int i=0; i<nPoints; i++) { getline(ifs, value, ','); coords[i][0] = monitorWidth*((1000.0 - atof(value.c_str()))/1000.0); getline(ifs, value, ','); coords[i][1] = monitorHeight*((1000.0 - atof(value.c_str()))/1000.0); getline(ifs, value, ','); data[i][0] = atof(value.c_str())-cameraWidth/2.0; getline(ifs, value, ','); data[i][1] = cameraHeight/2.0 - atof(value.c_str()); getline(ifs, value, ','); error[i][0] = atof(value.c_str()); getline(ifs, value); error[i][1] = atof(value.c_str()); } ifs.close(); /* for(int k =0; k<nPoints; k++) { printf( "%g,%g,%g,%g,%g,%g\n", coords[k][0], coords[k][1], measured[k][0], measured[k][1], error[k][0], error[k][0]); } */ // double params[11] = {10.0, 570.0, 130.0, 185.0, -.4836443450476, -1.1132326618289, .8172934386507, // -2.1796283945831, 8.0098006074300, 33.3526742746832, 563.0}; double params[11] = {10.0, 570.0, 130.0, 185.0, 0, 0, 0, 0, 0, 50, 563.0}; double *spread = new1D<double>(11, 0.0); // spread[0] = 3; // spread[1] = 50; // spread[2] = 50; // spread[3] = 50; spread[4] = 3.14/2; spread[5] = 3.14/2; spread[6] = 3.14/2; spread[7] = 5; spread[8] = 5; spread[9] = 30; spread[10] = 0; EyeDeltaFunction *df = new EyeDeltaFunction(coords, data, error, nPoints, 2, params, 11); df->setStartingSpread(spread); Minimizer *m = new Minimizer(df); m->DoMinimize(); double* pOut = df->getParameters(); printf("R: %g\n", pOut[0]); printf("x0: %g\n", pOut[1]); printf("y0: %g\n", pOut[2]); printf("z0: %g\n", pOut[3]); printf("a: %g\n", pOut[4]); printf("b: %g\n", pOut[5]); printf("g: %g\n", pOut[6]); printf("bx: %g\n", pOut[7]); printf("by: %g\n", pOut[8]); printf("dc: %g\n", pOut[9]); printf("z: %g\n", pOut[10]); spread[1] = 50; spread[2] = 50; spread[3] = 50; df->setStartingSpread(spread); m->DoMinimize(); pOut = df->getParameters(); printf("R: %g\n", pOut[0]); printf("x0: %g\n", pOut[1]); printf("y0: %g\n", pOut[2]); printf("z0: %g\n", pOut[3]); printf("a: %g\n", pOut[4]); printf("b: %g\n", pOut[5]); printf("g: %g\n", pOut[6]); printf("bx: %g\n", pOut[7]); printf("by: %g\n", pOut[8]); printf("dc: %g\n", pOut[9]); printf("z: %g\n", pOut[10]); spread[0] = 3; // spread[10] = 20; df->setStartingSpread(spread); m->DoMinimize(); pOut = df->getParameters(); printf("R: %g\n", pOut[0]); printf("x0: %g\n", pOut[1]); printf("y0: %g\n", pOut[2]); printf("z0: %g\n", pOut[3]); printf("a: %g\n", pOut[4]); printf("b: %g\n", pOut[5]); printf("g: %g\n", pOut[6]); printf("bx: %g\n", pOut[7]); printf("by: %g\n", pOut[8]); printf("dc: %g\n", pOut[9]); printf("z: %g\n", pOut[10]); }
int main(int, char **) { FILE *o = fopen("papers/hughes-saft/figs/single-rod-in-water-low-res.dat", "w"); Functional f = OfEffectivePotential(SaftFluid2(hughes_water_prop.lengthscale, hughes_water_prop.epsilonAB, hughes_water_prop.kappaAB, hughes_water_prop.epsilon_dispersion, hughes_water_prop.lambda_dispersion, hughes_water_prop.length_scaling, 0)); double 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)); const double EperVolume = f(hughes_water_prop.kT, -hughes_water_prop.kT*log(n_1atm)); for (cavitysize=1.0*nm; cavitysize<=1.1*nm; cavitysize += 0.5*nm) { Lattice lat(Cartesian(width,0,0), Cartesian(0,ymax,0), Cartesian(0,0,zmax)); GridDescription gd(lat, 0.5); 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/single-rod-in-water-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 + 1000*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(); Minimizer min = Precision(1e-11, PreconditionedConjugateGradient(f, gd, hughes_water_prop.kT, &potential, QuadraticLineMinimizer)); //printf("\nDiameter of rod = %g bohr (%g nm)\n", cavitysize, cavitysize/nm); const int numiters = 50; for (int i=0;i<numiters && min.improve_energy(false);i++) { fflush(stdout); //Grid density(gd, EffectivePotentialToDensity()(hughes_water_prop.kT, gd, potential)); //density.epsNativeSlice("papers/hughes-saft/figs/single-rod-in-water.eps", // Cartesian(0,ymax,0), Cartesian(0,0,zmax), // Cartesian(0,ymax/2,zmax/2)); // sleep(3); } const double EperCell = EperVolume*(zmax*ymax - 0.25*M_PI*cavitysize*cavitysize)*width; //printf("The bulk energy per cell should be %g\n", EperCell); double energy = (min.energy() - EperCell)/width; //printf("Energy is %.15g\n", energy); fprintf(o, "%g\t%.15g\n", cavitysize/nm, energy); char *plotname = (char *)malloc(1024); sprintf(plotname, "papers/hughes-saft/figs/single-rod-res0.5-slice-%04.1f.dat", cavitysize/nm); Grid density(gd, EffectivePotentialToDensity()(hughes_water_prop.kT, gd, potential)); plot_grids_y_direction(plotname, density); free(plotname); } fclose(o); }