Molecule H2() { int nAtoms = 2; Eigen::Vector3d H1( 0.735000, 0.000000, 0.000000); Eigen::Vector3d H2(-0.735000, 0.000000, 0.000000); Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = H1.transpose(); geom.col(1) = H2.transpose(); Eigen::Vector2d charges, masses; charges << 1.0, 1.0; masses << 1.0078250, 1.0078250; std::vector<Atom> atoms; double radiusH = 1.20; atoms.push_back( Atom("Hydrogen", "H", charges(0), masses(0), radiusH, H1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(1), masses(1), radiusH, H2, 1.0) ); std::vector<Sphere> spheres; Sphere sph2(H1, radiusH); Sphere sph3(H2, radiusH); spheres.push_back(sph2); spheres.push_back(sph3); Symmetry pGroup = buildGroup(0, 0, 0, 0); return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };
int main() { typedef TempKernel kernel_type; typedef kernel_type::source_type source_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::target_type target_type; typedef kernel_type::result_type result_type; kernel_type K; // init source std::vector<source_type> sources(2); // init charge std::vector<charge_type> charges(sources.size()); // init target std::vector<target_type> targets(2); // init results vectors for exact std::vector<result_type> exact(targets.size()); // test direct fmmtl::direct(K, sources, charges, targets, exact); std::cout << exact[0] << "\n"; fmmtl::direct(K, sources, charges, exact); std::cout << exact[0] << "\n"; }
int main(int argc, char **argv) { int numBodies = 1000; bool checkErrors = true; // Parse custom command line args for (int i = 1; i < argc; ++i) { if (strcmp(argv[i],"-N") == 0) { i++; numBodies = atoi(argv[i]); } else if (strcmp(argv[i],"-nocheck") == 0) { checkErrors = false; } } // Init the FMM Kernel and options FMMOptions opts = get_options(argc, argv); typedef UnitKernel kernel_type; kernel_type K; typedef kernel_type::point_type point_type; typedef kernel_type::source_type source_type; typedef kernel_type::target_type target_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::result_type result_type; // Init points and charges std::vector<source_type> points(numBodies); for (int k = 0; k < numBodies; ++k) points[k] = source_type(drand(), drand(), drand()); std::vector<charge_type> charges(numBodies); for (int k = 0; k < numBodies; ++k) charges[k] = drand(); // Build the FMM //fmm_plan plan = fmm_plan(K, bodies, opts); FMM_plan<kernel_type> plan = FMM_plan<kernel_type>(K, points, opts); // Execute the FMM //fmm_execute(plan, charges, target_points); std::vector<result_type> result = plan.execute(charges); // Check the result if (checkErrors) { std::vector<result_type> exact(numBodies); // Compute the result with a direct matrix-vector multiplication Direct::matvec(K, points, charges, exact); int wrong_results = 0; for (unsigned k = 0; k < result.size(); ++k) { printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k], result[k]); if ((exact[k] - result[k]) / exact[k] > 1e-13) ++wrong_results; } printf("Wrong counts: %d\n", wrong_results); } }
Molecule H3() { int nAtoms = 3; Eigen::Vector3d H1( 0.735000, 0.000000, -1.333333); Eigen::Vector3d H2(-0.735000, 0.000000, -1.333333); Eigen::Vector3d H3( 0.000000, 0.000000, 2.666667); Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = H1.transpose(); geom.col(1) = H2.transpose(); geom.col(2) = H3.transpose(); Eigen::Vector3d charges, masses; charges << 1.0, 1.0, 1.0; masses << 1.0078250, 1.0078250, 1.0078250; std::vector<Atom> atoms; double radiusH = (1.20 * 1.20) / convertBohrToAngstrom; atoms.push_back( Atom("Hydrogen", "H", charges(0), masses(0), radiusH, H1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(1), masses(1), radiusH, H2, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(2), masses(2), radiusH, H3, 1.0) ); std::vector<Sphere> spheres; Sphere sph2(H1, radiusH); Sphere sph3(H2, radiusH); Sphere sph4(H3, radiusH); spheres.push_back(sph2); spheres.push_back(sph3); spheres.push_back(sph4); enum pointGroup { pgC1, pgC2, pgCs, pgCi, pgD2, pgC2v, pgC2h, pgD2h }; Symmetry pGroup; switch(group) { case(pgC1): pGroup = buildGroup(0, 0, 0, 0); break; case(pgC2v): // C2v as generated by Oyz and Oxz pGroup = buildGroup(2, 1, 2, 0); break; default: pGroup = buildGroup(0, 0, 0, 0); break; } return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };
int Stick::Worth() const { int worth = Category()->worth(); worth += 20 * charges(); if (!is_known()) worth /= 2; return worth; }
Molecule NH3() { int nAtoms = 4; Eigen::Vector3d N( -0.000000000, -0.104038047, 0.000000000); Eigen::Vector3d H1(-0.901584415, 0.481847022, -1.561590016); Eigen::Vector3d H2(-0.901584415, 0.481847022, 1.561590016); Eigen::Vector3d H3( 1.803168833, 0.481847022, 0.000000000); Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = N.transpose(); geom.col(1) = H1.transpose(); geom.col(2) = H2.transpose(); geom.col(3) = H3.transpose(); Eigen::Vector4d charges, masses; charges << 7.0, 1.0, 1.0, 1.0; masses << 14.0030740, 1.0078250, 1.0078250, 1.0078250; std::vector<Atom> atoms; atoms.push_back( Atom("Nitrogen", "N", charges(0), masses(0), 2.929075493, N, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(1), masses(1), 2.267671349, H1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(2), masses(2), 2.267671349, H2, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(3), masses(3), 2.267671349, H3, 1.0) ); std::vector<Sphere> spheres; Sphere sph1(N, 2.929075493); Sphere sph2(H1, 2.267671349); Sphere sph3(H2, 2.267671349); Sphere sph4(H3, 2.267671349); spheres.push_back(sph1); spheres.push_back(sph2); spheres.push_back(sph3); spheres.push_back(sph4); // C1 Symmetry pGroup = buildGroup(0, 0, 0, 0); return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };
void execute(const Kernel& K, ChargeIter cfirst, ChargeIter clast, ResultIter rfirst, ResultIter rlast) { // TODO: Ugh, iterator type hiding via copy std::vector<charge_type> charges(cfirst, clast); std::vector<result_type> results(rfirst, rlast); execute(K, charges, results); std::copy(results.begin(), results.end(), rfirst); }
int main() { typedef LaplaceSpherical kernel_type; kernel_type K(5); typedef kernel_type::point_type point_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::result_type result_type; FMMOptions opts; opts.set_mac_theta(.5); opts.set_max_per_box(125); // optimal ncrit std::vector<std::pair<unsigned,double>> times; double tic, toc; int numBodies = 1000000; // initialize points std::vector<point_type> points(numBodies); for (int k=0; k<numBodies; ++k){ points[k] = point_type(drand(), drand(), drand()); } // initialize charges std::vector<charge_type> charges(numBodies); for (int k=0; k<numBodies; ++k){ charges[k] = drand(); } // loop in ncrit for (int ncrit=50; ncrit<=400; ncrit+=50){ opts.set_max_per_box(ncrit); // create FMM plan FMM_plan<kernel_type> plan = FMM_plan<kernel_type>(K, points, opts); // execute FMM // run 3 times and make an average int nt = 3; // number of identical runs for timing std::vector<double> timings(nt); std::vector<result_type> result(numBodies); for (int i=0; i<nt; i++){ tic = get_time(); result = plan.execute(charges); toc = get_time(); timings[i] = toc-tic; } double FMM_time = std::accumulate(timings.begin(), timings.end(), 0.0) / timings.size(); std::cout << ncrit << " " << FMM_time << std::endl; } return 0; }
Molecule CH3() { int nAtoms = 4; Eigen::Vector3d C1( 0.0006122714, 0.0000000000, 0.0000000000); Eigen::Vector3d H1( 1.5162556382, -1.3708721537, 0.0000000000); Eigen::Vector3d H2(-0.7584339548, 0.6854360769, 1.7695110698); Eigen::Vector3d H3(-0.7584339548, 0.6854360769, -1.7695110698); Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = C1.transpose(); geom.col(1) = H1.transpose(); geom.col(2) = H2.transpose(); geom.col(3) = H3.transpose(); Eigen::Vector4d charges, masses; charges << 6.0, 1.0, 1.0, 1.0; masses << 12.00, 1.0078250, 1.0078250, 1.0078250; double radiusC = (1.70 * 1.20) / convertBohrToAngstrom; double radiusH = (1.20 * 1.20) / convertBohrToAngstrom; std::vector<Atom> atoms; atoms.push_back( Atom("Carbon", "C", charges(0), masses(0), radiusC, C1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(1), masses(1), radiusH, H1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(2), masses(2), radiusH, H2, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(3), masses(3), radiusH, H3, 1.0) ); std::vector<Sphere> spheres; Sphere sph1(C1, radiusC); Sphere sph2(H1, radiusH); Sphere sph3(H2, radiusH); Sphere sph4(H3, radiusH); spheres.push_back(sph1); spheres.push_back(sph2); spheres.push_back(sph3); spheres.push_back(sph4); // Cs as generated by Oxy Symmetry pGroup = buildGroup(1, 4, 0, 0); return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };
bool ExternalCharges::parse(TextStream& textStream) { int max(INT_MAX); bool allOk(true), isDouble; bool maxSet(false), invalidFormat(false); double x, y, z, q; QStringList tokens; Data::PointChargeList* charges(new Data::PointChargeList); while (!textStream.atEnd() && charges->size() < max) { tokens = textStream.nextLineAsTokens(); if (tokens.size() >= 4) { x = tokens[0].toDouble(&isDouble); allOk = allOk && isDouble; y = tokens[1].toDouble(&isDouble); allOk = allOk && isDouble; z = tokens[2].toDouble(&isDouble); allOk = allOk && isDouble; q = tokens[3].toDouble(&isDouble); allOk = allOk && isDouble; if (allOk) { charges->append(new Data::PointCharge(q, qglviewer::Vec(x,y,z))); }else { invalidFormat = true; break; } }else if (tokens.size() >= 1) { if (tokens.first().contains("$end", Qt::CaseInsensitive) || maxSet) { break; }else { max = tokens[0].toInt(&maxSet); } } } if (maxSet && charges->size() != max) { if (invalidFormat) { QString msg("Invalid format on line "); m_errors.append(msg += QString::number(textStream.lineNumber())); }else { m_errors.append("End of stream encountered"); } delete charges; }else if (charges->isEmpty()) { m_errors.append("No charges found"); delete charges; }else { m_dataBank.append(charges); } return m_errors.isEmpty(); }
Molecule C2H4() { int nAtoms = 6; Eigen::Vector3d C1(0.0000000000, 0.0000000000, 1.2578920000); Eigen::Vector3d H1(0.0000000000, 1.7454620000, 2.3427160000); Eigen::Vector3d H2(0.0000000000, -1.7454620000, 2.3427160000); Eigen::Vector3d C2(0.0000000000, 0.0000000000, -1.2578920000); Eigen::Vector3d H3(0.0000000000, 1.7454620000, -2.3427160000); Eigen::Vector3d H4(0.0000000000, -1.7454620000, -2.3427160000); Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = C1.transpose(); geom.col(1) = H1.transpose(); geom.col(2) = H2.transpose(); geom.col(3) = C2.transpose(); geom.col(4) = H3.transpose(); geom.col(5) = H4.transpose(); Eigen::VectorXd charges(6), masses(6); charges << 6.0, 1.0, 1.0, 6.0, 1.0, 1.0; masses << 12.00, 1.0078250, 1.0078250, 12.0, 1.0078250, 1.0078250; double radiusC = (1.70 * 1.20) / convertBohrToAngstrom; double radiusH = (1.20 * 1.20) / convertBohrToAngstrom; std::vector<Atom> atoms; atoms.push_back( Atom("Carbon", "C", charges(0), masses(0), radiusC, C1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(1), masses(1), radiusH, H1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(2), masses(2), radiusH, H2, 1.0) ); atoms.push_back( Atom("Carbon", "C", charges(3), masses(3), radiusC, C2, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(4), masses(4), radiusH, H3, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(5), masses(5), radiusH, H4, 1.0) ); std::vector<Sphere> spheres; Sphere sph1(C1, radiusC); Sphere sph2(H1, radiusH); Sphere sph3(H2, radiusH); Sphere sph4(C2, radiusC); Sphere sph5(H3, radiusH); Sphere sph6(H4, radiusH); spheres.push_back(sph1); spheres.push_back(sph2); spheres.push_back(sph3); spheres.push_back(sph4); spheres.push_back(sph5); spheres.push_back(sph6); // D2h as generated by Oxy, Oxz, Oyz Symmetry pGroup = buildGroup(3, 4, 2, 1); return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };
void QChemInput::readExternalChargesSection(TextStream& textStream) { ExternalCharges parser; if (parser.parse(textStream)) { Data::Bank& bank(parser.data()); if (!bank.isEmpty()) { Data::Base* base(bank.takeFirst()); Data::PointChargeList* charges(dynamic_cast<Data::PointChargeList*>(base)); if (charges) m_dataBank.append(charges); } }else { m_errors << parser.errors(); } }
List Factory::convert(Data::PointChargeList& pointCharges) { Charges* charges(new Charges()); unsigned nCharges(pointCharges.size()); for (unsigned i = 0; i < nCharges; ++i) { double q(pointCharges[i]->value()); qglviewer::Vec position(pointCharges[i]->position()); Charge* charge(new Charge(q,position)); charges->appendLayer(charge); } List list; list.append(charges); return list; }
void test_kernel(const Kernel& K) { typedef typename Kernel::source_type source_type; typedef typename Kernel::charge_type charge_type; typedef typename Kernel::target_type target_type; typedef typename Kernel::result_type result_type; std::vector<source_type> sources(1); std::vector<charge_type> charges(1); std::vector<target_type> targets(1); std::vector<result_type> results(1); Direct::matvec(K, sources, charges, targets, results); std::cout << results[0] << std::endl; std::cout << KernelTraits<Kernel>() << std::endl; std::cout << typeid(Kernel).name() << " OK." << std::endl; }
int task1_main (void) { FILE* infile = NULL, *outfile = NULL; int month = 0, year = 0, customer_number = 0, hours_used = 0; double charge = 0.0, average_cost = 0.0; printf ("\nOpening files..."); infile = fopen ("task1_input.dat", "r"); outfile = fopen ("task1_output.dat", "w"); fscanf (infile, " %d", &month); fscanf (infile, " %d", &year); fprintf (outfile, "InternetLite Charges for %d/%d\n\nCustomer # --|-- Hours Used --|-- Total Charge --|-- Average Cost\n", month, year); printf ("Calculating Costs..."); while (!feof (infile)) { fscanf (infile, " %d", &customer_number); fscanf (infile, " %d", &hours_used); charges (hours_used, &charge, &average_cost); fprintf (outfile, "%d\t\t --|-- %d\t\t\t--|-- $%.2lf\t\t --|-- $%.2lf\n", customer_number, hours_used, charge, average_cost); } printf ("Closing files..."); fclose (infile); fclose (outfile); printf ("Charges complete!\n"); system ("pause"); return 0; }
int main(int argc, char **argv) { int numPanels= 1000, recursions = 4, p = 5, k = 3, max_iterations = 500; FMMOptions opts = get_options(argc,argv); opts.sparse_local = true; SolverOptions solver_options; bool second_kind = false; char *mesh_name; bool mesh = false; // solve / PC settings SOLVERS solver = SOLVE_GMRES; PRECONDITIONERS pc = IDENTITY; // use lazy evaluator by default // opts.lazy_evaluation = true; // parse command line args // check if no arguments given printf("\nLaplaceBEM on a sphere\n"); if (argc == 1) printHelpAndExit(); printf("parameters : \n"); printf("============ \n"); for (int i = 1; i < argc; ++i) { if (strcmp(argv[i],"-theta") == 0) { i++; printf("theta = %s\n", argv[i]); } else if (strcmp(argv[i],"-recursions") == 0) { i++; recursions = atoi(argv[i]); // print out problem size based on the # of recursions printf("N = %i\n", 2* (int) pow(4, recursions)); } else if (strcmp(argv[i],"-eval") == 0) { i++; } else if (strcmp(argv[i], "-ncrit") == 0) { i++; printf("ncrit = %s\n", argv[i]); } else if (strcmp(argv[i], "-printtree") == 0) { } else if (strcmp(argv[i],"-p") == 0) { i++; p = atoi(argv[i]); solver_options.max_p = p; printf("max-p = %i\n", p); } else if (strcmp(argv[i],"-k") == 0) { i++; k = atoi(argv[i]); } else if (strcmp(argv[i],"-second_kind") == 0) { second_kind = true; printf("second-kind = True\n"); } else if (strcmp(argv[i],"-fixed_p") == 0) { solver_options.variable_p = false; printf("relaxed = False\n"); } else if (strcmp(argv[i],"-solver_tol") == 0) { i++; solver_options.residual = (double)atof(argv[i]); printf("solver_tol = %.2e\n", solver_options.residual); } else if (strcmp(argv[i],"-max_iters") == 0) { i++; max_iterations = atoi(argv[i]); } else if (strcmp(argv[i],"-gmres") == 0) { solver = SOLVE_GMRES; } else if (strcmp(argv[i],"-fgmres") == 0) { solver = SOLVE_FGMRES; } else if (strcmp(argv[i],"-local") == 0) { solver = SOLVE_FGMRES; pc = LOCAL; } else if (strcmp(argv[i],"-diagonal") == 0) { pc = DIAGONAL; } else if (strcmp(argv[i],"-help") == 0) { printHelpAndExit(); } else if (strcmp(argv[i],"-mesh") == 0) { i++; mesh_name = argv[i]; mesh = true; } else { printf("[W]: Unknown command line arg: \"%s\"\n",argv[i]); printHelpAndExit(); } } printf("============\n"); solver_options.max_iters = max_iterations; solver_options.restart = max_iterations; // opts.sparse_local = true; double tic, toc; // Init the FMM Kernel typedef LaplaceSphericalBEM kernel_type; kernel_type K(p,k); // useful typedefs typedef kernel_type::point_type point_type; typedef kernel_type::source_type source_type; typedef kernel_type::target_type target_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::result_type result_type; // Init points and charges std::vector<source_type> panels(numPanels); std::vector<charge_type> charges(numPanels); if (mesh) { printf("reading mesh from: %s\n",mesh_name); MeshIO::readMsh<point_type,source_type>(mesh_name, panels); // , panels); } else { Triangulation::UnitSphere(panels, recursions); // initialiseSphere(panels, charges, recursions); //, ProblemOptions()); } // run case solving for Phi (instead of dPhi/dn) if (second_kind) for (auto& it : panels) it.switch_BC(); // set constant Phi || dPhi/dn for each panel charges.resize(panels.size()); // set up a more complicated charge, from BEM++ for (unsigned i=0; i<panels.size(); i++) { #if BEMCPP_TEST auto center = panels[i].center; double x = center[0], y = center[1], z = center[2]; double r = norm(center); charges[i] = 2*x*z/(r*r*r*r*r) - y/(r*r*r); #else charges[i] = 1.; #endif } // charges = std::vector<charge_type>(panels.size(),1.); // Build the FMM structure FMM_plan<kernel_type> plan = FMM_plan<kernel_type>(K, panels, opts); // generate the RHS and initial condition std::vector<charge_type> x(panels.size(),0.); tic = get_time(); std::vector<result_type> b(panels.size(),0.); double tic2, toc2; // generate RHS using temporary FMM plan { tic2 = get_time(); for (auto& it : panels) it.switch_BC(); toc2 = get_time(); printf("Flipping BC: %g\n",toc2-tic2); tic2 = get_time(); FMM_plan<kernel_type> rhs_plan = FMM_plan<kernel_type>(K,panels,opts); toc2 = get_time(); printf("Creating plan: %g\n",toc2-tic2); tic2 = get_time(); b = rhs_plan.execute(charges); toc2 = get_time(); printf("Executing plan: %g\n",toc2-tic2); for (auto& it : panels) it.switch_BC(); } toc = get_time(); double setup_time = toc-tic; // Solve the system using GMRES // generate the Preconditioner tic = get_time(); Preconditioners::Diagonal<charge_type> M(K, plan.source_begin(), plan.source_end() ); // M.print(); SolverOptions inner_options(1e-2,1,2); inner_options.variable_p = true; /* // Preconditioners::FMGMRES<FMM_plan<kernel_type>,Preconditioners::Diagonal<charge_type>> inner(plan, b, inner_options, M); // Local preconditioner Preconditioners::LocalInnerSolver<FMM_plan<kernel_type>, Preconditioners::Diagonal<result_type>> local(K, panels, b); // block diagonal preconditioner Preconditioners::BlockDiagonal<FMM_plan<kernel_type>> block_diag(K,panels); */ // Initial low accuracy solve // /* double tic2, toc2; tic2 = get_time(); { printf("Initial solve starting..\n"); // initial solve to 1e-2 accuracy, 5 iterations, P = 2 SolverOptions initial_solve(5e-3,50,3); // fmm_gmres(plan, x, b, solver_options, M); GMRES(plan, x, b, initial_solve, M); printf("Initial solve finished..\n"); } toc2 = get_time(); printf("Initial solve took: %.4es\n",toc2-tic2); */ // Outer GMRES solve with diagonal preconditioner & relaxation FGMRESContext<result_type> context(x.size(), solver_options.restart); if (second_kind) printf("2nd-kind equation being solved\n"); else printf("1st-kind equation being solved\n"); #if 1 if (solver == SOLVE_GMRES && pc == IDENTITY){ printf("Solver: GMRES\nPreconditioner: Identity\n"); // straight GMRES, no preconditioner // DirectMV<kernel_type> MV(K, panels, panels); GMRES(plan,x,b,solver_options); } else if (solver == SOLVE_GMRES && pc == DIAGONAL) { printf("Solver: GMRES\nPreconditioner: Diagonal\n"); // GMRES, diagonal preconditioner GMRES(plan, x, b, solver_options, M, context); } #else else if (solver == SOLVE_GMRES && pc == DIAGONAL) { printf("Solver: GMRES\nPreconditioner: Diagonal\n"); // GMRES, diagonal preconditioner GMRES(plan,x,b,solver_options, M, context); } else if (solver == SOLVE_FGMRES && pc == IDENTITY) { printf("Solver: FMRES\nPreconditioner: Identity\n"); // GMRES, diagonal preconditioner FGMRES(plan,x,b,solver_options); } else if (solver == SOLVE_FGMRES && pc == DIAGONAL) { printf("Solver: FGMRES\nPreconditioner: Block Diagonal\n"); // GMRES, diagonal preconditioner FGMRES(plan,x,b,solver_options, block_diag, context); } else if (solver == SOLVE_FGMRES && pc == LOCAL) { printf("Solver: FGMRES\nPreconditioner: Local solve\n"); // FGMRES, Local inner solver FGMRES(plan,x,b,solver_options, local, context); } else { printf("[E] no valid solver / preconditioner option chosen\n"); exit(0); } #endif // GMRES(MV,x,b,solver_options, M, context); // FGMRES(plan,x,b,solver_options, inner, context); // , context); // Outer/Inner FGMRES / GMRES (Diagonal) toc = get_time(); double solve_time = toc-tic; printf("\nTIMING:\n"); printf("\tsetup : %.4es\n",setup_time); printf("\tsolve : %.4es\n",solve_time); // check errors -- analytical solution for dPhi/dn = 1. double e = 0.; double e2 = 0.; #if BEMCPP_TEST std::vector<result_type> analytical(panels.size()); for (unsigned i=0; i<panels.size(); i++) { auto center = panels[i].center; double x = center[0], y = center[1], z = center[2]; double r = norm(center); analytical[i] = -(-6 * x * z / (r*r*r*r*r*r) + 2 * y / (r*r*r*r)); } auto ai = analytical.begin(); for (auto xi : x) { // printf("approx: %.4g, analytical: %.4g\n",xi,*ai); e += (xi-*ai)*(xi-*ai); e2 += (*ai)*(*ai); ++ai; } #else double an = 1.; for (auto xi : x) { e += (xi-an)*(xi-an); e2 += an*an; } #endif #define EXTERNAL_ERROR #ifdef EXTERNAL_ERROR std::vector<target_type> outside_point(1); outside_point[0] = target_type(point_type(3.,3.,3.),point_type(3.,3.,3.),point_type(3.,3.,3.)); outside_point[0].center = point_type(3.,3.,3.); std::vector<result_type> outside_result_1(1); std::vector<result_type> outside_result_2(1); outside_result_1[0] = 0.; outside_result_2[0] = 0.; // first layer Direct::matvec(K, panels.begin(), panels.end(), x.begin(), outside_point.begin(), outside_point.end(), outside_result_2.begin()); // for (auto& pi : panels) pi.switch_BC(); for (auto& op : outside_point) op.switch_BC(); Direct::matvec(K, panels.begin(), panels.end(), charges.begin(), outside_point.begin(), outside_point.end(), outside_result_1.begin()); double exact = 1. / norm(static_cast<point_type>(outside_point[0])) * 1; double outside_result = (outside_result_2[0]-outside_result_1[0])/4/M_PI; double outside_error = fabs(outside_result-exact)/fabs(exact); printf("external phi: %.5g, exact: %.5g, error: %.4e\n",outside_result,exact, outside_error); #endif printf("relative error: %.3e\n",sqrt(e/e2)); }
int main(int argc, char **argv) { int N = 1 << 20; // Parse custom command line args for (int i = 1; i < argc; ++i) { if (strcmp(argv[i],"-N") == 0) { N = atoi(argv[++i]); } } // Round up to the nearest square number int n_side = int(std::ceil(std::sqrt(N))); N = n_side * n_side; // Init the FMM Kernel and options FMMOptions opts = get_options(argc, argv); //typedef UnitExpansion kernel_type; //typedef ExpExpansion kernel_type; typedef LaplaceSpherical kernel_type; //typedef YukawaCartesian kernel_type; // Init kernel kernel_type K; typedef kernel_type::point_type point_type; typedef kernel_type::source_type source_type; typedef kernel_type::target_type target_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::result_type result_type; std::cout << "Initializing source and N = " << N << " targets..." << std::endl; // Init a square targets double xmin = -1; double xmax = 1; double ymin = -1; double ymax = 1; std::vector<target_type> targets; targets.reserve(N); for (int n = 0; n < n_side; ++n) { for (int m = 0; m < n_side; ++m) { targets.push_back(target_type(xmin + n * (xmax-xmin) / (n_side-1), ymin + m * (ymax-ymin) / (n_side-1))); } } //int middle = n_side/2 * n_side + n_side/2; int middle = fmmtl::random<unsigned>::get(0, N); // Init charges, only the middle source has a charge std::vector<charge_type> charges(N); charges[middle] = charge_type(1); std::cout << "Building the kernel matrix..." << std::endl; // Build the FMM fmmtl::kernel_matrix<kernel_type> A = K(targets, targets); A.set_options(opts); std::cout << "Performing the kernel matrix-vector mult..." << std::endl; // Execute the FMM std::vector<result_type> result = A * charges; // Check the result std::cout << "Computing direct kernel matrix-vector mult..." << std::endl; // Compute the result with a direct matrix-vector multiplication std::vector<result_type> exact(N); fmmtl::direct(K, targets.begin()+middle, targets.begin()+middle+1, charges.begin()+middle, targets.begin(), targets.end(), exact.begin()); std::cout << "Computing the errors..." << std::endl; std::vector<double> log_error(result.size()); double min_error = std::numeric_limits<double>::max(); double max_error = std::numeric_limits<double>::lowest(); for (unsigned k = 0; k < result.size(); ++k) { double error = norm_2(exact[k] - result[k]) / norm_2(exact[k]); if (error > 1e-15) log_error[k] = std::log10(error); else log_error[k] = -16; min_error = std::min(min_error, log_error[k]); max_error = std::max(max_error, log_error[k]); } std::cout << "Min log error: " << min_error << std::endl; std::cout << "Max log error: " << max_error << std::endl; // Fill the image with the errors computed above gil::rgb8_image_t img(n_side, n_side); auto img_view = gil::view(img); for (int n = 0; n < n_side; ++n) { for (int m = 0; m < n_side; ++m) { img_view(n,m) = make_heat((log_error[n*n_side+m] - min_error) / (max_error - min_error)); } } gil::png_write_view("fmmtl_errors.png", const_view(img)); }
Layer::List Factory::toLayers(Data::Base& data) { Layer::List layers; //qDebug() << "Layer::Factory converting" << Data::Type::toString(data.typeID()); try { switch (data.typeID()) { case Data::Type::Bank: { Data::Bank& bank(dynamic_cast<Data::Bank&>(data)); layers << convert(bank); } break; case Data::Type::GeometryList: { Data::GeometryList& list(dynamic_cast<Data::GeometryList&>(data)); layers << convert(list); } break; case Data::Type::Geometry: { Data::Geometry& geometry(dynamic_cast<Data::Geometry&>(data)); layers << convert(geometry); } break; case Data::Type::PointChargeList: { Data::PointChargeList& charges(dynamic_cast<Data::PointChargeList&>(data)); layers << convert(charges); } break; case Data::Type::MolecularOrbitalsList: { Data::MolecularOrbitalsList& list(dynamic_cast<Data::MolecularOrbitalsList&>(data)); layers << convert(list); } break; case Data::Type::MolecularOrbitals: { Data::MolecularOrbitals& molecularOrbitals(dynamic_cast<Data::MolecularOrbitals&>(data)); layers.append(new MolecularOrbitals(molecularOrbitals)); } break; case Data::Type::ExcitedStates: { Data::ExcitedStates& states(dynamic_cast<Data::ExcitedStates&>(data)); layers.append(new ExcitedStates(states)); } break; case Data::Type::Frequencies: { Data::Frequencies& frequencies(dynamic_cast<Data::Frequencies&>(data)); layers.append(new Frequencies(frequencies)); } break; case Data::Type::FileList: { Data::FileList& fileList(dynamic_cast<Data::FileList&>(data)); layers << convert(fileList); } break; case Data::Type::GridData: { QLOG_WARN() << "Data::GridData passed to LayerFactory"; //Data::GridData& grid(dynamic_cast<Data::GridData&>(data)); //layers.append(new CubeData(grid)); } break; case Data::Type::CubeData: { Data::CubeData& cube(dynamic_cast<Data::CubeData&>(data)); layers.append(new CubeData(cube)); } break; case Data::Type::EfpFragment: { Data::EfpFragment& efp(dynamic_cast<Data::EfpFragment&>(data)); layers.append(new EfpFragment(efp)); } break; case Data::Type::EfpFragmentList: { Data::EfpFragmentList& efpList(dynamic_cast<Data::EfpFragmentList&>(data)); layers << convert(efpList); } break; case Data::Type::Mesh: { Data::Mesh& meshData(dynamic_cast<Data::Mesh&>(data)); Data::Surface surface(meshData); Layer::Surface* surfaceLayer(new Surface(surface)); surfaceLayer->setCheckState(Qt::Checked); layers.append(surfaceLayer); } break; case Data::Type::Surface: { Data::Surface& surfaceData(dynamic_cast<Data::Surface&>(data)); Layer::Surface* surfaceLayer(new Surface(surfaceData)); surfaceLayer->setCheckState(surfaceData.isVisible() ? Qt::Checked : Qt::Unchecked); layers.append(surfaceLayer); } break; case Data::Type::Nmr: { Data::Nmr& nmrData(dynamic_cast<Data::Nmr&>(data)); Layer::Nmr* nmrLayer(new Nmr(nmrData)); layers.append(nmrLayer); } break; default: QLOG_WARN() << "Unimplemented data type in Layer::Factory" << Data::Type::toString(data.typeID()); break; } } catch (const std::bad_cast& e) { QLOG_ERROR() << "Data cast in Layer::Factory failed" << Data::Type::toString(data.typeID()); } return layers; }
int main(int argc, const char * argv[]) { int numParticles = 24; double charges_arr[] = {0.131300, 0.147300, 0.139400, 0.157400, 0.117000, 0.067800, 0.091200, 0.424900, 0.425600, 0.483500, 0.423600, -0.109800, -0.094800, -0.207900, -0.146800, -0.151000, 0.126300, 0.936500, -0.045900, -0.074300, -0.833000, -0.711000, -0.801600, -0.495800}; double atomicRadii_arr[] = {0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.120000, 0.170000, 0.170000, 0.170000, 0.170000, 0.170000, 0.170000, 0.170000, 0.170000, 0.170000, 0.155000, 0.150000, 0.150000, 0.150000}; double scaleFactors_arr[] = {0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.850000, 0.720000, 0.720000, 0.720000, 0.720000, 0.720000, 0.720000, 0.720000, 0.720000, 0.720000, 0.790000, 0.850000, 0.850000, 0.850000}; std::vector<double> charges(charges_arr, charges_arr + sizeof(charges_arr) / sizeof(double)); std::vector<double> atomicRadii(atomicRadii_arr, atomicRadii_arr + sizeof(atomicRadii_arr) / sizeof(double)); std::vector<double> scaleFactors(scaleFactors_arr, scaleFactors_arr + sizeof(scaleFactors_arr) / sizeof(double)); vector3 atomCoordinates[numParticles]; atomCoordinates[0][0] = 2.805550; atomCoordinates[0][1] = 0.089450; atomCoordinates[0][2] = 1.683500; atomCoordinates[1][0] = 2.713690; atomCoordinates[1][1] = 0.503260; atomCoordinates[1][2] = 1.735420; atomCoordinates[2][0] = 2.580450; atomCoordinates[2][1] = 0.033700; atomCoordinates[2][2] = 1.759150; atomCoordinates[3][0] = 2.487860; atomCoordinates[3][1] = 0.447340; atomCoordinates[3][2] = 1.816930; atomCoordinates[4][0] = 2.946940; atomCoordinates[4][1] = 0.422240; atomCoordinates[4][2] = 1.714860; atomCoordinates[5][0] = 2.984070; atomCoordinates[5][1] = 0.255700; atomCoordinates[5][2] = 1.683920; atomCoordinates[6][0] = 2.861380; atomCoordinates[6][1] = 0.300150; atomCoordinates[6][2] = 1.449780; atomCoordinates[7][0] = 3.095920; atomCoordinates[7][1] = 0.243650; atomCoordinates[7][2] = 1.485840; atomCoordinates[8][0] = 3.085850; atomCoordinates[8][1] = 0.363430; atomCoordinates[8][2] = 1.370570; atomCoordinates[9][0] = 3.130310; atomCoordinates[9][1] = 0.402180; atomCoordinates[9][2] = 1.526820; atomCoordinates[10][0] = 2.352870; atomCoordinates[10][1] = 0.278670; atomCoordinates[10][2] = 1.858320; atomCoordinates[11][0] = 2.737170; atomCoordinates[11][1] = 0.168810; atomCoordinates[11][2] = 1.712970; atomCoordinates[12][0] = 2.683540; atomCoordinates[12][1] = 0.398830; atomCoordinates[12][2] = 1.742020; atomCoordinates[13][0] = 2.610740; atomCoordinates[13][1] = 0.137850; atomCoordinates[13][2] = 1.754950; atomCoordinates[14][0] = 2.556960; atomCoordinates[14][1] = 0.368490; atomCoordinates[14][2] = 1.788380; atomCoordinates[15][0] = 2.774370; atomCoordinates[15][1] = 0.299610; atomCoordinates[15][2] = 1.706940; atomCoordinates[16][0] = 2.522120; atomCoordinates[16][1] = 0.234120; atomCoordinates[16][2] = 1.795440; atomCoordinates[17][0] = 2.884280; atomCoordinates[17][1] = 0.507750; atomCoordinates[17][2] = 1.481190; atomCoordinates[18][0] = 2.913600; atomCoordinates[18][1] = 0.335030; atomCoordinates[18][2] = 1.658250; atomCoordinates[19][0] = 2.926150; atomCoordinates[19][1] = 0.365170; atomCoordinates[19][2] = 1.508870; atomCoordinates[20][0] = 3.065150; atomCoordinates[20][1] = 0.341270; atomCoordinates[20][2] = 1.470230; atomCoordinates[21][0] = 2.912950; atomCoordinates[21][1] = 0.548670; atomCoordinates[21][2] = 1.368890; atomCoordinates[22][0] = 2.827210; atomCoordinates[22][1] = 0.581440; atomCoordinates[22][2] = 1.566630; atomCoordinates[23][0] = 2.405610; atomCoordinates[23][1] = 0.197730; atomCoordinates[23][2] = 1.831700; ObcParameters* obcParameters = new ObcParameters(numParticles, ObcParameters::ObcTypeII); obcParameters->setAtomicRadii(atomicRadii); obcParameters->setScaledRadiusFactors(scaleFactors); obcParameters->setSolventDielectric(static_cast<double>(78.5)); obcParameters->setSoluteDielectric(static_cast<double>(1.0)); obcParameters->setPi4Asolv(4*M_PI*2.25936); obcParameters->setUseCutoff(static_cast<double>(1.5)); ReferenceObc *obc = new ReferenceObc(obcParameters); obc->setIncludeAceApproximation(true); vector3 inputForces[numParticles]; double obcEnergy; obcEnergy = obc->computeBornEnergyForces(atomCoordinates, charges, inputForces); // Energy is inconsistent with MMTK version std::cout << "Obc energy: " << obcEnergy << std::endl; for (int i = 0; i < numParticles; ++i) std::cout << inputForces[i][0] << ' ' << inputForces[i][1] << ' ' << inputForces[i][2] << std::endl; delete obcParameters; return 0; }
int main(int argc, char **argv) { int N = 10000; bool checkErrors = true; // Parse custom command line args for (int i = 1; i < argc; ++i) { if (strcmp(argv[i],"-N") == 0) { N = atoi(argv[++i]); } else if (strcmp(argv[i],"-nocheck") == 0) { checkErrors = false; } } // Init the FMM Kernel and options FMMOptions opts = get_options(argc, argv); // Init kernel typedef LaplaceSpherical kernel_type; kernel_type K; typedef kernel_type::point_type point_type; typedef kernel_type::source_type source_type; typedef kernel_type::target_type target_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::result_type result_type; // Init points and charges std::vector<source_type> points(N); for (unsigned k = 0; k < points.size(); ++k) points[k] = fmmtl::random<source_type>::get(); std::vector<charge_type> charges(N); for (unsigned k = 0; k < charges.size(); ++k) charges[k] = fmmtl::random<charge_type>::get(); // Build the FMM fmmtl::kernel_matrix<kernel_type> A = K(points, points); A.set_options(opts); // Execute the FMM Clock t1; std::vector<result_type> result = A * charges; double time1 = t1.seconds(); std::cout << "FMM in " << time1 << " secs" << std::endl; // Execute the FMM Clock t2; result = A * charges; double time2 = t2.seconds(); std::cout << "FMM in " << time2 << " secs" << std::endl; // Execute the FMM Clock t3; result = A * charges; double time3 = t3.seconds(); std::cout << "FMM in " << time3 << " secs" << std::endl; // Check the result if (checkErrors) { std::cout << "Computing direct matvec..." << std::endl; std::vector<result_type> exact(N); // Compute the result with a direct matrix-vector multiplication Direct::matvec(K, points, charges, exact); double tot_error_sq = 0; double tot_norm_sq = 0; double tot_ind_rel_err = 0; double max_ind_rel_err = 0; for (unsigned k = 0; k < result.size(); ++k) { // Individual relative error double rel_error = norm(exact[k] - result[k]) / norm(exact[k]); tot_ind_rel_err += rel_error; // Maximum relative error max_ind_rel_err = std::max(max_ind_rel_err, rel_error); // Total relative error tot_error_sq += normSq(exact[k] - result[k]); tot_norm_sq += normSq(exact[k]); } double tot_rel_err = sqrt(tot_error_sq/tot_norm_sq); std::cout << "Vector relative error: " << tot_rel_err << std::endl; double ave_rel_err = tot_ind_rel_err / result.size(); std::cout << "Average relative error: " << ave_rel_err << std::endl; std::cout << "Maximum relative error: " << max_ind_rel_err << std::endl; } }
int main(int argc, char **argv) { int numBodies = 1000, p=5; bool checkErrors = true; double beta = 0.125; FMMOptions opts = get_options(argc, argv); // parse custom command line args for (int i = 1; i < argc; ++i) { if (strcmp(argv[i],"-N") == 0) { i++; numBodies = atoi(argv[i]); } else if (strcmp(argv[i],"-p") == 0) { i++; p = atoi(argv[i]); } else if (strcmp(argv[i],"-beta") == 0) { i++; beta = atof(argv[i]); } else if (strcmp(argv[i],"-nocheck") == 0) { checkErrors = false; } } // Init the FMM Kernel #ifdef SKELETON_KERNEL typedef KernelSkeleton kernel_type; kernel_type K; #endif #ifdef SPH_KERNEL typedef LaplaceSpherical kernel_type; kernel_type K(p); #endif #ifdef CART_KERNEL typedef LaplaceCartesian<5> kernel_type; kernel_type K; #endif #ifdef YUKAWA_KERNEL typedef YukawaCartesian kernel_type; kernel_type K(p,beta); #endif #ifdef YUKAWA_SPH typedef YukawaSpherical kernel_type; kernel_type K(p,beta); #endif #ifdef UNIT_KERNEL typedef UnitKernel kernel_type; kernel_type K; #endif #ifdef STOKES_SPH typedef StokesSpherical kernel_type; kernel_type K(p); #endif // if not using a Yukawa kernel, quiet warnings #if !defined(YUKAWA_KERNEL) && !defined(YUKAWA_SPH) (void) beta; #endif typedef kernel_type::point_type point_type; typedef kernel_type::source_type source_type; typedef kernel_type::target_type target_type; typedef kernel_type::charge_type charge_type; typedef kernel_type::result_type result_type; // Init points and charges std::vector<source_type> points(numBodies); for (int k = 0; k < numBodies; ++k) points[k] = source_type(drand(), drand(), drand()); //std::vector<point_type> target_points = points; std::vector<charge_type> charges(numBodies); for (int k = 0; k < numBodies; ++k) { #if defined(STOKES_SPH) #if defined(STRESSLET) charges[k][0] = drand(); charges[k][1] = drand(); charges[k][2] = drand(); charges[k][3] = 1.; charges[k][4] = 0.; charges[k][5] = 0.; #else charges[k] = charge_type(1,1,1); // charge_type(drand(),drand(),drand()); #endif #else charges[k] = drand(); #endif } // Build the FMM //fmm_plan plan = fmm_plan(K, bodies, opts); FMM_plan<kernel_type> plan = FMM_plan<kernel_type>(K, points, opts); // Execute the FMM //fmm_execute(plan, charges, target_points); std::vector<result_type> result = plan.execute(charges); // Check the result // TODO: More elegant if (checkErrors) { // choose a number of samples to use int numSamples = std::min(numBodies, 1000); std::vector<int> sample_map(numSamples); std::vector<point_type> sample_targets(numSamples); std::vector<result_type> exact(numSamples); // sample the space (needs to be done better) for (int i=0; i<numSamples; i++) { int sample = i >> 15 % numBodies; sample_map[i] = sample; sample_targets[i] = points[sample]; } // Compute the result with a direct matrix-vector multiplication Direct::matvec(K, points.begin(), points.end(), charges.begin(), sample_targets.begin(), sample_targets.end(), exact.begin()); #if defined(SPH_KERNEL) || defined(CART_KERNEL) || defined(YUKAWA_KERNEL) result_type rdiff, rnorm; for (unsigned k = 0; k < exact.size(); ++k) { auto exact_val = exact[k]; auto fmm_val = result[sample_map[k]]; // printf("[%03d] exact: %lg, FMM: %lg\n", k, exact_val[0], fmm_val[0]); rdiff += (fmm_val - exact_val) * (fmm_val - exact_val); rnorm += exact_val * exact_val; } printf("Error (pot) : %.4e\n", sqrt(rdiff[0] / rnorm[0])); printf("Error (acc) : %.4e\n", sqrt((rdiff[1]+rdiff[2]+rdiff[3]) / (rnorm[1]+rnorm[2]+rnorm[3]))); #endif #if defined(YUKAWA_SPH) result_type rdiff = 0., rnorm = 0.; for (unsigned k = 0; k < exact.size(); ++k) { // printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k], result[k]); auto exact_val = exact[k]; auto fmm_val = result[sample_map[k]]; rdiff = (fmm_val - exact_val) * (fmm_val - exact_val); rnorm = exact_val * exact_val; } printf("Error (pot) : %.4e\n", sqrt(rdiff / rnorm)); #endif #if defined(STOKES_SPH) result_type rdiff = result_type(0.), rnorm = result_type(0.); for (unsigned k = 0; k < exact.size(); ++k) { auto exact_val = exact[k]; auto fmm_val = result[sample_map[k]]; // std::cout << exact_val << " : " << fmm_val << std::endl; for (unsigned i=0; i < 3; i++) { rdiff[i] += (fmm_val[i]-exact_val[i])*(fmm_val[i]-exact_val[i]); rnorm[i] += exact_val[i]*exact_val[i]; } } auto div = rdiff/rnorm; printf("Error (u) : %.4e, (v) : %.4e, (w) : %.4e\n",sqrt(div[0]),sqrt(div[1]),sqrt(div[2])); #endif #ifdef UNIT_KERNEL int wrong_results = 0; for (unsigned k = 0; k < exact.size(); ++k) { auto exact_val = exact[k]; auto fmm_val = result[sample_map[k]]; // printf("[%03d] exact: %lg, FMM: %lg\n", k, exact[k], result[k]); if ((exact_val - fmm_val) / exact_val > 1e-13) ++wrong_results; } printf("Wrong counts: %d\n", wrong_results); #endif } }
Molecule C6H6() { int nAtoms = 12; // These are in Angstrom Eigen::Vector3d C1(5.274, 1.999, -8.568); Eigen::Vector3d C2(6.627, 2.018, -8.209); Eigen::Vector3d C3(7.366, 0.829, -8.202); Eigen::Vector3d C4(6.752, -0.379, -8.554); Eigen::Vector3d C5(5.399, -0.398, -8.912); Eigen::Vector3d C6(4.660, 0.791, -8.919); Eigen::Vector3d H1(4.704, 2.916, -8.573); Eigen::Vector3d H2(7.101, 2.950, -7.938); Eigen::Vector3d H3(8.410, 0.844, -7.926); Eigen::Vector3d H4(7.322, -1.296, -8.548); Eigen::Vector3d H5(4.925, -1.330, -9.183); Eigen::Vector3d H6(3.616, 0.776, -9.196); // Scale C1 /= convertBohrToAngstrom; C2 /= convertBohrToAngstrom; C3 /= convertBohrToAngstrom; C4 /= convertBohrToAngstrom; C5 /= convertBohrToAngstrom; C6 /= convertBohrToAngstrom; H1 /= convertBohrToAngstrom; H2 /= convertBohrToAngstrom; H3 /= convertBohrToAngstrom; H4 /= convertBohrToAngstrom; H5 /= convertBohrToAngstrom; H6 /= convertBohrToAngstrom; Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = C1.transpose(); geom.col(1) = C2.transpose(); geom.col(2) = C3.transpose(); geom.col(3) = C4.transpose(); geom.col(4) = C5.transpose(); geom.col(5) = C6.transpose(); geom.col(6) = H1.transpose(); geom.col(7) = H2.transpose(); geom.col(8) = H3.transpose(); geom.col(9) = H4.transpose(); geom.col(10) = H5.transpose(); geom.col(11) = H6.transpose(); Eigen::VectorXd charges(12), masses(12); charges << 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0; masses << 12.00, 12.0, 12.0, 12.0, 12.0, 12.0, 1.0078250, 1.0078250, 1.0078250, 1.0078250, 1.0078250, 1.0078250; double radiusC = 1.70 / convertBohrToAngstrom; double radiusH = 1.20 / convertBohrToAngstrom; std::vector<Atom> atoms; atoms.push_back( Atom("Carbon", "C", charges(0), masses(0), radiusC, C1, 1.0) ); atoms.push_back( Atom("Carbon", "C", charges(1), masses(1), radiusC, C2, 1.0) ); atoms.push_back( Atom("Carbon", "C", charges(2), masses(2), radiusC, C3, 1.0) ); atoms.push_back( Atom("Carbon", "C", charges(3), masses(3), radiusC, C4, 1.0) ); atoms.push_back( Atom("Carbon", "C", charges(4), masses(4), radiusC, C5, 1.0) ); atoms.push_back( Atom("Carbon", "C", charges(5), masses(5), radiusC, C6, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(6), masses(6), radiusH, H1, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(7), masses(7), radiusH, H2, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(8), masses(8), radiusH, H3, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(9), masses(9), radiusH, H4, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(10), masses(10), radiusH, H5, 1.0) ); atoms.push_back( Atom("Hydrogen", "H", charges(11), masses(11), radiusH, H6, 1.0) ); std::vector<Sphere> spheres; Sphere sph1(C1, radiusC); Sphere sph2(C2, radiusC); Sphere sph3(C3, radiusC); Sphere sph4(C4, radiusC); Sphere sph5(C5, radiusC); Sphere sph6(C6, radiusC); Sphere sph7(H1, radiusH); Sphere sph8(H2, radiusH); Sphere sph9(H3, radiusH); Sphere sph10(H4, radiusH); Sphere sph11(H5, radiusH); Sphere sph12(H6, radiusH); spheres.push_back(sph1); spheres.push_back(sph2); spheres.push_back(sph3); spheres.push_back(sph4); spheres.push_back(sph5); spheres.push_back(sph6); spheres.push_back(sph7); spheres.push_back(sph8); spheres.push_back(sph9); spheres.push_back(sph10); spheres.push_back(sph11); spheres.push_back(sph12); // D2h as generated by Oxy, Oxz, Oyz Symmetry pGroup = buildGroup(0, 0, 0, 0); return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };
Molecule CO2() { int nAtoms = 3; Eigen::Vector3d C1( 0.0000000000, 0.0000000000, 0.0000000000); Eigen::Vector3d O1( 2.1316110791, 0.0000000000, 0.0000000000); Eigen::Vector3d O2(-2.1316110791, 0.0000000000, 0.0000000000); Eigen::MatrixXd geom(3, nAtoms); geom.col(0) = C1.transpose(); geom.col(1) = O1.transpose(); geom.col(2) = O2.transpose(); Eigen::Vector3d charges, masses; charges << 6.0, 8.0, 8.0; masses << 12.00, 15.9949150, 15.9949150; std::vector<Atom> atoms; double radiusC = (1.70 * 1.20) / convertBohrToAngstrom; double radiusO = (1.52 * 1.20) / convertBohrToAngstrom; atoms.push_back( Atom("Carbon", "C", charges(0), masses(0), radiusC, C1, 1.0) ); atoms.push_back( Atom("Oxygen", "O", charges(1), masses(1), radiusO, O1, 1.0) ); atoms.push_back( Atom("Oxygen", "O", charges(2), masses(2), radiusO, O2, 1.0) ); std::vector<Sphere> spheres; Sphere sph1(C1, radiusC); Sphere sph2(O1, radiusO); Sphere sph3(O2, radiusO); spheres.push_back(sph1); spheres.push_back(sph2); spheres.push_back(sph3); enum pointGroup { pgC1, pgC2, pgCs, pgCi, pgD2, pgC2v, pgC2h, pgD2h }; Symmetry pGroup; switch(group) { case(pgC1): pGroup = buildGroup(0, 0, 0, 0); break; case(pgC2): // C2 as generated by C2z pGroup = buildGroup(1, 3, 0, 0); break; case(pgCs): // Cs as generated by Oyz pGroup = buildGroup(1, 1, 0, 0); break; case(pgCi): // Ci as generated by i pGroup = buildGroup(1, 7, 0, 0); break; case(pgD2): // D2 as generated by C2z and C2x pGroup = buildGroup(2, 3, 6, 0); break; case(pgC2v): // C2v as generated by Oyz and Oxz pGroup = buildGroup(2, 1, 2, 0); break; case(pgC2h): // C2h as generated by Oxy and i pGroup = buildGroup(2, 4, 7, 0); break; case(pgD2h): // D2h as generated by Oxy, Oxz and Oyz pGroup = buildGroup(3, 4, 2, 1); break; default: pGroup = buildGroup(0, 0, 0, 0); break; } return Molecule(nAtoms, charges, masses, geom, atoms, spheres, pGroup); };