Codebase list votca-xtp / debian/1.5-1 src / libxtp / threecenter_dft.cc
debian/1.5-1

Tree @debian/1.5-1 (Download .tar.gz)

threecenter_dft.cc @debian/1.5-1raw · history · blame

/* 
 *            Copyright 2009-2018 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *              http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/xtp/threecenter.h>
#include <votca/xtp/symmetric_matrix.h>
#include <votca/xtp/eigen.h>

namespace votca {
  namespace xtp {

    void TCMatrix_dft::Fill(AOBasis& auxbasis, AOBasis& dftbasis, const Eigen::MatrixXd& V_sqrtm1) {

      for (int i = 0; i < auxbasis.AOBasisSize(); i++) {
        try {
          _matrix.push_back(Symmetric_Matrix(dftbasis.AOBasisSize()));
        } catch (std::bad_alloc& ba) {
          std::cerr << "Basisset/aux basis too large for 3c calculation. Not enough RAM. Caught bad alloc: " << ba.what() << std::endl;
          exit(0);
        }

      }
      #pragma omp parallel for schedule(dynamic)
      for (int is = dftbasis.getNumofShells()-1; is >=0; is--) {
        const Eigen::MatrixXd V=V_sqrtm1;
        const AOShell& dftshell = dftbasis.getShell(is);
        std::vector< Eigen::MatrixXd > block;
        for (int i = 0; i < dftshell.getNumFunc(); i++) {
          int size = dftshell.getStartIndex() + i+1;
          block.push_back(Eigen::MatrixXd::Zero(auxbasis.AOBasisSize(), size));
        }
        FillBlock(block, is, dftbasis, auxbasis);
        int offset = dftshell.getStartIndex();
        for (unsigned i = 0; i < block.size(); ++i) {
          Eigen::MatrixXd temp =V * block[i];
          for (int mu = 0; mu < temp.rows(); ++mu) {
            for (int j = 0; j < temp.cols(); ++j) {
              _matrix[mu](i + offset, j) = temp(mu, j);
            }
          }
        }
      }
      return;
    }

    /*
     * Determines the 3-center integrals for a given shell in the aux basis
     * by calculating the 3-center overlap integral of the functions in the
     * aux shell with ALL functions in the DFT basis set (FillThreeCenterOLBlock)
     */

    void TCMatrix_dft::FillBlock(std::vector< Eigen::MatrixXd >& block, int shellindex, const AOBasis& dftbasis, const AOBasis& auxbasis) {
      const AOShell& left_dftshell = dftbasis.getShell(shellindex);
      tensor3d::extent_gen extents;
      int start = left_dftshell.getStartIndex();
      // alpha-loop over the aux basis function
      for (const AOShell& shell_aux:auxbasis) {
        int aux_start = shell_aux.getStartIndex();


        for (int is = 0; is <= shellindex; is++) {

          const AOShell& shell_col = dftbasis.getShell(is);
          int col_start=shell_col.getStartIndex();
          tensor3d threec_block(extents[ range(0, shell_aux.getNumFunc()) ][ range(0, left_dftshell.getNumFunc()) ][ range(0, shell_col.getNumFunc())]);
          for (int i = 0; i < shell_aux.getNumFunc(); ++i) {
            for (int j = 0; j < left_dftshell.getNumFunc(); ++j) {
              for (int k = 0; k < shell_col.getNumFunc(); ++k) {
                threec_block[i][j][k] = 0.0;
              }
            }
          }

          bool nonzero = FillThreeCenterRepBlock(threec_block, shell_aux, left_dftshell, shell_col);
          if (nonzero) {

            for (int left = 0; left < left_dftshell.getNumFunc(); left++) {
              for (int aux = 0; aux < shell_aux.getNumFunc(); aux++) {
                for (int col = 0; col < shell_col.getNumFunc(); col++) {
                  //symmetry
                  if ((col_start + col)>(start + left)) {
                    break;
                  }
                  block[left](aux_start + aux, col_start + col) = threec_block[aux][left][col];
                }
              }
            }
          }
        }
      }
      return;
    }






  }
}