Changeset 889c27


Ignore:
Timestamp:
Mar 11, 2013, 11:33:01 PM (13 years ago)
Author:
Frederik Heber <heber@…>
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)
Message:

We sample electron density if MPQCData::DoLongrange says so.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/bin/mpqc/mpqc.cc

    r8d3df9 r889c27  
    16311631//       }
    16321632     }
    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;
    16441650       }
    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           }
    16621665         }
    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();
    17471751           }
    1748            r.z() = min.z();
     1752           r.y() = min.y();
    17491753         }
    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         }
    17721775       }
    17731776     }
     
    19021905  // put info how to sample the density into MPQCData
    19031906  MPQCData data(grid);
     1907  data.DoLongrange = DoLongrange; // set whether we sample the density
    19041908// now call work horse
    19051909  mainFunction(grp, values, output, input, generic_input, in_char_array, argc, argv, data);
Note: See TracChangeset for help on using the changeset viewer.