MADNESS 0.10.1
BSHApply.h
Go to the documentation of this file.
1/*
2 * BSHApply.h
3 *
4 * Created on: Feb 26, 2020
5 * Author: fbischoff
6 */
7
8#ifndef SRC_APPS_CHEM_BSHAPPLY_H_
9#define SRC_APPS_CHEM_BSHAPPLY_H_
10
13
14namespace madness {
15
16/// apply the BSH operator on a vector of functions with corresponding potentials
17
18/// this class
19/// - constructs the bsh operator with the appropriate exponents
20/// - performs a level shift if necessary
21/// - adds coupling terms: ( T - fock(i,i) ) psi_i = -V psi_i + \sum_{j\neq i} psi_j fock(j,i)
22/// TODO: adding a level shift seems to make the operation less precise, why??
23template<typename T, std::size_t NDIM>
24class BSHApply {
25
26public:
29 double levelshift=0.0;
30 double lo=1.e-6;
31 double bshtol=1.e-5;
32 bool printme=false;
33 bool destroy_Vpsi=false;
35 return_value ret_value=residual; // return the new orbitals/functions or the residuals
36
37public:
39 metric() {
40 bshtol = FunctionDefaults <NDIM> ::get_thresh();
41 printme = printme and world.rank()==0;
42 }
43
44
45 /// apply the BSH operator on the vector of functions and respective potentials
46
47 /// @param[in] eps orbital energies or the square fock matrix
48 /// @param[in] Vpsi vector of functions V*MOs
49 /// @return an MO structure holding the residuals and the orbital energy updates
50 std::tuple<std::vector<Function<T,NDIM> >, Tensor<double> > operator()(
51 const std::vector<Function<T,NDIM> > psi,
52 const Tensor<T> eps,
53 const std::vector<Function<T,NDIM> >& Vpsi1) const {
54
55 double cpu0=cpu_time();
56 std::vector<Function<T,NDIM> > Vpsi=copy(world,Vpsi1);
57
58 // add coupling between the functions (i.e. in case of localized orbitals)
59 // ( T + V ) \psi_i = \sum_j \psi_j F_{ji}
60 // ( T - F_{ii}) \psi_i = -V \psi_i + \sum_{j\neq i} \psi_jF_{ji}
61 // no coupling means F_{ij} =\eps_i \delta_{ij}, and the coupling term vanishes
63
64 std::vector < std::shared_ptr<SeparatedConvolution<double,NDIM> > > ops(psi.size());
65 for (int i=0; i<eps.dim(0); ++i) {
66 T e_i= (eps.ndim()==2) ? eps(i,i) : eps(i);
67 if (printme) print("orbital energy for the BSH operator",e_i);
68 ops[i]=std::shared_ptr<SeparatedConvolution<double,NDIM> >(
69 BSHOperatorPtr<NDIM>(world, sqrt(-2.0*eps_in_green(e_i)), lo, bshtol));
70 ops[i]->destructive()=true;
71 }
72
73 const std::vector<Function<T,NDIM> > tmp = apply(world,ops,-2.0*Vpsi);
74 const std::vector<Function<T,NDIM> > res=truncate(psi-tmp,FunctionDefaults<NDIM>::get_thresh()*0.1);
75 const std::vector<Function<T,NDIM> > bra_res=make_bra(res);
76
77 // update eps
78 Tensor<double> norms=real(inner(world,make_bra(tmp),tmp));
79 Tensor<T> rnorms=inner(world,bra_res,res);
80 for (int i=0; i<norms.size(); ++i) {
81 norms(i)=sqrt(norms(i));
82 rnorms(i)=sqrt(rnorms(i));
83 }
84 if (printme) {
85 print("norm2(tmp)",norms);
86 print("norm2(res)",rnorms);
87 }
88
89 Tensor<T> in=inner(world,Vpsi,bra_res); // no shift here!
90 Tensor<double> delta_eps(psi.size());
91 for (size_t i=0; i<psi.size(); ++i) delta_eps(i)=std::real(in(i))/(norms[i]*norms[i]);
92
93 if (printme) print("orbital energy update",delta_eps);
94 double cpu1=cpu_time();
95 if (printme) printf("time in BSHApply() %8.4fs\n",cpu1-cpu0);
96
97 if (ret_value==update) return std::make_tuple(tmp,delta_eps);
98 else if (ret_value==residual) return std::make_tuple(res,delta_eps);
99 else {
100 MADNESS_EXCEPTION("unknown return value in BSHApply",1);
101 }
102 }
103
104
105 /// apply the BSH operator on the vector of functions and respective potentials
106
107 /// @param[in] arg the MO structure holding MOs and orbital energies
108 /// @param[in] Vpsi vector of functions V*MOs
109 /// @return an MO structure holding the residuals and the orbital energy updates
111 const std::vector<Function<T,NDIM> >& Vpsi) const {
112 std::tuple<std::vector<Function<T,NDIM>, Tensor<T> > > result;
113 result=this->operator()(arg.get_mos(),arg.get_eps(),Vpsi);
114 return result;
115 }
116
117 std::vector<Function<T,NDIM> > make_bra(const std::vector<Function<T,NDIM> >& rhs) const {
118 if (metric.is_initialized()) return metric*rhs;
119 return rhs;
120 }
121
122 /// limit the orbital energy (diagonal fock matrix element) entering the Green's function parameter mu
123 double eps_in_green(const T eps) const {
124
125 if (std::imag(eps)>1.e-12)
126 MADNESS_EXCEPTION("complex orbital energies in BSHApply",1);
127 return std::min(-0.05,std::real(eps)+levelshift);
128 }
129
130 std::vector<Function<T,NDIM> > add_coupling_and_levelshift(const std::vector<Function<T,NDIM> > psi,
131 const Tensor<T> fock1) const {
132
133 // check dimensions
134 bool consistent=(psi.size()==size_t(fock1.dim(0)));
135 if ((fock1.ndim()==2) and not (psi.size()==size_t(fock1.dim(1)))) consistent=false;
136
137 if (not consistent) {
138 print("Fock matrix dimensions",fock1.ndim(), fock1.dim(0), fock1.dim(1));
139 print("number of orbitals",psi.size());
140 MADNESS_EXCEPTION("confused Fock matrix/orbital energies in BSHApply - 1",1);
141 }
142
143 bool do_coupling=(fock1.ndim()==2);
144
145 // subtract the BSH energy (aka Fock diagonal elements) from the rhs
146 // ( T - fock(i,i) ) psi_i = -V psi_i + \sum_{j\neq i} psi_j fock(j,i)
147 // if there is no level shift and the orbital energies are large enough the
148 // diagonal should simply vanish.
149 if (do_coupling) {
150 Tensor<T> fock=copy(fock1);
151 for (int i=0; i<fock.dim(0); ++i) {
152 fock(i,i)-=eps_in_green(fock(i,i));
153 }
154 if (printme) {
155 print("coupling fock matrix");
156 print(fock);
157 }
158 return transform(world, psi, fock);
159
160 } else {
161 std::vector<T> eps(psi.size());
162 if (fock1.ndim()==1)
163 for (int i=0; i<fock1.dim(0); ++i) eps[i]=fock1(i)-eps_in_green(fock1(i));
164 if (fock1.ndim()==2)
165 for (int i=0; i<fock1.dim(0); ++i) eps[i]=fock1(i,i)-eps_in_green(fock1(i,i));
166
167 std::vector<Function<T,NDIM> > result=copy(world,psi);
168 scale(world,result,eps);
169 return result;
170 }
171
172 }
173
174};
175} // namespace madness
176
177
178#endif /* SRC_APPS_CHEM_BSHAPPLY_H_ */
This header should include pretty much everything needed for the parallel runtime.
apply the BSH operator on a vector of functions with corresponding potentials
Definition BSHApply.h:24
double bshtol
Definition BSHApply.h:31
bool destroy_Vpsi
Definition BSHApply.h:33
double levelshift
Definition BSHApply.h:29
std::tuple< std::vector< Function< T, NDIM > >, Tensor< double > > operator()(const std::vector< Function< T, NDIM > > psi, const Tensor< T > eps, const std::vector< Function< T, NDIM > > &Vpsi1) const
apply the BSH operator on the vector of functions and respective potentials
Definition BSHApply.h:50
Function< double, NDIM > metric
Definition BSHApply.h:34
return_value ret_value
Definition BSHApply.h:35
double eps_in_green(const T eps) const
limit the orbital energy (diagonal fock matrix element) entering the Green's function parameter mu
Definition BSHApply.h:123
std::vector< Function< T, NDIM > > make_bra(const std::vector< Function< T, NDIM > > &rhs) const
Definition BSHApply.h:117
double lo
Definition BSHApply.h:30
bool printme
Definition BSHApply.h:32
MolecularOrbitals< T, NDIM > operator()(const MolecularOrbitals< T, NDIM > &arg, const std::vector< Function< T, NDIM > > &Vpsi) const
apply the BSH operator on the vector of functions and respective potentials
Definition BSHApply.h:110
World & world
Definition BSHApply.h:28
std::vector< Function< T, NDIM > > add_coupling_and_levelshift(const std::vector< Function< T, NDIM > > psi, const Tensor< T > fock1) const
Definition BSHApply.h:130
BSHApply(World &world)
Definition BSHApply.h:38
return_value
Definition BSHApply.h:27
@ residual
Definition BSHApply.h:27
@ update
Definition BSHApply.h:27
long dim(int i) const
Returns the size of dimension i.
Definition basetensor.h:147
long ndim() const
Returns the number of dimensions in the tensor.
Definition basetensor.h:144
long size() const
Returns the number of elements in the tensor.
Definition basetensor.h:138
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:204
A multiresolution adaptive numerical function.
Definition mra.h:122
bool is_initialized() const
Returns true if the function is initialized.
Definition mra.h:147
Definition MolecularOrbitals.h:24
std::vector< Function< T, NDIM > > get_mos() const
Definition MolecularOrbitals.h:64
A tensor is a multidimension array.
Definition tensor.h:317
A parallel world class.
Definition world.h:132
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:318
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition tensor.h:2502
double psi(const Vector< double, 3 > &r)
Definition hatom_energy.cc:78
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
static double cpu_time()
Returns the cpu time in seconds relative to an arbitrary origin.
Definition timers.h:127
response_space scale(response_space a, double b)
void truncate(World &world, response_space &v, double tol, bool fence)
Definition basic_operators.cc:30
std::vector< Function< TENSOR_RESULT_TYPE(T, R), NDIM > > transform(World &world, const std::vector< Function< T, NDIM > > &v, const Tensor< R > &c, bool fence=true)
Transforms a vector of functions according to new[i] = sum[j] old[j]*c[j,i].
Definition vmra.h:689
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:225
response_space apply(World &world, std::vector< std::vector< std::shared_ptr< real_convolution_3d > > > &op, response_space &f)
Definition basic_operators.cc:39
double inner(response_space &a, response_space &b)
Definition response_functions.h:442
double real(double x)
Definition complexfun.h:52
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence.
Definition mra.h:2002