Changeset 889c27
- Timestamp:
- Mar 11, 2013, 11:33:01 PM (13 years ago)
- Children:
- d13755
- Parents:
- 8d3df9
- git-author:
- Frederik Heber <heber@…> (03/06/13 21:33:55)
- git-committer:
- Frederik Heber <heber@…> (03/11/13 23:33:01)
- File:
-
- 1 edited
-
src/bin/mpqc/mpqc.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/bin/mpqc/mpqc.cc
r8d3df9 r889c27 1631 1631 // } 1632 1632 } 1633 { 1634 // fill positions and charges (NO LONGER converting from bohr radii to angstroem) 1635 const double AtomicLengthToAngstroem = 1.;//0.52917721; 1636 data.positions.reserve(wfn->molecule()->natom()); 1637 data.charges.reserve(wfn->molecule()->natom()); 1638 for (int iatom=0;iatom < wfn->molecule()->natom(); ++iatom) { 1639 data.charges.push_back(wfn->molecule()->Z(iatom)); 1640 std::vector<double> pos(3, 0.); 1641 for (int j=0;j<3;++j) 1642 pos[j] = wfn->molecule()->r(iatom, j)*AtomicLengthToAngstroem; 1643 data.positions.push_back(pos); 1633 // we do sample the density only on request 1634 if (data.DoLongrange) { 1635 { 1636 // fill positions and charges (NO LONGER converting from bohr radii to angstroem) 1637 const double AtomicLengthToAngstroem = 1.;//0.52917721; 1638 data.positions.reserve(wfn->molecule()->natom()); 1639 data.charges.reserve(wfn->molecule()->natom()); 1640 for (int iatom=0;iatom < wfn->molecule()->natom(); ++iatom) { 1641 data.charges.push_back(wfn->molecule()->Z(iatom)); 1642 std::vector<double> pos(3, 0.); 1643 for (int j=0;j<3;++j) 1644 pos[j] = wfn->molecule()->r(iatom, j)*AtomicLengthToAngstroem; 1645 data.positions.push_back(pos); 1646 } 1647 std::cout << "We have " 1648 << data.positions.size() << " positions and " 1649 << data.charges.size() << " charges." << std::endl; 1644 1650 } 1645 std::cout << "We have " 1646 << data.positions.size() << " positions and " 1647 << data.charges.size() << " charges." << std::endl; 1648 } 1649 if (data.sampled_grid.level != 0) 1650 { 1651 // we now need to sample the density on the grid 1652 // 1. get max and min over all basis function positions 1653 assert( scf->basis()->ncenter() > 0 ); 1654 SCVector3 bmin( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) ); 1655 SCVector3 bmax( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) ); 1656 for (int nr = 1; nr< scf->basis()->ncenter(); ++nr) { 1657 for (int i=0; i < 3; ++i) { 1658 if (scf->basis()->r(nr,i) < bmin(i)) 1659 bmin(i) = scf->basis()->r(nr,i); 1660 if (scf->basis()->r(nr,i) > bmax(i)) 1661 bmax(i) = scf->basis()->r(nr,i); 1651 if (data.sampled_grid.level != 0) 1652 { 1653 // we now need to sample the density on the grid 1654 // 1. get max and min over all basis function positions 1655 assert( scf->basis()->ncenter() > 0 ); 1656 SCVector3 bmin( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) ); 1657 SCVector3 bmax( scf->basis()->r(0,0), scf->basis()->r(0,1), scf->basis()->r(0,2) ); 1658 for (int nr = 1; nr< scf->basis()->ncenter(); ++nr) { 1659 for (int i=0; i < 3; ++i) { 1660 if (scf->basis()->r(nr,i) < bmin(i)) 1661 bmin(i) = scf->basis()->r(nr,i); 1662 if (scf->basis()->r(nr,i) > bmax(i)) 1663 bmax(i) = scf->basis()->r(nr,i); 1664 } 1662 1665 } 1663 } 1664 std::cout << "Basis min is at " << bmin << " and max is at " << bmax << std::endl; 1665 1666 // 2. choose an appropriately large grid 1667 // we have to pay attention to capture the right amount of the exponential decay 1668 // and also to have a power of two size of the grid at best 1669 SCVector3 boundaryV(5.); // boundary extent around compact domain containing basis functions 1670 bmin -= boundaryV; 1671 bmax += boundaryV; 1672 for (size_t i=0;i<3;++i) { 1673 if (bmin(i) < data.sampled_grid.begin[i]) 1674 bmin(i) = data.sampled_grid.begin[i]; 1675 if (bmax(i) > data.sampled_grid.end[i]) 1676 bmax(i) = data.sampled_grid.end[i]; 1677 } 1678 // set the non-zero window of the sampled_grid 1679 data.sampled_grid.setWindow(bmin.data(), bmax.data()); 1680 1681 // for the moment we always generate a grid of full size 1682 // (NO LONGER converting grid dimensions from angstroem to bohr radii) 1683 const double AtomicLengthToAngstroem = 1.;//0.52917721; 1684 SCVector3 min; 1685 SCVector3 max; 1686 SCVector3 delta; 1687 size_t samplepoints[3]; 1688 // due to periodic boundary conditions, we don't need gridpoints-1 here 1689 // TODO: in case of open boundary conditions, we need data on the right 1690 // hand side boundary as well 1691 const int gridpoints = data.sampled_grid.getGridPointsPerAxis(); 1692 for (size_t i=0;i<3;++i) { 1693 min(i) = data.sampled_grid.begin_window[i]/AtomicLengthToAngstroem; 1694 max(i) = data.sampled_grid.end_window[i]/AtomicLengthToAngstroem; 1695 delta(i) = data.sampled_grid.getDeltaPerAxis(i)/AtomicLengthToAngstroem; 1696 samplepoints[i] = data.sampled_grid.getWindowGridPointsPerAxis(i); 1697 } 1698 std::cout << "Grid starts at " << min 1699 << " and ends at " << max 1700 << " with a delta of " << delta 1701 << " to get " 1702 << samplepoints[0] << "," 1703 << samplepoints[1] << "," 1704 << samplepoints[2] << " samplepoints." 1705 << std::endl; 1706 assert( data.sampled_grid.sampled_grid.size() == samplepoints[0]*samplepoints[1]*samplepoints[2]); 1707 1708 // 3. sample the atomic density 1709 const double element_volume_conversion = 1710 1./AtomicLengthToAngstroem/AtomicLengthToAngstroem/AtomicLengthToAngstroem; 1711 SCVector3 r = min; 1712 1713 // taken from scf::density() 1714 RefSCMatrix nos 1715 = scf->integral()->petite_list()->evecs_to_AO_basis(scf->natural_orbitals()); 1716 RefDiagSCMatrix nd = scf->natural_density(); 1717 GaussianBasisSet::ValueData *valdat 1718 = new GaussianBasisSet::ValueData(scf->basis(), scf->integral()); 1719 std::vector<double>::iterator griditer = data.sampled_grid.sampled_grid.begin(); 1720 const int nbasis = scf->basis()->nbasis(); 1721 double *bs_values = new double[nbasis]; 1722 1723 for (size_t x = 0; x < samplepoints[0]; ++x, r.x() += delta(0)) { 1724 std::cout << "Sampling now for x=" << r.x() << std::endl; 1725 for (size_t y = 0; y < samplepoints[1]; ++y, r.y() += delta(1)) { 1726 for (size_t z = 0; z < samplepoints[2]; ++z, r.z() += delta(2)) { 1727 scf->basis()->values(r,valdat,bs_values); 1728 1729 // loop over natural orbitals adding contributions to elec_density 1730 double elec_density=0.0; 1731 for (int i=0; i<nbasis; ++i) { 1732 double tmp = 0.0; 1733 for (int j=0; j<nbasis; ++j) { 1734 tmp += nos.get_element(j,i)*bs_values[j]; 1735 } 1736 elec_density += nd.get_element(i)*tmp*tmp; 1737 } 1738 const double dens_at_r = elec_density * element_volume_conversion; 1739 // const double dens_at_r = scf->density(r) * element_volume_conversion; 1740 1741 // if (fabs(dens_at_r) > 1e-4) 1742 // std::cout << "Electron density at " << r << " is " << dens_at_r << std::endl; 1743 if (griditer != data.sampled_grid.sampled_grid.end()) 1744 *griditer++ = dens_at_r; 1745 else 1746 std::cerr << "PAST RANGE!" << std::endl; 1666 std::cout << "Basis min is at " << bmin << " and max is at " << bmax << std::endl; 1667 1668 // 2. choose an appropriately large grid 1669 // we have to pay attention to capture the right amount of the exponential decay 1670 // and also to have a power of two size of the grid at best 1671 SCVector3 boundaryV(5.); // boundary extent around compact domain containing basis functions 1672 bmin -= boundaryV; 1673 bmax += boundaryV; 1674 for (size_t i=0;i<3;++i) { 1675 if (bmin(i) < data.sampled_grid.begin[i]) 1676 bmin(i) = data.sampled_grid.begin[i]; 1677 if (bmax(i) > data.sampled_grid.end[i]) 1678 bmax(i) = data.sampled_grid.end[i]; 1679 } 1680 // set the non-zero window of the sampled_grid 1681 data.sampled_grid.setWindow(bmin.data(), bmax.data()); 1682 1683 // for the moment we always generate a grid of full size 1684 // (NO LONGER converting grid dimensions from angstroem to bohr radii) 1685 const double AtomicLengthToAngstroem = 1.;//0.52917721; 1686 SCVector3 min; 1687 SCVector3 max; 1688 SCVector3 delta; 1689 size_t samplepoints[3]; 1690 // due to periodic boundary conditions, we don't need gridpoints-1 here 1691 // TODO: in case of open boundary conditions, we need data on the right 1692 // hand side boundary as well 1693 const int gridpoints = data.sampled_grid.getGridPointsPerAxis(); 1694 for (size_t i=0;i<3;++i) { 1695 min(i) = data.sampled_grid.begin_window[i]/AtomicLengthToAngstroem; 1696 max(i) = data.sampled_grid.end_window[i]/AtomicLengthToAngstroem; 1697 delta(i) = data.sampled_grid.getDeltaPerAxis(i)/AtomicLengthToAngstroem; 1698 samplepoints[i] = data.sampled_grid.getWindowGridPointsPerAxis(i); 1699 } 1700 std::cout << "Grid starts at " << min 1701 << " and ends at " << max 1702 << " with a delta of " << delta 1703 << " to get " 1704 << samplepoints[0] << "," 1705 << samplepoints[1] << "," 1706 << samplepoints[2] << " samplepoints." 1707 << std::endl; 1708 assert( data.sampled_grid.sampled_grid.size() == samplepoints[0]*samplepoints[1]*samplepoints[2]); 1709 1710 // 3. sample the atomic density 1711 const double element_volume_conversion = 1712 1./AtomicLengthToAngstroem/AtomicLengthToAngstroem/AtomicLengthToAngstroem; 1713 SCVector3 r = min; 1714 1715 // taken from scf::density() 1716 RefSCMatrix nos 1717 = scf->integral()->petite_list()->evecs_to_AO_basis(scf->natural_orbitals()); 1718 RefDiagSCMatrix nd = scf->natural_density(); 1719 GaussianBasisSet::ValueData *valdat 1720 = new GaussianBasisSet::ValueData(scf->basis(), scf->integral()); 1721 std::vector<double>::iterator griditer = data.sampled_grid.sampled_grid.begin(); 1722 const int nbasis = scf->basis()->nbasis(); 1723 double *bs_values = new double[nbasis]; 1724 1725 for (size_t x = 0; x < samplepoints[0]; ++x, r.x() += delta(0)) { 1726 std::cout << "Sampling now for x=" << r.x() << std::endl; 1727 for (size_t y = 0; y < samplepoints[1]; ++y, r.y() += delta(1)) { 1728 for (size_t z = 0; z < samplepoints[2]; ++z, r.z() += delta(2)) { 1729 scf->basis()->values(r,valdat,bs_values); 1730 1731 // loop over natural orbitals adding contributions to elec_density 1732 double elec_density=0.0; 1733 for (int i=0; i<nbasis; ++i) { 1734 double tmp = 0.0; 1735 for (int j=0; j<nbasis; ++j) { 1736 tmp += nos.get_element(j,i)*bs_values[j]; 1737 } 1738 elec_density += nd.get_element(i)*tmp*tmp; 1739 } 1740 const double dens_at_r = elec_density * element_volume_conversion; 1741 // const double dens_at_r = scf->density(r) * element_volume_conversion; 1742 1743 // if (fabs(dens_at_r) > 1e-4) 1744 // std::cout << "Electron density at " << r << " is " << dens_at_r << std::endl; 1745 if (griditer != data.sampled_grid.sampled_grid.end()) 1746 *griditer++ = dens_at_r; 1747 else 1748 std::cerr << "PAST RANGE!" << std::endl; 1749 } 1750 r.z() = min.z(); 1747 1751 } 1748 r. z() = min.z();1752 r.y() = min.y(); 1749 1753 } 1750 r.y() = min.y(); 1751 } 1752 delete[] bs_values; 1753 delete valdat; 1754 assert( griditer == data.sampled_grid.sampled_grid.end()); 1755 // normalization of electron charge to equal electron number 1756 { 1757 double integral_value = 0.; 1758 const double volume_element = pow(AtomicLengthToAngstroem,3)*delta(0)*delta(1)*delta(2); 1759 for (std::vector<double>::const_iterator diter = data.sampled_grid.sampled_grid.begin(); 1760 diter != data.sampled_grid.sampled_grid.end(); ++diter) 1761 integral_value += *diter; 1762 integral_value *= volume_element; 1763 const double normalization = 1764 ((integral_value == 0) && (scf->nelectron() == 0)) ? 1765 1. : scf->nelectron()/integral_value; 1766 std::cout << "Created " << data.sampled_grid.sampled_grid.size() << " grid points" 1767 << " with integral value of " << integral_value 1768 << " against nelectron of " << scf->nelectron() << "." << std::endl; 1769 for (std::vector<double>::iterator diter = data.sampled_grid.sampled_grid.begin(); 1770 diter != data.sampled_grid.sampled_grid.end(); ++diter) 1771 *diter *= normalization; 1754 delete[] bs_values; 1755 delete valdat; 1756 assert( griditer == data.sampled_grid.sampled_grid.end()); 1757 // normalization of electron charge to equal electron number 1758 { 1759 double integral_value = 0.; 1760 const double volume_element = pow(AtomicLengthToAngstroem,3)*delta(0)*delta(1)*delta(2); 1761 for (std::vector<double>::const_iterator diter = data.sampled_grid.sampled_grid.begin(); 1762 diter != data.sampled_grid.sampled_grid.end(); ++diter) 1763 integral_value += *diter; 1764 integral_value *= volume_element; 1765 const double normalization = 1766 ((integral_value == 0) && (scf->nelectron() == 0)) ? 1767 1. : scf->nelectron()/integral_value; 1768 std::cout << "Created " << data.sampled_grid.sampled_grid.size() << " grid points" 1769 << " with integral value of " << integral_value 1770 << " against nelectron of " << scf->nelectron() << "." << std::endl; 1771 for (std::vector<double>::iterator diter = data.sampled_grid.sampled_grid.begin(); 1772 diter != data.sampled_grid.sampled_grid.end(); ++diter) 1773 *diter *= normalization; 1774 } 1772 1775 } 1773 1776 } … … 1902 1905 // put info how to sample the density into MPQCData 1903 1906 MPQCData data(grid); 1907 data.DoLongrange = DoLongrange; // set whether we sample the density 1904 1908 // now call work horse 1905 1909 mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv, data);
Note:
See TracChangeset
for help on using the changeset viewer.
