ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
evolve_elec.h
Go to the documentation of this file.
1#ifndef W_ABACUS_DEVELOP_ABACUS_DEVELOP_SOURCE_MODULE_HAMILT_LCAO_MODULE_TDDFT_EVOLVE_ELEC_H
2#define W_ABACUS_DEVELOP_ABACUS_DEVELOP_SOURCE_MODULE_HAMILT_LCAO_MODULE_TDDFT_EVOLVE_ELEC_H
3
8#include "source_base/module_device/device.h" // base_device
9#include "source_base/module_device/memory_op.h" // memory operations
14#include "source_psi/psi.h"
15
16//-----------------------------------------------------------
17// mohan add 2021-02-09
18// This class is used to evolve the electronic wave functions
19// in TDDFT in terms of the multiple k points
20// k is the index for the points in the first Brillouin zone
21//-----------------------------------------------------------
22
23//------------------------ Debugging utility function ------------------------//
24
25// Print the shape of a Tensor
26inline void print_tensor_shape(const ct::Tensor& tensor, const std::string& name)
27{
28 std::cout << "Shape of " << name << ": [";
29 for (int i = 0; i < tensor.shape().ndim(); ++i)
30 {
31 std::cout << tensor.shape().dim_size(i);
32 if (i < tensor.shape().ndim() - 1)
33 {
34 std::cout << ", ";
35 }
36 }
37 std::cout << "]" << std::endl;
38}
39
40// Recursive print function
41template <typename T>
42inline void print_tensor_data_recursive(const T* data,
43 const std::vector<int64_t>& shape,
44 const std::vector<int64_t>& strides,
45 int dim,
46 std::vector<int64_t>& indices,
47 const std::string& name)
48{
49 if (dim == shape.size())
50 {
51 // Recursion base case: print data when reaching the innermost dimension
52 std::cout << name;
53 for (size_t i = 0; i < indices.size(); ++i)
54 {
55 std::cout << "[" << indices[i] << "]";
56 }
57 std::cout << " = " << *data << std::endl;
58 return;
59 }
60 // Recursively process the current dimension
61 for (int64_t i = 0; i < shape[dim]; ++i)
62 {
63 indices[dim] = i;
64 print_tensor_data_recursive(data + i * strides[dim], shape, strides, dim + 1, indices, name);
65 }
66}
67
68// Generic print function
69template <typename T>
70inline void print_tensor_data(const ct::Tensor& tensor, const std::string& name)
71{
72 const std::vector<int64_t>& shape = tensor.shape().dims();
73 const std::vector<int64_t>& strides = tensor.shape().strides();
74 const T* data = tensor.data<T>();
75 std::vector<int64_t> indices(shape.size(), 0);
76 print_tensor_data_recursive(data, shape, strides, 0, indices, name);
77}
78
79// Specialization for std::complex<double>
80template <>
81inline void print_tensor_data<std::complex<double>>(const ct::Tensor& tensor, const std::string& name)
82{
83 const std::vector<int64_t>& shape = tensor.shape().dims();
84 const std::vector<int64_t>& strides = tensor.shape().strides();
85 const std::complex<double>* data = tensor.data<std::complex<double>>();
86 std::vector<int64_t> indices(shape.size(), 0);
87 print_tensor_data_recursive(data, shape, strides, 0, indices, name);
88}
89
90//------------------------ Debugging utility function ------------------------//
91
92namespace module_rt
93{
94#ifdef __MPI
95//------------------------ MPI gathering and distributing functions ------------------------//
96template <typename T>
97void gatherPsi(const int myid,
98 const int root_proc,
99 T* psi_l,
100 const Parallel_Orbitals& para_orb,
102{
103 const int* desc_psi = para_orb.desc_wfc; // Obtain the descriptor from Parallel_Orbitals
104 int ctxt = desc_psi[1]; // BLACS context
105 int nrows = desc_psi[2]; // Global matrix row number
106 int ncols = desc_psi[3]; // Global matrix column number
107
108 if (myid == root_proc)
109 {
110 psi_g.p.reset(new T[nrows * ncols]); // No need to delete[] since it is a shared_ptr
111 }
112 else
113 {
114 psi_g.p.reset(new T[nrows * ncols]); // Placeholder for non-root processes
115 }
116
117 // Set the descriptor of the global psi
118 psi_g.desc.reset(new int[9]{1, ctxt, nrows, ncols, nrows, ncols, 0, 0, nrows});
119 psi_g.row = nrows;
120 psi_g.col = ncols;
121
122 // Call the Cpxgemr2d function in ScaLAPACK to collect the matrix data
123 Cpxgemr2d(nrows, ncols, psi_l, 1, 1, const_cast<int*>(desc_psi), psi_g.p.get(), 1, 1, psi_g.desc.get(), ctxt);
124}
125
126template <typename T>
127void distributePsi(const Parallel_Orbitals& para_orb, T* psi_l, const ModuleESolver::Matrix_g<T>& psi_g)
128{
129 const int* desc_psi = para_orb.desc_wfc; // Obtain the descriptor from Parallel_Orbitals
130 int ctxt = desc_psi[1]; // BLACS context
131 int nrows = desc_psi[2]; // Global matrix row number
132 int ncols = desc_psi[3]; // Global matrix column number
133
134 // Call the Cpxgemr2d function in ScaLAPACK to distribute the matrix data
135 Cpxgemr2d(nrows, ncols, psi_g.p.get(), 1, 1, psi_g.desc.get(), psi_l, 1, 1, const_cast<int*>(desc_psi), ctxt);
136}
137//------------------------ MPI gathering and distributing functions ------------------------//
138#endif // __MPI
139
140template <typename Device = base_device::DEVICE_CPU>
142{
143 friend class ModuleESolver::ESolver_KS_LCAO<std::complex<double>, double>;
144
145 // Template parameter is needed for the friend class declaration
146 friend class ModuleESolver::ESolver_KS_LCAO_TDDFT<double, Device>;
147 friend class ModuleESolver::ESolver_KS_LCAO_TDDFT<std::complex<double>, Device>;
148
149 public:
150 Evolve_elec();
151 ~Evolve_elec();
152
153 private:
154 static void solve_psi(const int& istep,
155 const int nband,
156 const int nlocal,
157 const int& nks,
158 hamilt::Hamilt<std::complex<double>>* phm,
159 Parallel_Orbitals& para_orb,
160 psi::Psi<std::complex<double>>* psi,
161 psi::Psi<std::complex<double>>* psi_laststep,
162 std::complex<double>** Hk_laststep,
163 std::complex<double>** Sk_laststep,
164 ModuleBase::matrix& ekb,
165 std::ofstream& ofs_running,
166 const int htype,
167 const int propagator,
168 const bool use_tensor,
169 const bool use_lapack);
170
171 // ct_device_type = ct::DeviceType::CpuDevice or ct::DeviceType::GpuDevice
173 // ct_Device = ct::DEVICE_CPU or ct::DEVICE_GPU
174 using ct_Device = typename ct::PsiToContainer<Device>::type;
175
176 // Memory operations
177 using syncmem_double_h2d_op = base_device::memory::synchronize_memory_op<double, Device, base_device::DEVICE_CPU>;
178 using syncmem_double_d2h_op = base_device::memory::synchronize_memory_op<double, base_device::DEVICE_CPU, Device>;
180 = base_device::memory::synchronize_memory_op<std::complex<double>, Device, base_device::DEVICE_CPU>;
182 = base_device::memory::synchronize_memory_op<std::complex<double>, base_device::DEVICE_CPU, Device>;
183};
184} // namespace module_rt
185#endif
Definition esolver_ks_lcao_tddft.h:54
Definition esolver_ks_lcao.h:50
Definition parallel_orbitals.h:9
int desc_wfc[9]
Definition parallel_orbitals.h:37
int64_t dim_size(int dim) const
Get the size of a dimension in the tensor.
Definition tensor_shape.cpp:31
const std::vector< int64_t > & dims() const
Get all dimension sizes in the tensor.
Definition tensor_shape.cpp:36
unsigned int ndim() const
Get the ndim of the tensor.
Definition tensor_shape.cpp:46
const std::vector< int64_t > & strides() const
Definition tensor_shape.cpp:41
A multi-dimensional array of elements of a single data type.
Definition tensor.h:32
void * data() const
Get a pointer to the data buffer of the tensor.
Definition tensor.cpp:73
const TensorShape & shape() const
Get the shape of the tensor.
Definition tensor.cpp:67
Definition evolve_elec.h:142
static ct::DeviceType ct_device_type
Definition evolve_elec.h:172
typename ct::PsiToContainer< Device >::type ct_Device
Definition evolve_elec.h:174
static void solve_psi(const int &istep, const int nband, const int nlocal, const int &nks, hamilt::Hamilt< std::complex< double > > *phm, Parallel_Orbitals &para_orb, psi::Psi< std::complex< double > > *psi, psi::Psi< std::complex< double > > *psi_laststep, std::complex< double > **Hk_laststep, std::complex< double > **Sk_laststep, ModuleBase::matrix &ekb, std::ofstream &ofs_running, const int htype, const int propagator, const bool use_tensor, const bool use_lapack)
Definition evolve_elec.cpp:23
std::complex< double > complex
Definition diago_cusolver.cpp:13
void print_tensor_data_recursive(const T *data, const std::vector< int64_t > &shape, const std::vector< int64_t > &strides, int dim, std::vector< int64_t > &indices, const std::string &name)
Definition evolve_elec.h:42
void print_tensor_shape(const ct::Tensor &tensor, const std::string &name)
Definition evolve_elec.h:26
void print_tensor_data(const ct::Tensor &tensor, const std::string &name)
Definition evolve_elec.h:70
#define T
Definition exp.cpp:237
DeviceType
The type of memory used by an allocator.
Definition tensor_types.h:73
Definition band_energy.cpp:11
void distributePsi(const Parallel_Orbitals &para_orb, T *psi_l, const ModuleESolver::Matrix_g< T > &psi_g)
Definition evolve_elec.h:127
void gatherPsi(const int myid, const int root_proc, T *psi_l, const Parallel_Orbitals &para_orb, ModuleESolver::Matrix_g< T > &psi_g)
Definition evolve_elec.h:97
std::enable_if< block2d_data_type< T >::value, void >::type Cpxgemr2d(int M, int N, T *A, int IA, int JA, int *DESCA, T *B, int IB, int JB, int *DESCB, int ICTXT)
Definition scalapack_connector.h:186
Definition esolver_ks_lcao_tddft.h:17
std::shared_ptr< T > p
Definition esolver_ks_lcao_tddft.h:18
size_t row
Definition esolver_ks_lcao_tddft.h:19
size_t col
Definition esolver_ks_lcao_tddft.h:20
std::shared_ptr< int > desc
Definition esolver_ks_lcao_tddft.h:21
Definition tensor_types.h:113