MADNESS  0.10.1
esolver.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id$
32 */
33 /*
34  * File: esolver.h
35  * Author: wsttiger
36  *
37  * Created on April 17, 2009, 12:12 PM
38  */
39 
40 #ifndef _ESOLVER_H
41 #define _ESOLVER_H
42 
43 typedef std::shared_ptr< WorldDCPmapInterface< Key<3> > > pmapT;
44 typedef Vector<double,3> coordT;
45 typedef std::shared_ptr< FunctionFunctorInterface<std::complex<double>,3> > functorT;
46 typedef std::shared_ptr< FunctionFunctorInterface<double,3> > rfunctorT;
47 typedef Function<std::complex<double>,3> functionT;
48 typedef Function<std::complex<double>,3> cfunctionT;
49 typedef Function<double,3> rfunctionT;
50 typedef std::vector<functionT> vecfuncT;
51 typedef std::vector<rfunctionT> rvecfuncT;
52 typedef std::vector<cfunctionT> cvecfuncT;
53 typedef Tensor< std::complex<double> > ctensorT;
54 typedef Tensor<double> rtensorT;
55 typedef FunctionFactory<std::complex<double>,3> factoryT;
56 typedef FunctionFactory<double,3> rfactoryT;
57 typedef SeparatedConvolution<double,3> operatorT;
58 typedef std::shared_ptr<operatorT> poperatorT;
59 
60 void print_cube(World& world, const Function<double,3>& f, int npts)
61 {
62  f.reconstruct();
63  if (world.rank() == 0) printf("\n");
64  Tensor<double> csize = FunctionDefaults<3>::get_cell_width();
65 
66  for (int i = 0; i < npts; i++)
67  {
68  for (int j = 0; j < npts; j++)
69  {
70  for (int k = 0; k < npts; k++)
71  {
72  double x = (i+0.5) * (csize[0]/npts) - csize[0]/2;
73  double y = (j+0.5) * (csize[1]/npts) - csize[1]/2;
74  double z = (k+0.5) * (csize[2]/npts) - csize[2]/2;
75  coordT p(0.0);
76  p[0] = x; p[1] = y; p[2] = z;
77  if (world.rank() == 0)
78  printf("%10.2f%10.2f%10.2f%15.8f\n", x, y, z, f(p));
79  }
80  }
81  }
82 }
83 
84 void print_cube(World& world, const Function<double,3>& f1, const Function<double,3>& f2, int npts)
85 {
86  f1.reconstruct();
87  f2.reconstruct();
88  if (world.rank() == 0) printf("\n");
89  Tensor<double> csize = FunctionDefaults<3>::get_cell_width();
90 
91  for (int i = 0; i < npts; i++)
92  {
93  for (int j = 0; j < npts; j++)
94  {
95  for (int k = 0; k < npts; k++)
96  {
97  double x = (i+0.5) * (csize[0]/npts) - csize[0]/2;
98  double y = (j+0.5) * (csize[1]/npts) - csize[1]/2;
99  double z = (k+0.5) * (csize[2]/npts) - csize[2]/2;
100  coordT p(0.0);
101  p[0] = x; p[1] = y; p[2] = z;
102  if (world.rank() == 0)
103  printf("%10.2f%10.2f%10.2f%15.8f%15.8f\n", x, y, z, f1(p), f2(p));
104  }
105  }
106  }
107 }
108 
109 void print_cube(World& world, const Function<double,3>& f1, const Function<double,3>& f2,
110  const Function<double,3>& f3, int npts)
111 {
112  f1.reconstruct();
113  f2.reconstruct();
114  f3.reconstruct();
115  if (world.rank() == 0) printf("\n");
116  Tensor<double> csize = FunctionDefaults<3>::get_cell_width();
117 
118  for (int i = 0; i < npts; i++)
119  {
120  for (int j = 0; j < npts; j++)
121  {
122  for (int k = 0; k < npts; k++)
123  {
124  double x = (i+0.5) * (csize[0]/npts) - csize[0]/2;
125  double y = (j+0.5) * (csize[1]/npts) - csize[1]/2;
126  double z = (k+0.5) * (csize[2]/npts) - csize[2]/2;
127  coordT p(0.0);
128  p[0] = x; p[1] = y; p[2] = z;
129  if (world.rank() == 0)
130  printf("%10.2f%10.2f%10.2f%15.8f%15.8f%15.8f\n", x, y, z, f1(p), f2(p), f3(p));
131  }
132  }
133  }
134 }
135 
136 struct KPoint
137 {
139  double weight;
140  // the first wavefunction for this k-point has index begin
141  // the last wavefunction for this k-point has index end-1
142  unsigned int begin;
143  unsigned int end;
144 
146  {
147  k[0] = 0.0; k[1] = 0.0; k[2] = 0.0;
148  weight = 0.0;
149  begin = -1;
150  end = -1;
151  }
152 
153  KPoint(const coordT& k, const double& weight, const int& begin,
154  const int& end)
155  : k(k), weight(weight), begin(begin), end(end) {}
156 
157  KPoint(const coordT& k, const double& weight)
158  : k(k), weight(weight), begin(-1), end(-1) {}
159 
160  KPoint(const double& k0, const double& k1, const double& k2, const double& weight)
161  : weight(weight), begin(-1), end(-1)
162  {
163  k[0] = k0; k[1] = k1; k[2] = k2;
164  }
165 
166  bool is_orb_in_kpoint(unsigned int idx)
167  {
168  return ((idx >= begin) && (idx < end)) ? true : false;
169  }
170 
171  template <typename Archive>
172  void serialize(Archive& ar) {
173  ar & k & weight & begin & end;
174  }
175 
176 };
177 
178 std::istream& operator >> (std::istream& is, KPoint& kpt)
179 {
180  for (unsigned int i = 0; i < kpt.k.size(); i++)
181  is >> kpt.k[i];
182  is >> kpt.weight;
183  is >> kpt.begin;
184  is >> kpt.end;
185 
186  return is;
187 }
188 
189  //***************************************************************************
190  bool is_equal(double val1, double val2, double eps)
191  {
192  double d = fabs(val1-val2);
193  return (fabs(d) <= eps) ? true : false;
194  }
195  //***************************************************************************
196 
197 // //***************************************************************************
198 // template <typename Q, int NDIM>
199 // Function<Q,NDIM> pdiff(const Function<Q,NDIM>& f, int axis, bool fence = true)
200 // {
201 // Function<Q,NDIM>& g = const_cast< Function<Q,NDIM>& >(f);
202 // // Check for periodic boundary conditions
203 // Tensor<int> oldbc = g.get_bc();
204 // Tensor<int> bc(NDIM,2);
205 // bc(___) = 1;
206 // g.set_bc(bc);
207 // // Do calculation
208 // Function<Q,NDIM> rf = diff(g,axis,fence);
209 // // Restore previous boundary conditions
210 // g.set_bc(oldbc);
211 // return rf;
212 // }
213 // //***************************************************************************
214 
215  //***************************************************************************
216  template <typename Q, int NDIM>
218  const std::vector< Function<std::complex<Q>,NDIM> >& v,
219  const bool periodic,
220  const KPoint k = KPoint(coordT(0.0), 0.0))
221  {
222  reconstruct(world, v);
223  int n = v.size();
224  ctensorT c(n, n);
225  const std::complex<double> I = std::complex<double>(0.0, 1.0);
226  double k0 = k.k[0];
227  double k1 = k.k[1];
228  double k2 = k.k[2];
229  double ksquared = k0*k0 + k1*k1 + k2*k2;
230  if (periodic)
231  {
232  complex_derivative_3d Dx(world,0);
233  complex_derivative_3d Dy(world,1);
234  complex_derivative_3d Dz(world,2);
235  for (int i = 0; i < n; i++)
236  {
237  for (int j = 0; j <= i; j++)
238  {
239 // functionT dv2_j = pdiff(pdiff(v[j], 0), 0) +
240 // pdiff(pdiff(v[j], 1), 1) +
241 // pdiff(pdiff(v[j], 2), 2);
242 // functionT dv_j = std::complex<Q>(0.0, 2.0*k0) * pdiff(v[j], 0) +
243 // std::complex<Q>(0.0, 2.0*k1) * pdiff(v[j], 1) +
244 // std::complex<Q>(0.0, 2.0*k2) * pdiff(v[j], 2);
245  functionT dv2_j = Dx(Dx(v[j])) + Dy(Dy(v[j])) + Dz(Dz(v[j]));
246  functionT dv_j = std::complex<Q>(0.0, 2.0*k0) * Dx(v[j]) +
247  std::complex<Q>(0.0, 2.0*k1) * Dy(v[j]) +
248  std::complex<Q>(0.0, 2.0*k2) * Dz(v[j]);
249  functionT tmp = (ksquared*v[j]) - dv_j - dv2_j;
250  c(i, j) = inner(v[i], tmp);
251  c(j, i) = conj(c(i, j));
252  }
253  }
254  }
255  else
256  {
257  std::vector< std::shared_ptr < Derivative< std::complex<Q>,NDIM> > > gradop =
258  gradient_operator<std::complex<Q>,NDIM>(world);
259  for (int axis = 0; axis < 3; axis++)
260  {
261  vecfuncT dv = apply(world, *(gradop[axis]), v);
262  c += matrix_inner(world, dv, dv, true);
263  dv.clear(); // Allow function memory to be freed
264  }
265  }
266  return c.scale(0.5);
267  }
268 
269 
270  //***************************************************************************
271  template <typename Q, int NDIM>
273  const std::vector< Function<std::complex<Q>,NDIM> >& v,
274  const bool periodic,
275  const KPoint k = KPoint(coordT(0.0), 0.0))
276  {
277  const std::complex<double> I = std::complex<double>(0.0, 1.0);
278  const std::complex<double> one = std::complex<double>(1.0, 0.0);
279 
280  int n = v.size();
281  ctensorT c(n, n);
282  std::vector< std::shared_ptr < Derivative< std::complex<Q>,NDIM> > > gradop =
283  gradient_operator<std::complex<Q>,NDIM>(world);
284  for (int axis = 0; axis < 3; axis++) {
285  reconstruct(world, v);
286  vecfuncT dv = apply(world, *(gradop[axis]), v);
287  if (periodic) {
288  compress(world,v);
289  compress(world,dv);
290  for (int i=0; i<n; i++) dv[i].gaxpy(one, v[i], I*k.k[axis], false);
291  world.gop.fence();
292  }
293  c += matrix_inner(world, dv, dv, true);
294  dv.clear(); // Allow function memory to be freed
295  }
296  return c.scale(0.5);
297  }
298  //***************************************************************************
299 
300  //***************************************************************************
301  template <typename Q, int NDIM>
303  const std::vector< Function<std::complex<Q>,NDIM> >& v)
304  {
305  const std::complex<double> I = std::complex<double>(0.0, 1.0);
306  const std::complex<double> one = std::complex<double>(1.0, 0.0);
307 
308  int n = v.size();
309  ctensorT c(n, n);
310  std::vector< std::shared_ptr < Derivative< std::complex<Q>,NDIM> > > gradop =
311  gradient_operator<std::complex<Q>,NDIM>(world);
312  for (int axis = 0; axis < 3; axis++) {
313  reconstruct(world, v);
314  vecfuncT dv = apply(world, *(gradop[axis]), v);
315  c += matrix_inner(world, dv, dv, true);
316  dv.clear(); // Allow function memory to be freed
317  }
318  return c.scale(0.5);
319  }
320  //***************************************************************************
321 
322 // //***************************************************************************
323 // template <typename Q, int NDIM>
324 // ctensorT kinetic_energy_matrix(World& world,
325 // const std::vector< Function<Q,NDIM> >& v,
326 // const bool periodic,
327 // const KPoint k = KPoint(coordT(0.0), 0.0))
328 // {
329 // reconstruct(world, v);
330 // int n = v.size();
331 // ctensorT c(n, n);
332 // const std::complex<double> I = std::complex<double>(0.0, 1.0);
333 // double k0 = k.k[0];
334 // double k1 = k.k[1];
335 // double k2 = k.k[2];
336 // if (periodic)
337 // {
338 // for (int i = 0; i < n; i++)
339 // {
340 // functionT dv_i_0 = function_real2complex(pdiff(v[i], 0)) + I * k0 * v[i];
341 // functionT dv_i_1 = function_real2complex(pdiff(v[i], 1)) + I * k1 * v[i];
342 // functionT dv_i_2 = function_real2complex(pdiff(v[i], 2)) + I * k2 * v[i];
343 // for (int j = 0; j <= i; j++)
344 // {
345 // functionT dv_j_0 = function_real2complex(pdiff(v[j], 0)) - I * k0 * v[j];
346 // functionT dv_j_1 = function_real2complex(pdiff(v[j], 1)) - I * k1 * v[j];
347 // functionT dv_j_2 = function_real2complex(pdiff(v[j], 2)) - I * k2 * v[j];
348 // c(i, j) = inner(dv_i_0, dv_j_0) + inner(dv_i_1, dv_j_1) + inner(dv_i_2, dv_j_2);
349 // c(j, i) = conj(c(i, j));
350 // }
351 // }
352 // }
353 // else
354 // {
355 // rtensorT r(n, n);
356 // for (int axis = 0; axis < 3; axis++)
357 // {
358 // rvecfuncT dv = diff(world, v, axis);
359 // r += matrix_inner(world, dv, dv, true);
360 // dv.clear(); // Allow function memory to be freed
361 // }
362 // c = ctensorT(r);
363 // }
364 // return c.scale(0.5);
365 // }
366 // //***************************************************************************
367 
368 
369 
370 
371 #endif /* _ESOLVER_H */
372 
size_type size() const
Accessor for the number of elements in the Vector.
Definition: vector.h:276
double(* f)(const coord_3d &)
Definition: derivatives.cc:54
double(* f1)(const coord_3d &)
Definition: derivatives.cc:55
double(* f3)(const coord_3d &)
Definition: derivatives.cc:57
double(* f2)(const coord_3d &)
Definition: derivatives.cc:56
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
std::shared_ptr< WorldDCPmapInterface< Key< 3 > > > pmapT
Definition: esolver.h:43
Function< std::complex< double >, 3 > cfunctionT
Definition: esolver.h:48
std::istream & operator>>(std::istream &is, KPoint &kpt)
Definition: esolver.h:178
bool is_equal(double val1, double val2, double eps)
Definition: esolver.h:190
FunctionFactory< std::complex< double >, 3 > factoryT
Definition: esolver.h:55
void print_cube(World &world, const Function< double, 3 > &f, int npts)
Definition: esolver.h:60
Tensor< std::complex< double > > ctensorT
Definition: esolver.h:53
Vector< double, 3 > coordT
Definition: esolver.h:44
std::shared_ptr< FunctionFunctorInterface< double, 3 > > rfunctorT
Definition: esolver.h:46
Tensor< double > rtensorT
Definition: esolver.h:54
std::vector< rfunctionT > rvecfuncT
Definition: esolver.h:51
Function< std::complex< double >, 3 > functionT
Definition: esolver.h:47
std::shared_ptr< FunctionFunctorInterface< std::complex< double >, 3 > > functorT
Definition: esolver.h:45
SeparatedConvolution< double, 3 > operatorT
Definition: esolver.h:57
std::shared_ptr< operatorT> poperatorT
Definition: esolver.h:58
Function< double, 3 > rfunctionT
Definition: esolver.h:49
ctensorT kinetic_energy_matrix_slow(World &world, const std::vector< Function< std::complex< Q >, NDIM > > &v, const bool periodic, const KPoint k=KPoint(coordT(0.0), 0.0))
Definition: esolver.h:217
std::vector< cfunctionT > cvecfuncT
Definition: esolver.h:52
std::vector< functionT > vecfuncT
Definition: esolver.h:50
ctensorT kinetic_energy_matrix2(World &world, const std::vector< Function< std::complex< Q >, NDIM > > &v)
Definition: esolver.h:302
ctensorT kinetic_energy_matrix(World &world, const std::vector< Function< std::complex< Q >, NDIM > > &v, const bool periodic, const KPoint k=KPoint(coordT(0.0), 0.0))
Definition: esolver.h:272
FunctionFactory< double, 3 > rfactoryT
Definition: esolver.h:56
Fcwf apply(World &world, real_convolution_3d &op, const Fcwf &psi)
Definition: fcwf.cc:281
std::complex< double > inner(const Fcwf &psi, const Fcwf &phi)
Definition: fcwf.cc:275
Tensor< std::complex< double > > matrix_inner(World &world, std::vector< Fcwf > &a, std::vector< Fcwf > &b)
Definition: fcwf.cc:431
std::vector< std::shared_ptr< real_derivative_3d > > gradop
Definition: h2dft.cc:51
static const double v
Definition: hatom_sf_dirac.cc:20
vector< functionT > vecfuncT
Definition: mcpfit.cc:51
Vector< double, 3 > coordT
Definition: mcpfit.cc:48
Function< T, NDIM > conj(const Function< T, NDIM > &f, bool fence=true)
Return the complex conjugate of the input function with the same distribution and optional fence.
Definition: mra.h:2046
void compress(World &world, const std::vector< Function< T, NDIM > > &v, bool fence=true)
Compress a vector of functions.
Definition: vmra.h:133
Derivative< double_complex, 3 > complex_derivative_3d
Definition: functypedefs.h:177
void gaxpy(const double a, ScalarResult< T > &left, const double b, const T &right, const bool fence=true)
the result type of a macrotask must implement gaxpy
Definition: macrotaskq.h:140
const std::vector< Function< T, NDIM > > & reconstruct(const std::vector< Function< T, NDIM > > &v)
reconstruct a vector of functions
Definition: vmra.h:156
static const double c
Definition: relops.cc:10
static const long k
Definition: rk.cc:44
Definition: esolver.h:137
void serialize(Archive &ar)
Definition: esolver.h:172
unsigned int end
Definition: esolver.h:143
coordT k
Definition: esolver.h:138
unsigned int begin
Definition: esolver.h:142
KPoint(const coordT &k, const double &weight, const int &begin, const int &end)
Definition: esolver.h:153
KPoint()
Definition: esolver.h:145
double weight
Definition: esolver.h:139
KPoint(const coordT &k, const double &weight)
Definition: esolver.h:157
KPoint(const double &k0, const double &k1, const double &k2, const double &weight)
Definition: esolver.h:160
bool is_orb_in_kpoint(unsigned int idx)
Definition: esolver.h:166
static const double_complex I
Definition: tdse1d.cc:164
void d()
Definition: test_sig.cc:79
static const std::size_t NDIM
Definition: testpdiff.cc:42
std::size_t axis
Definition: testpdiff.cc:59
double k0
Definition: testperiodic.cc:66
double k2
Definition: testperiodic.cc:68
double k1
Definition: testperiodic.cc:67