32 const std::vector<std::vector<GridContainers::Cartesian_gridpoint> >&
34 constexpr double boxsize = 1;
37 Eigen::Array3d::Ones() * std::numeric_limits<double>::max();
39 Eigen::Array3d::Ones() * std::numeric_limits<double>::min();
41 for (
const auto& atom_grid : grid) {
42 for (
const auto& gridpoint : atom_grid) {
43 const Eigen::Vector3d& pos = gridpoint.grid_pos;
44 max = max.max(pos.array()).eval();
45 min = min.min(pos.array()).eval();
49 Eigen::Array3d molextension = max - min;
50 Eigen::Array<Index, 3, 1> numberofboxes =
51 (molextension / boxsize).ceil().cast<
Index>();
54 boxes(numberofboxes.x(), numberofboxes.y(), numberofboxes.z());
56 for (
const auto& atomgrid : grid) {
57 for (
const auto& gridpoint : atomgrid) {
58 Eigen::Array3d pos = gridpoint.grid_pos - min.matrix();
59 Eigen::Array<Index, 3, 1> index = (pos / boxsize).floor().cast<
Index>();
60 boxes(index.x(), index.y(), index.z()).push_back(&gridpoint);
63 for (
auto& box : boxes) {
68 for (
const auto& point : box) {
78#pragma omp parallel for
83 std::vector<GridBox> grid_boxes_copy;
86 std::vector<bool> Merged = std::vector<bool>(
grid_boxes_.size(),
false);
102 grid_boxes_copy.push_back(box);
106 for (
auto& box : grid_boxes_copy) {
108 box.PrepareForIntegration();
114 std::vector<const Eigen::Vector3d*> gridpoints;
117 const std::vector<Eigen::Vector3d>& points = box.getGridPoints();
118 for (
const Eigen::Vector3d& point : points) {
119 gridpoints.push_back(&point);
126 Eigen::MatrixXd result = Eigen::MatrixXd::Zero(atoms.
size(), atoms.
size());
127#pragma omp parallel for
128 for (
Index i = 0; i < atoms.
size(); ++i) {
129 const Eigen::Vector3d& pos_a = atoms[i].
getPos();
130 for (
Index j = 0; j < i; ++j) {
131 const Eigen::Vector3d& pos_b = atoms[j].
getPos();
132 result(j, i) = 1 / (pos_a - pos_b).norm();
135 return result + result.transpose();
139 std::vector<double>& PruningIntervals,
146 }
else if (maxindex == 2) {
148 if (r < PruningIntervals[0]) {
150 }
else if ((r >= PruningIntervals[0]) && (r < PruningIntervals[3])) {
157 if (r < PruningIntervals[0]) {
159 }
else if ((r >= PruningIntervals[0]) && (r < PruningIntervals[1])) {
161 }
else if ((r >= PruningIntervals[1]) && (r < PruningIntervals[2])) {
162 constexpr Index maximum = 4;
164 std::max(maxindex - 1, maximum));
165 }
else if ((r >= PruningIntervals[2]) && (r < PruningIntervals[3])) {
168 constexpr Index maximum = 1;
170 std::max(maxindex - 1, maximum));
181 double p = spherical_grid.
phi[i_sph];
182 double t = spherical_grid.
theta[i_sph];
183 const Eigen::Vector3d s =
184 Eigen::Vector3d{sin(p) * cos(t), sin(p) * sin(t), cos(p)};
185 double r = radial_grid.
radius[i_rad];
186 gridpoint.
grid_pos = atomA_pos + r * s;
188 radial_grid.
weight[i_rad] * spherical_grid.
weight[i_sph];
194 std::vector<GridContainers::Cartesian_gridpoint>& atomgrid)
const {
195 Eigen::MatrixXd result = Eigen::MatrixXd::Zero(atoms.
size(), atomgrid.size());
196#pragma omp parallel for
197 for (
Index i = 0; i < atoms.
size(); ++i) {
198 const Eigen::Vector3d& atom_pos = atoms[i].
getPos();
199 for (
Index j = 0; j <
Index(atomgrid.size()); ++j) {
200 const auto& gridpoint = atomgrid[j];
201 result(i, j) = (atom_pos - gridpoint.grid_pos).norm();
209 std::vector<GridContainers::Cartesian_gridpoint>& atomgrid,
Index i_atom,
210 const Eigen::MatrixXd& Rij)
const {
213#pragma omp parallel for schedule(guided)
214 for (
Index i_grid = 0; i_grid <
Index(atomgrid.size()); i_grid++) {
215 Eigen::VectorXd p =
SSWpartition(AtomGridDist.col(i_grid), Rij);
217 double wsum = p.sum();
220 atomgrid[i_grid].grid_weight *= p[i_atom] / wsum;
222 std::cerr <<
"\nSum of partition weights of grid point " << i_grid
223 <<
" of atom " << i_atom <<
" is zero! ";
224 throw std::runtime_error(
"\nThis should never happen!");
243 std::vector<std::vector<GridContainers::Cartesian_gridpoint> > grid;
245 for (
Index i_atom = 0; i_atom < atoms.
size(); ++i_atom) {
246 const QMAtom& atom = atoms[i_atom];
248 const Eigen::Vector3d& atomA_pos = atom.
getPos();
258 std::vector<double> PruningIntervals =
260 Index current_order = 0;
262 std::vector<GridContainers::Cartesian_gridpoint> atomgrid;
263 for (
Index i_rad = 0; i_rad < radial_grid.
radius.size(); i_rad++) {
264 double r = radial_grid.
radius[i_rad];
268 UpdateOrder(sphericalgridofElement, maxorder, PruningIntervals, r);
270 if (order != current_order) {
272 current_order = order;
275 for (
Index i_sph = 0; i_sph < spherical_grid.
phi.size(); i_sph++) {
279 atomgrid.push_back(gridpoint);
285 std::vector<GridContainers::Cartesian_gridpoint> atomgrid_cleanedup;
286 for (
const auto& point : atomgrid) {
287 if (point.grid_weight > 1
e-13) {
288 atomgrid_cleanedup.push_back(point);
291 grid.push_back(atomgrid_cleanedup);
299 const Eigen::MatrixXd& Rij)
const {
300 const double ass = 0.725;
302 Eigen::VectorXd p = Eigen::VectorXd::Ones(rq_i.size());
303 const double tol_scr = 1
e-10;
304 const double leps = 1
e-6;
306 for (
Index i = 1; i < rq_i.size(); i++) {
307 double rag = rq_i(i);
309 for (
Index j = 0; j < i; j++) {
310 if ((std::abs(p[i]) > tol_scr) || (std::abs(p[j]) > tol_scr)) {
311 double mu = (rag - rq_i(j)) * Rij(j, i);
314 }
else if (mu < -ass) {
318 if (std::abs(mu) < leps) {
319 sk = -1.88603178008 * mu + 0.5;
327 p[i] = p[i] * (1.0 - sk);
336 const static double alpha_erf1 = 1.0 / 0.30;
337 return 0.5 * std::erfc(std::abs(x / (1.0 - x * x)) * alpha_erf1);
Container to hold Basisfunctions for all atoms.
const Eigen::Vector3d & getPos() const
std::vector< double > CalculatePruningIntervals(const std::string &element)
std::map< std::string, GridContainers::radial_grid > CalculateAtomicRadialGrids(const AOBasis &aobasis, const QMMolecule &atoms, const std::string &type)
void addGridBox(const GridBox &box)
static bool compareGridboxes(GridBox &box1, GridBox &box2)
void addGridPoint(const GridContainers::Cartesian_gridpoint &point)
std::map< std::string, radial_grid > radial_grids
std::map< std::string, spherical_grid > spherical_grids
Index getIndexFromOrder(Index order) const
Index getOrderFromIndex(Index index) const
std::map< std::string, GridContainers::spherical_grid > CalculateSphericalGrids(const QMMolecule &atoms, const std::string &type) const
Index Type2MaxOrder(const std::string &element, const std::string &type) const
GridContainers::spherical_grid CalculateUnitSphereGrid(const std::string &element, const std::string &type) const
const Eigen::Vector3d & getPos() const
const std::string & getElement() const
void FindSignificantShells(const AOBasis &basis)
GridContainers::Cartesian_gridpoint CreateCartesianGridpoint(const Eigen::Vector3d &atomA_pos, GridContainers::radial_grid &radial_grid, GridContainers::spherical_grid &spherical_grid, Index i_rad, Index i_sph) const
Eigen::VectorXd SSWpartition(const Eigen::VectorXd &rq_i, const Eigen::MatrixXd &Rij) const
Index getGridSize() const
std::vector< GridBox > grid_boxes_
void GridSetup(const std::string &type, const QMMolecule &atoms, const AOBasis &basis)
Index getBoxesSize() const
Index UpdateOrder(LebedevGrid &sphericalgridofElement, Index maxorder, std::vector< double > &PruningIntervals, double r) const
void SortGridpointsintoBlocks(const std::vector< std::vector< GridContainers::Cartesian_gridpoint > > &grid)
std::vector< const Eigen::Vector3d * > getGridpoints() const
Eigen::MatrixXd CalcDistanceAtomsGridpoints(const QMMolecule &atoms, std::vector< GridContainers::Cartesian_gridpoint > &atomgrid) const
void SSWpartitionAtom(const QMMolecule &atoms, std::vector< GridContainers::Cartesian_gridpoint > &atomgrid, Index i_atom, const Eigen::MatrixXd &Rij) const
Eigen::MatrixXd CalcInverseAtomDist(const QMMolecule &atoms) const
double erf1c(double x) const
base class for all analysis tools