Example #1
0
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);
};
Example #2
0
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);
  }
}
Example #4
0
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);
};
Example #5
0
int Stick::Worth() const
{
    int worth = Category()->worth();
    worth += 20 * charges();
    if (!is_known())
        worth /= 2;
    return worth;
}
Example #6
0
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);
};
Example #7
0
  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;

}
Example #9
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();
}
Example #11
0
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);
};
Example #12
0
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();
   }
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
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;
}
Example #16
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));
}
Example #17
0
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));
}
Example #18
0
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;
}
Example #19
0
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;
}
Example #20
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
  }
}
Example #22
0
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);
};
Example #23
0
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);
};