/*
* Copyright 2009-2019 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.
*
*/
#pragma once
#ifndef __XTP_THREECENTER__H
#define __XTP_THREECENTER__H
#include <array>
#include <votca/xtp/eigen.h>
#include <votca/xtp/logger.h>
#include <votca/xtp/symmetric_matrix.h>
#ifdef USE_CUDA
#include "cudapipeline.h"
#endif
/**
* \brief Calculates three electron overlap integrals for GW and DFT.
*
*
*
*/
namespace votca {
namespace xtp {
class AOShell;
class AOBasis;
// due to different requirements for the data format for DFT and GW we have two
// different classes TCMatrix_gwbse and TCMatrix_dft which inherit from TCMatrix
class TCMatrix {
public:
Index Removedfunctions() const { return _removedfunctions; }
protected:
Index _removedfunctions = 0;
Eigen::MatrixXd _inv_sqrt;
bool FillThreeCenterRepBlock(Eigen::Tensor<double, 3>& threec_block,
const AOShell& shell, const AOShell& shell_row,
const AOShell& shell_col) const;
};
class TCMatrix_dft : public TCMatrix {
public:
void Fill(const AOBasis& auxbasis, const AOBasis& dftbasis);
Index size() const { return Index(_matrix.size()); }
Symmetric_Matrix& operator[](Index i) { return _matrix[i]; }
const Symmetric_Matrix& operator[](Index i) const { return _matrix[i]; }
private:
std::vector<Symmetric_Matrix> _matrix;
void FillBlock(std::vector<Eigen::MatrixXd>& block, Index shellindex,
const AOBasis& dftbasis, const AOBasis& auxbasis);
};
class TCMatrix_gwbse : public TCMatrix {
public:
TCMatrix_gwbse(Logger& log) : _log{log} {};
// returns one level as a constant reference
const Eigen::MatrixXd& operator[](Index i) const { return _matrix[i]; }
// returns one level as a reference
Eigen::MatrixXd& operator[](Index i) { return _matrix[i]; }
// returns auxbasissize
Index auxsize() const { return _auxbasissize; }
Index get_mmin() const { return _mmin; }
Index get_mmax() const { return _mmax; }
Index get_nmin() const { return _nmin; }
Index get_nmax() const { return _nmax; }
Index msize() const { return _mtotal; }
Index nsize() const { return _ntotal; }
void Initialize(Index basissize, Index mmin, Index mmax, Index nmin,
Index nmax);
void Fill(const AOBasis& auxbasis, const AOBasis& dftbasis,
const Eigen::MatrixXd& dft_orbitals);
// Rebuilds ThreeCenterIntegrals, only works if the original basisobjects
// still exist
void Rebuild() { Fill(*_auxbasis, *_dftbasis, *_dft_orbitals); }
void MultiplyRightWithAuxMatrix(const Eigen::MatrixXd& AuxMatrix);
private:
// store vector of matrices
std::vector<Eigen::MatrixXd> _matrix;
// Logger
Logger& _log;
// band summation indices
Index _mmin;
Index _mmax;
Index _nmin;
Index _nmax;
Index _ntotal;
Index _mtotal;
Index _auxbasissize;
const AOBasis* _auxbasis = nullptr;
const AOBasis* _dftbasis = nullptr;
const Eigen::MatrixXd* _dft_orbitals = nullptr;
std::vector<Eigen::MatrixXd> FillBlock(
const std::vector<Eigen::MatrixXd>& symmstorage,
const Eigen::MatrixXd& dft_orbitals) const;
void MultiplyRightWithAuxMatrixOpenMP(const Eigen::MatrixXd& AuxMatrix);
void FillAllBlocksOpenMP(const AOBasis& gwbasis, const AOBasis& dftbasis,
const Eigen::MatrixXd& dft_orbitals);
std::vector<Eigen::MatrixXd> ComputeSymmStorage(
const AOShell& auxshell, const AOBasis& dftbasis) const;
#if defined(USE_CUDA)
std::array<CudaMatrix, 2> SendDFTMatricesToGPU(
const Eigen::MatrixXd& dft_orbitals, const CudaPipeline& cuda_pip) const;
std::array<CudaMatrix, 3> CreateIntermediateCudaMatrices(
Index basissize, const CudaPipeline& cuda_pip) const;
void FillAllBlocksCuda(const AOBasis& gwbasis, const AOBasis& dftbasis,
const Eigen::MatrixXd& dft_orbitals);
void MultiplyRightWithAuxMatrixCuda(const Eigen::MatrixXd& matrix);
std::vector<Eigen::MatrixXd> FillBlockCUDA(
const std::vector<Eigen::MatrixXd>& symmstorage,
const std::array<CudaMatrix, 2>& cuda_matrices,
std::array<CudaMatrix, 3>& cuda_inter_matrices,
const CudaPipeline& cuda_pip) const;
#endif
};
} // namespace xtp
} // namespace votca
#endif /* AOMATRIX_H */