MADNESS 0.10.1
diamagneticpotentialfactor.h
Go to the documentation of this file.
1/*
2 * diamagneticpotentialfactor.h
3 *
4 * Created on: 16 Apr 2019
5 * Author: fbischoff
6 */
7
8#ifndef SRC_APPS_CHEM_DIAMAGNETICPOTENTIALFACTOR_H_
9#define SRC_APPS_CHEM_DIAMAGNETICPOTENTIALFACTOR_H_
10
11
12#include <madness/mra/mra.h>
14
15namespace madness {
16
17
18/// to be put in a separate file
20
21public:
22
23 /// constructor takes a world and the parameters for the calculation
25 const std::vector<coord_3d>& coords)
27
28 use_v_vector=param.use_v_vector();
29 physical_B={0,0,param.physical_B()};
30 explicit_B={0,0,param.explicit_B()};
31
33
34 potential_radius=param.potential_radius();
35
36 // initialize all functions to their default values
37 diamagnetic_factor_=real_factory_3d(world).functor([] (const coord_3d& r) {return 1.0;});
38 diamagnetic_factor_square=real_factory_3d(world).functor([] (const coord_3d& r) {return 1.0;});
39 diamagnetic_U2=real_factory_3d(world).functor([] (const coord_3d& r) {return 0.0;});
40 diamagnetic_U1=zero_functions<double,3>(world,3);
41
43 if (param.printlevel()>9) print_info();
44 }
45
50
51 static std::vector<coord_3d> compute_v_vector(const coord_3d& B,
52 const std::vector<coord_3d>& coords, bool use_v_vector) {
53 std::vector<coord_3d> v;
54 if (use_v_vector) {
55 for (auto& c : coords) v.push_back(0.5*cross(B,c));
56 } else {
57 v=std::vector<coord_3d> (1,{0.0,0.0,0.0});
58 }
59 return v;
60 }
61
62
63 void print_info() const;
64
65 /// return the diamagnetic factor
67
68 /// return the square of the diamagnetic factor
70
71 /// return a custom factor for a given magnetic field
72 real_function_3d custom_factor(const coord_3d& B, const std::vector<coord_3d>& vv,
73 const double extra_exponent=1.0) const {
74 const double absB=B.normf();
75 if (absB==0.0) return real_factory_3d(world).functor([](const coord_3d& r){return 1.0;}).truncate_on_project();
76 const double& ee=extra_exponent;
77 auto diamagnetic_HO = [&absB, &B, &vv, &ee](const coord_3d& r) {
78 double result=0.0;
79 const coord_3d A=0.5*cross(B,r);
80 for (auto& v : vv) {
82 result+=exp(-1.0/absB*inner(arg,arg));
83 }
84 if (ee!=1.0) result=std::pow(result,ee);
85 return result;
86 };
87 real_function_3d result=real_factory_3d(world).functor(diamagnetic_HO);
88 return result;
89 }
90
91
92 /// return a custom factor for a given magnetic field
93 complex_function_3d factor_with_phase(const coord_3d& B, const std::vector<coord_3d>& vv) const {
94 const double absB=B.normf();
95 if (absB==0.0) return complex_factory_3d(world).functor([](const coord_3d& r){return 1.0;}).truncate_on_project();
96 auto diamagnetic_HO = [&absB, &B, &vv](const coord_3d& r) {
97 double result=0.0;
98 const coord_3d A=0.5*cross(B,r);
99 for (auto& v : vv) {
100 coord_3d arg=A-v;
101 result+=exp(-1.0/absB*inner(arg,arg));
102 }
103 double theta=acos(r[2]/r.normf());
104 double phi=atan2(r[1],r[0]);
105 double_complex phase=r.normf()*sin(theta)*exp(absB*double_complex(0.0,1.0)*phi);
106 return result*phase;
107 };
108 complex_function_3d result=complex_factory_3d(world).functor(diamagnetic_HO);
109 return result;
110 }
111
112 /// compute the bare potential without confinement or factors
115 const double b_square=inner(physical_B,physical_B);
117 .functor([& b_square](const coord_3d& r){return 0.125*b_square*(r[0]*r[0] + r[1]*r[1]);});
118 return result;
119 }
120
121 /// apply the diamagnetic potential on rhs
122 std::vector<complex_function_3d> apply_potential(const std::vector<complex_function_3d>& rhs) const;
123
124 /// make sure the magnetic field is oriented along the z axis
125 static bool B_along_z(const coord_3d& B) {
126 return((B[0]==0.0) && (B[1]==0.0));
127 }
128
129 std::vector<coord_3d> get_v() const {return v;}
130 std::vector<coord_3d> get_coords() const {return coords;}
131
133
135
136 /// given the explicit and the physical B, estimate the radius
137 /// of the wave function
138 double estimate_wavefunction_radius(const double eps=1.e-8) const {
139 double remaining_B=(get_physical_B()-get_explicit_B()).normf();
140 return 2.0*sqrt(-log(eps)/remaining_B);
141 }
142
143private:
144 World& world; ///< the world
145 coord_3d physical_B={0,0,0}; ///< the actual magnetic field strength
146 coord_3d explicit_B={0,0,0}; ///< the magnetic field strength encoded in the diamagnetic factor
147
148 /// the diamagnetic factor to cancel the diamagnetic potential
151
152 /// radius where the diamagnetic potential flattens out
154
155 /// the boxed diamagnetic potential (for a given B)
157 std::vector<real_function_3d> diamagnetic_U1;
158
159 /// the position of the nuclei in the coordinate space:
160 std::vector<coord_3d> coords;
161
162 /// the position of the nuclei in the "A" space: v = 1/2 B cross R
163 std::vector<coord_3d> v;
164
165 bool use_v_vector=true;
166
167public:
168 /// recompute the factor and the potentials for given physical and explicit magnetic fields
170
171 /// compute the commutator of the orbital-zeeman term with the diamagnetic factor
172
173 /// @return a local potential: iB \sum_i \vec r \cdot \vec v_i
175
178
179 /// returns \f$R^{-1} \vec\nabla R\f$
180 std::vector<real_function_3d> compute_nabla_R_div_R() const;
181
182 /// run the tests
183
184 /// @param[in] level: 1: basic tests, .. , 3: all the tests
185 bool test_me(const int level) const {
186 bool success=true;
187 if ((level<1) or (level>3)) {
188 print("testing diamagneticpotentialfactor with an invalid level of ",level);
189 }
190 if (level<2) {
191 success=test_factor() and success;
192 success=test_lz_commutator() and success;
193 success=test_harmonic_potential() and success;
194 success=test_scalar_potentials() and success;
195 success=test_vector_potentials() and success;
196 }
197 if (level<3) {
198 ;
199 }
200 if (level<4) {
201 ;
202 }
203 return success;
204 }
205
206private:
207
208
209 /// compute a factor for comparison in coordinate space
210 bool test_factor() const;
211
212 /// test the harmonic potential
213 bool test_harmonic_potential() const;
214
215 /// test analytical vs numerical computation of the potentials
216 bool test_scalar_potentials() const;
217
218 /// test analytical vs numerical computation of the potentials
219 bool test_vector_potentials() const;
220
221 bool test_lz_commutator() const;
222
223public:
224 /// make a set orbitals for testing (not orthonormalized!)
225 std::vector<complex_function_3d> make_fake_orbitals(const int n,
226 const coord_3d& offset={0.0,0.0,0.0}) const;
227
228 /// compute the radius for the diamagnetic potential
229 double get_potential_radius() const {
230 return potential_radius;
231 }
232
233};
234
235
236} /* namespace madness */
237
238#endif /* SRC_APPS_CHEM_DIAMAGNETICPOTENTIALFACTOR_H_ */
std::complex< double > double_complex
Definition cfft.h:14
Definition test_ar.cc:118
Definition test_ar.cc:141
to be put in a separate file
Definition diamagneticpotentialfactor.h:19
real_function_3d custom_factor(const coord_3d &B, const std::vector< coord_3d > &vv, const double extra_exponent=1.0) const
return a custom factor for a given magnetic field
Definition diamagneticpotentialfactor.h:72
static std::vector< coord_3d > compute_v_vector(const coord_3d &B, const std::vector< coord_3d > &coords, bool use_v_vector)
Definition diamagneticpotentialfactor.h:51
static bool B_along_z(const coord_3d &B)
make sure the magnetic field is oriented along the z axis
Definition diamagneticpotentialfactor.h:125
real_function_3d diamagnetic_factor_square
Definition diamagneticpotentialfactor.h:150
real_function_3d diamagnetic_factor_
the diamagnetic factor to cancel the diamagnetic potential
Definition diamagneticpotentialfactor.h:149
double estimate_wavefunction_radius(const double eps=1.e-8) const
Definition diamagneticpotentialfactor.h:138
bool test_me(const int level) const
run the tests
Definition diamagneticpotentialfactor.h:185
std::vector< real_function_3d > compute_nabla_R_div_R() const
returns
Definition diamagneticpotentialfactor.cc:188
complex_function_3d compute_lz_commutator() const
compute the commutator of the orbital-zeeman term with the diamagnetic factor
Definition diamagneticpotentialfactor.cc:135
real_function_3d factor_square() const
return the square of the diamagnetic factor
Definition diamagneticpotentialfactor.h:69
bool test_scalar_potentials() const
test analytical vs numerical computation of the potentials
Definition diamagneticpotentialfactor.cc:306
std::vector< complex_function_3d > make_fake_orbitals(const int n, const coord_3d &offset={0.0, 0.0, 0.0}) const
make a set orbitals for testing (not orthonormalized!)
Definition diamagneticpotentialfactor.cc:369
coord_3d explicit_B
the magnetic field strength encoded in the diamagnetic factor
Definition diamagneticpotentialfactor.h:146
coord_3d get_explicit_B() const
Definition diamagneticpotentialfactor.h:132
std::vector< complex_function_3d > apply_potential(const std::vector< complex_function_3d > &rhs) const
apply the diamagnetic potential on rhs
Definition diamagneticpotentialfactor.cc:216
World & world
the world
Definition diamagneticpotentialfactor.h:144
double get_potential_radius() const
compute the radius for the diamagnetic potential
Definition diamagneticpotentialfactor.h:229
bool test_harmonic_potential() const
test the harmonic potential
Definition diamagneticpotentialfactor.cc:282
bool test_vector_potentials() const
test analytical vs numerical computation of the potentials
Definition diamagneticpotentialfactor.cc:327
real_function_3d compute_U2() const
Definition diamagneticpotentialfactor.cc:151
void print_info() const
Definition diamagneticpotentialfactor.cc:110
std::vector< coord_3d > coords
the position of the nuclei in the coordinate space:
Definition diamagneticpotentialfactor.h:160
std::vector< coord_3d > v
the position of the nuclei in the "A" space: v = 1/2 B cross R
Definition diamagneticpotentialfactor.h:163
real_function_3d bare_diamagnetic_potential() const
compute the bare potential without confinement or factors
Definition diamagneticpotentialfactor.h:113
std::vector< coord_3d > get_v() const
Definition diamagneticpotentialfactor.h:129
Diamagnetic_potential_factor(World &world, const Nemo_complex_Parameters &param, const std::vector< coord_3d > &coords)
constructor takes a world and the parameters for the calculation
Definition diamagneticpotentialfactor.h:24
real_function_3d factor() const
return the diamagnetic factor
Definition diamagneticpotentialfactor.h:66
void recompute_factors_and_potentials()
recompute the factor and the potentials for given physical and explicit magnetic fields
Definition diamagneticpotentialfactor.cc:122
std::vector< coord_3d > get_coords() const
Definition diamagneticpotentialfactor.h:130
coord_3d physical_B
the actual magnetic field strength
Definition diamagneticpotentialfactor.h:145
bool test_factor() const
compute a factor for comparison in coordinate space
Definition diamagneticpotentialfactor.cc:239
coord_3d get_physical_B() const
Definition diamagneticpotentialfactor.h:134
complex_function_3d factor_with_phase(const coord_3d &B, const std::vector< coord_3d > &vv) const
return a custom factor for a given magnetic field
Definition diamagneticpotentialfactor.h:93
bool test_lz_commutator() const
Definition diamagneticpotentialfactor.cc:349
real_function_3d diamagnetic_U2
the boxed diamagnetic potential (for a given B)
Definition diamagneticpotentialfactor.h:156
bool use_v_vector
Definition diamagneticpotentialfactor.h:165
real_function_3d compute_R_times_T_commutator_scalar_term_numerically() const
Definition diamagneticpotentialfactor.cc:176
double potential_radius
radius where the diamagnetic potential flattens out
Definition diamagneticpotentialfactor.h:153
void reset_explicit_B_and_v(const coord_3d &eB)
Definition diamagneticpotentialfactor.h:46
std::vector< real_function_3d > diamagnetic_U1
Definition diamagneticpotentialfactor.h:157
T normf() const
Calculate the 2-norm of the vector elements.
Definition vector.h:400
A parallel world class.
Definition world.h:132
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
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
Main include file for MADNESS and defines Function interface.
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
std::vector< Function< TENSOR_RESULT_TYPE(T, R), NDIM > > cross(const std::vector< Function< T, NDIM > > &f, const std::vector< Function< R, NDIM > > &g, bool do_refine=false, bool fence=true)
shorthand cross operator
Definition vmra.h:2070
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:93
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
double inner(response_space &a, response_space &b)
Definition response_functions.h:442
FunctionFactory< double_complex, 3 > complex_factory_3d
Definition functypedefs.h:100
static double phase(long i)
Definition twoscale.cc:85
static const double c
Definition relops.cc:10
InputParameters param
Definition tdse.cc:203
const double offset
Definition testfuns.cc:143