Skip to content

Commit e5768ec

Browse files
authored
LRCG (#5399)
1 parent d9984c8 commit e5768ec

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3925,7 +3925,7 @@ Currently supported: `RPA`, `LDA`, `PBE`, `HSE`, `HF`.
39253925

39263926
- **Type**: String
39273927
- **Description**: The method to solve the Casida equation $AX=\Omega X$ in LR-TDDFT under Tamm-Dancoff approximation (TDA), where $A_{ai,bj}=(\epsilon_a-\epsilon_i)\delta_{ij}\delta_{ab}+(ai|f_{Hxc}|bj)+\alpha_{EX}(ab|ij)$ is the particle-hole excitation matrix and $X$ is the transition amplitude.
3928-
- `dav`: Construct $AX$ and diagonalize the Hamiltonian matrix iteratively with Davidson algorithm.
3928+
- `dav`/`dav_subspace`/ `cg`: Construct $AX$ and diagonalize the Hamiltonian matrix iteratively with Davidson/Non-ortho-Davidson/CG algorithm.
39293929
- `lapack`: Construct the full $A$ matrix and directly diagonalize with LAPACK.
39303930
- `spectrum`: Calculate absorption spectrum only without solving Casida equation. The `OUT.${suffix}/` directory should contain the
39313931
files for LR-TDDFT eigenstates and eigenvalues, i.e. `Excitation_Energy.dat` and `Excitation_Amplitude_${processor_rank}.dat`

source/module_hsolver/diago_iter_assist.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace hsolver
2020
// Produces on output n_band eigenvectors (n_band <= nstart) in evc.
2121
//----------------------------------------------------------------------
2222
template <typename T, typename Device>
23-
void DiagoIterAssist<T, Device>::diagH_subspace(hamilt::Hamilt<T, Device>* pHamilt, // hamiltonian operator carrier
23+
void DiagoIterAssist<T, Device>::diagH_subspace(const hamilt::Hamilt<T, Device>* const pHamilt, // hamiltonian operator carrier
2424
const psi::Psi<T, Device>& psi, // [in] wavefunction
2525
psi::Psi<T, Device>& evc, // [out] wavefunction
2626
Real* en, // [out] eigenvalues

source/module_hsolver/diago_iter_assist.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class DiagoIterAssist
2929
static int SCF_ITER;
3030

3131
// for psi::Psi structure
32-
static void diagH_subspace(hamilt::Hamilt<T, Device>* pHamilt,
32+
static void diagH_subspace(const hamilt::Hamilt<T, Device>* const pHamilt,
3333
const psi::Psi<T, Device>& psi,
3434
psi::Psi<T, Device>& evc,
3535
Real* en,

source/module_lr/esolver_lrtd_lcao.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ inline int cal_nupdown_form_occ(const ModuleBase::matrix& wg)
8686
template<typename T, typename TR>
8787
void LR::ESolver_LR<T, TR>::parameter_check()const
8888
{
89-
std::set<std::string> lr_solvers = { "dav", "lapack" , "spectrum", "dav_subspace" };
89+
std::set<std::string> lr_solvers = { "dav", "lapack" , "spectrum", "dav_subspace", "cg" };
9090
std::set<std::string> xc_kernels = { "rpa", "lda", "pbe", "hf" , "hse" };
9191
if (lr_solvers.find(this->input.lr_solver) == lr_solvers.end()) {
9292
throw std::invalid_argument("ESolver_LR: unknown type of lr_solver");

source/module_lr/hsolver_lrtd.hpp

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
#include "module_hsolver/diago_dav_subspace.h"
55
#include "module_hsolver/diago_cg.h"
66
#include "module_hsolver/diago_iter_assist.h"
7+
#include "module_hsolver/diago_cg.h"
78
#include "module_lr/utils/lr_util.h"
89
#include "module_lr/utils/lr_util_print.h"
10+
#include "module_base/module_container/ATen/core/tensor_map.h"
911

1012
namespace LR
1113
{
@@ -68,7 +70,7 @@ namespace LR
6870
// 3. set precondition and diagethr
6971
for (int i = 0; i < dim; ++i) { precondition[i] = static_cast<Real<T>>(1.0); }
7072

71-
const int david_maxiter = hsolver::DiagoIterAssist<T>::PW_DIAG_NMAX;
73+
const int maxiter = hsolver::DiagoIterAssist<T>::PW_DIAG_NMAX;
7274

7375
auto hpsi_func = [&hm](T* psi_in, T* hpsi, const int ld_psi, const int nvec) {hm.hPsi(psi_in, hpsi, ld_psi, nvec);};
7476
auto spsi_func = [&hm](const T* psi_in, T* spsi, const int ld_psi, const int nvec)
@@ -84,7 +86,7 @@ namespace LR
8486
// do diag and add davidson iteration counts up to avg_iter
8587
hsolver::DiagoDavid<T> david(precondition.data(), nband, dim, PARAM.inp.pw_diag_ndim, PARAM.inp.use_paw, comm_info);
8688
hsolver::DiagoIterAssist<T>::avg_iter += static_cast<double>(david.diag(hpsi_func, spsi_func,
87-
dim, psi, eigenvalue.data(), diag_ethr, david_maxiter, ntry_max, 0));
89+
dim, psi, eigenvalue.data(), diag_ethr, maxiter, ntry_max, 0));
8890
}
8991
else if (method == "dav_subspace") //need refactor
9092
{
@@ -93,7 +95,7 @@ namespace LR
9395
dim,
9496
PARAM.inp.pw_diag_ndim,
9597
diag_ethr,
96-
david_maxiter,
98+
maxiter,
9799
false, //always do the subspace diag (check the implementation)
98100
comm_info);
99101
std::vector<double> ethr_band(nband, diag_ethr);
@@ -105,6 +107,44 @@ namespace LR
105107
ethr_band.data(),
106108
false /*scf*/));
107109
}
110+
else if (method == "cg")
111+
{
112+
////// `diagH_subspace` needs refactor:
113+
////// replace `Hamilt*` with `hpsi_func`
114+
////// or I cannot use `is_subspace=true` as my `HamiltLR` does not inherit `Hamilt`.
115+
116+
// auto subspace_func = [&hm](const ct::Tensor& psi_in, ct::Tensor& psi_out) {
117+
// const auto ndim = psi_in.shape().ndim();
118+
// REQUIRES_OK(ndim == 2, "dims of psi_in should be less than or equal to 2");
119+
// // Convert a Tensor object to a psi::Psi object
120+
// auto psi_in_wrapper = psi::Psi<T>(psi_in.data<T>(),
121+
// 1,
122+
// psi_in.shape().dim_size(0),
123+
// psi_in.shape().dim_size(1));
124+
// auto psi_out_wrapper = psi::Psi<T>(psi_out.data<T>(),
125+
// 1,
126+
// psi_out.shape().dim_size(0),
127+
// psi_out.shape().dim_size(1));
128+
// auto eigen = ct::Tensor(ct::DataTypeToEnum<Real<T>>::value,
129+
// ct::DeviceType::CpuDevice,
130+
// ct::TensorShape({ psi_in.shape().dim_size(0) }));
131+
// hsolver::DiagoIterAssist<T>::diagH_subspace(hm, psi_in_wrapper, psi_out_wrapper, eigen.data<Real<T>>());
132+
// };
133+
134+
////// why diago_cg depends on basis_type?
135+
// hsolver::DiagoCG<T> cg("lcao", "nscf", true, subspace_func, diag_ethr, maxiter, GlobalV::NPROC_IN_POOL);
136+
137+
auto subspace_func = [](const ct::Tensor& psi_in, ct::Tensor& psi_out) {};
138+
hsolver::DiagoCG<T> cg("lcao", "nscf", false, subspace_func, diag_ethr, maxiter, GlobalV::NPROC_IN_POOL);
139+
140+
auto psi_tensor = ct::TensorMap(psi, ct::DataTypeToEnum<T>::value, ct::DeviceType::CpuDevice, ct::TensorShape({ nband, dim }));
141+
auto eigen_tensor = ct::TensorMap(eigenvalue.data(), ct::DataTypeToEnum<Real<T>>::value, ct::DeviceType::CpuDevice, ct::TensorShape({ nband }));
142+
auto precon_tensor = ct::TensorMap(precondition.data(), ct::DataTypeToEnum<Real<T>>::value, ct::DeviceType::CpuDevice, ct::TensorShape({ dim }));
143+
auto hpsi_func = [&hm](const ct::Tensor& psi_in, ct::Tensor& hpsi) {hm.hPsi(psi_in.data<T>(), hpsi.data<T>(), psi_in.shape().dim_size(0) /*nbasis_local*/, 1/*band-by-band*/);};
144+
auto spsi_func = [&hm](const ct::Tensor& psi_in, ct::Tensor& spsi)
145+
{ std::memcpy(spsi.data<T>(), psi_in.data<T>(), sizeof(T) * psi_in.NumElements()); };
146+
cg.diag(hpsi_func, spsi_func, psi_tensor, eigen_tensor, precon_tensor);
147+
}
108148
else { throw std::runtime_error("HSolverLR::solve: method not implemented"); }
109149
}
110150

0 commit comments

Comments
 (0)