MADNESS  version 0.9
displacements.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 #ifndef MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
34 #define MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
35 
36 namespace madness {
38  template <std::size_t NDIM>
39  class Displacements {
40 
41  static std::vector< Key<NDIM> > disp;
42  static std::vector< Key<NDIM> > disp_periodicsum[64];
43 
44  public:
45  static int bmax_default() {
46  int bmax;
47  if (NDIM == 1) bmax = 7;
48  else if (NDIM == 2) bmax = 5;
49  else if (NDIM == 3) bmax = 3;
50  else if (NDIM == 6) bmax = 3;
51  else bmax = 2;
52  return bmax;
53  }
54 
55  private:
56  static bool cmp_keys(const Key<NDIM>& a, const Key<NDIM>& b) {
57  return a.distsq() < b.distsq();
58  }
59 
60  static bool cmp_keys_periodicsum(const Key<NDIM>& a, const Key<NDIM>& b) {
61  Translation twonm1 = (Translation(1)<<a.level())>>1;
62 
63  uint64_t suma=0, sumb=0;
64  for (std::size_t d=0; d<NDIM; ++d) {
65  Translation la = a.translation()[d];
66  if (la > twonm1) la -= twonm1*2;
67  if (la <-twonm1) la += twonm1*2;
68  suma += la*la;
69 
70  Translation lb = b.translation()[d];
71  if (lb > twonm1) lb -= twonm1*2;
72  if (lb <-twonm1) lb += twonm1*2;
73  sumb += lb*lb;
74  }
75  return suma < sumb;
76  }
77 
78  static void make_disp(int bmax) {
79  // Note newer loop structure in make_disp_periodic_sum
80  Vector<Translation,NDIM> d(0);
81 
82  int num = 1;
83  for (std::size_t i=0; i<NDIM; ++i) num *= (2*bmax + 1);
84  disp.resize(num,Key<NDIM>(0));
85 
86  num = 0;
87  if (NDIM == 1) {
88  for (d[0]=-bmax; d[0]<=bmax; ++d[0])
89  disp[num++] = Key<NDIM>(0,d);
90  }
91  else if (NDIM == 2) {
92  for (d[0]=-bmax; d[0]<=bmax; ++d[0])
93  for (d[1]=-bmax; d[1]<=bmax; ++d[1])
94  disp[num++] = Key<NDIM>(0,d);
95  }
96  else if (NDIM == 3) {
97  for (d[0]=-bmax; d[0]<=bmax; ++d[0])
98  for (d[1]=-bmax; d[1]<=bmax; ++d[1])
99  for (d[2]=-bmax; d[2]<=bmax; ++d[2])
100  disp[num++] = Key<NDIM>(0,d);
101  }
102  else if (NDIM == 4) {
103  for (d[0]=-bmax; d[0]<=bmax; ++d[0])
104  for (d[1]=-bmax; d[1]<=bmax; ++d[1])
105  for (d[2]=-bmax; d[2]<=bmax; ++d[2])
106  for (d[3]=-bmax; d[3]<=bmax; ++d[3])
107  disp[num++] = Key<NDIM>(0,d);
108  }
109  else if (NDIM == 5) {
110  for (d[0]=-bmax; d[0]<=bmax; ++d[0])
111  for (d[1]=-bmax; d[1]<=bmax; ++d[1])
112  for (d[2]=-bmax; d[2]<=bmax; ++d[2])
113  for (d[3]=-bmax; d[3]<=bmax; ++d[3])
114  for (d[4]=-bmax; d[4]<=bmax; ++d[4])
115 
116  disp[num++] = Key<NDIM>(0,d);
117  }
118  else if (NDIM == 6) {
119  for (d[0]=-bmax; d[0]<=bmax; ++d[0])
120  for (d[1]=-bmax; d[1]<=bmax; ++d[1])
121  for (d[2]=-bmax; d[2]<=bmax; ++d[2])
122  for (d[3]=-bmax; d[3]<=bmax; ++d[3])
123  for (d[4]=-bmax; d[4]<=bmax; ++d[4])
124  for (d[5]=-bmax; d[5]<=bmax; ++d[5])
125  disp[num++] = Key<NDIM>(0,d);
126  }
127  else {
128  MADNESS_EXCEPTION("_make_disp: hard dimension loop",NDIM);
129  }
130 
131  std::sort(disp.begin(), disp.end(), cmp_keys);
132  }
133 
134  static void make_disp_periodicsum(int bmax, Level n) {
135  Translation twon = Translation(1)<<n;
136 
137  if (bmax > (twon-1)) bmax=twon-1;
138 
139  // Make permissible 1D translations
140  Translation b[4*bmax+1];
141  int i=0;
142  for (Translation lx=-bmax; lx<=bmax; ++lx) {
143  b[i++] = lx;
144  if ((lx < 0) && (lx+twon > bmax)) b[i++] = lx + twon;
145  if ((lx > 0) && (lx-twon <-bmax)) b[i++] = lx - twon;
146  }
147  MADNESS_ASSERT(i <= 4*bmax+1);
148  int numb = i;
149 
150  disp_periodicsum[n] = std::vector< Key<NDIM> >();
151  Vector<long,NDIM> lim(numb);
152  for (IndexIterator index(lim); index; ++index) {
153  Vector<Translation,NDIM> d;
154  for (std::size_t i=0; i<NDIM; ++i) {
155  d[i] = b[index[i]];
156  }
157  disp_periodicsum[n].push_back(Key<NDIM>(n,d));
158  }
159 
160  std::sort(disp_periodicsum[n].begin(), disp_periodicsum[n].end(), cmp_keys_periodicsum);
161 // print("KEYS AT LEVEL", n);
162 // print(disp_periodicsum[n]);
163  }
164 
165 
166  public:
168  if (disp.size() == 0) {
169  make_disp(bmax_default());
170 
171  if (NDIM <= 3) {
172  Level nmax = 8*sizeof(Translation) - 2;
173  for (Level n=0; n<nmax; ++n) make_disp_periodicsum(bmax_default(), n);
174  }
175  }
176  }
177 
178  const std::vector< Key<NDIM> >& get_disp(Level n, bool isperiodicsum) {
179  if (isperiodicsum) {
180  MADNESS_ASSERT(NDIM <= 3);
181  return disp_periodicsum[n];
182  }
183  else {
184  return disp;
185  }
186  }
187 
188  };
189 }
190 #endif // MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
const int NDIM
Definition: tdse1.cc:44
Displacements()
Definition: displacements.h:167
uint64_t distsq() const
Definition: key.h:230
static int bmax_default()
Definition: displacements.h:45
Holds displacements for applying operators to avoid replicating for all operators.
Definition: displacements.h:39
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
const std::vector< Key< NDIM > > & get_disp(Level n, bool isperiodicsum)
Definition: displacements.h:178
int Level
Definition: key.h:58
#define MADNESS_EXCEPTION(msg, value)
Definition: worldexc.h:88
int64_t Translation
Definition: key.h:57
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
FLOAT b(int j, FLOAT z)
Definition: y1.cc:79
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:69