MADNESS 0.10.1
key.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
32#ifndef MADNESS_MRA_KEY_H__INCLUDED
33#define MADNESS_MRA_KEY_H__INCLUDED
34
35/// \file key.h
36/// \brief Multidimension Key for MRA tree and associated iterators
37
38#include <madness/mra/bc.h>
39#include <madness/mra/power.h>
44
45#include <algorithm>
46#include <climits> // CHAR_BIT
47#include <cstdint>
48
49namespace madness {
50
51 // // this has problems when nproc is a large-ish power of 2 such as 256
52 // // and leads to bad data distribution.
53 // static inline unsigned int sdbm(int n, const unsigned char* c, unsigned int sum=0) {
54 // for (int i=0; i<n; ++i) sum = c[i] + (sum << 6) + (sum << 16) - sum;
55 // return sum;
56 // }
57
58 typedef int64_t Translation;
59 typedef int Level;
60
61 template<std::size_t NDIM>
62 class KeyChildIterator;
63
64 /// Key is the index for a node of the 2^NDIM-tree
65
66 /// See KeyChildIterator for facile generation of children,
67 /// and foreach_child(parent,op) for facile application of operators
68 /// to child keys.
69 template<std::size_t NDIM>
70 class Key {
71 public:
72// static const typename Vector<Translation,NDIM>::size_type static_size = Vector<Translation,NDIM>::static_size;
73 static const std::size_t static_size = NDIM;
74
75 private:
76 friend class KeyChildIterator<NDIM> ;
80
81
82 public:
83
84 /// Default constructor makes an \em uninitialized key
85 Key() {}
86
87 /// Constructor with given n, l
89 {
90 MADNESS_ASSERT(n >= 0 && size_t(n) < sizeof(Translation)*CHAR_BIT);
91 rehash();
92 }
93
94 /// Constructor with given n and l=0
95 Key(int n) : n(n), l(0)
96 {
97 MADNESS_ASSERT(n >= 0 && size_t(n) < sizeof(Translation)*CHAR_BIT);
98 rehash();
99 }
100
101 // /// easy constructor ... UGH !!!!!!!!!!!!!!!!!!!!!!
102 // Key(const int n, const int l0, const int l1, const int l2) : n(n) {
103 // MADNESS_ASSERT(NDIM==3);
104 // l=Vector<Translation, NDIM>(0);
105 // l[0]=l0; l[1]=l1; l[2]=l2;
106 // rehash();
107 // }
108
109 /// Returns an invalid key
111 Key<NDIM> result;
112 result.n = -1;
113 result.l = 0;
114 result.rehash();
115 return result;
116 }
117
118 /// Checks if a key is invalid
119 bool is_invalid() const {
120 return n == -1;
121 }
122
123 /// Checks if a key is valid
124 bool is_valid() const {
125 return n != -1;
126 }
127
128 /// Equality test
129 bool operator==(const Key& other) const {
130 if (hashval != other.hashval) return false;
131 if (n != other.n) return false;
132 for (unsigned int i=0; i<NDIM; i++)
133 if (l[i] != other.l[i]) return false;
134 return true; // everything is equal
135 }
136
137 bool operator!=(const Key& other) const {
138 return !(*this == other);
139 }
140
141 /// Comparison operator less than to enable storage in STL map
142 bool operator<(const Key& other) const {
143 if (hashval < other.hashval) return true;
144 if (hashval > other.hashval) return false;
145
146 if (n < other.n) return true;
147 if (n > other.n) return false;
148
149 for (unsigned int i=0; i<NDIM; i++) {
150 if (l[i] < other.l[i]) return true;
151 if (l[i] > other.l[i]) return false;
152 }
153
154 return false; // everything is equal
155 }
156
157 inline hashT
158 hash() const {
159 return hashval;
160 }
161
162 // template<typename Archive>
163 // inline void
164 // serialize(Archive& ar) {
165 // ar & archive::wrap((unsigned char*) this, sizeof(*this));
166 // }
167
168 Level
169 level() const {
170 return n;
171 }
172
174 translation() const {
175 return l;
176 }
177
178 /// const accessor to elements of this->translation()
179 const Translation& operator[](std::size_t d) const {
180 return l[d];
181 }
182
183 uint64_t
184 distsq() const {
185 uint64_t dist = 0;
186 for (std::size_t d = 0; d < NDIM; ++d) {
187 dist += l[d] * l[d];
188 }
189 return dist;
190 }
191
192 // The distance of a displacement in real space.
193 double real_distsq(const madness::Tensor<double>& widths) const {
194 double dist = 0;
195 for (std::size_t d = 0; d < NDIM; ++d) {
196 // Subtract 1 to account for the least distance between points in the boxes.
197 const auto least_displacement_distance = std::max(std::abs(l[d]) - 1, static_cast<Translation>(0));
198 const auto real_width = widths(d) * least_displacement_distance;
199 dist += real_width * real_width;
200 }
201 return dist;
202 }
203
204 /// like distsq() but accounts for periodicity
205 uint64_t distsq_bc(const array_of_bools<NDIM>& is_periodic) const {
206 const Translation twonm1 = (Translation(1) << level()) >> 1;
207
208 uint64_t dsq = 0;
209 for (std::size_t d = 0; d < NDIM; ++d) {
210 Translation la = translation()[d];
211 if (is_periodic[d]) {
212 if (la > twonm1) {
213 la -= twonm1 * 2;
214 MADNESS_ASSERT(la <= twonm1);
215 }
216 if (la < -twonm1) {
217 la += twonm1 * 2;
218 MADNESS_ASSERT(la >= -twonm1);
219 }
220 }
221 dsq += la * la;
222 }
223
224 return dsq;
225 }
226
227 /// like real_distsq() but accounts for periodicity
228 double real_distsq_bc(const array_of_bools<NDIM>& is_periodic, const Tensor<double>& widths) const {
229 const Translation twonm1 = (Translation(1) << level()) >> 1;
230
231 double dsq = 0;
232 for (std::size_t d = 0; d < NDIM; ++d) {
233 Translation la = translation()[d];
234 if (is_periodic[d]) {
235 if (la > twonm1) {
236 la -= twonm1 * 2;
237 MADNESS_ASSERT(la <= twonm1);
238 }
239 if (la < -twonm1) {
240 la += twonm1 * 2;
241 MADNESS_ASSERT(la >= -twonm1);
242 }
243 }
244 // Subtract 1 to account for the least distance between points in the boxes.
245 const auto least_displacement_distance = std::max(std::abs(la) - 1, static_cast<Translation>(0));
246 const auto real_width = widths(d) * least_displacement_distance;
247 dsq += real_width * real_width;
248 }
249
250 return dsq;
251 }
252
253 /// like "periodic" distsq() but only selects the prescribed axes
254 template <std::size_t NDIM2>
255 std::enable_if_t<NDIM >= NDIM2, uint64_t>
256 distsq_bc(const array_of_bools<NDIM>& is_periodic, const std::array<std::size_t, NDIM2>& axes) const {
257 const Translation twonm1 = (Translation(1) << level()) >> 1;
258
259 uint64_t dsq = 0;
260 for (std::size_t a = 0; a < NDIM2; ++a) {
261 const auto d = axes[a];
263 Translation la = translation()[d];
264 if (is_periodic[d]) {
265 if (la > twonm1) {
266 la -= twonm1 * 2;
267 MADNESS_ASSERT(la <= twonm1);
268 }
269 if (la < -twonm1) {
270 la += twonm1 * 2;
271 MADNESS_ASSERT(la >= -twonm1);
272 }
273 }
274 dsq += la * la;
275 }
276
277 return dsq;
278 }
279
280 /// Returns the key of the parent
281
282 /// Default is the immediate parent (generation=1). To get
283 /// the grandparent use generation=2, and similarly for
284 /// great-grandparents.
285 ///
286 /// !! If there is no such parent it quietly returns the
287 /// closest match (which may be self if this is the top of the
288 /// tree).
289 Key
290 parent(int generation = 1) const {
292 if (generation > n)
293 generation = n;
294 for (std::size_t i = 0; i < NDIM; ++i)
295 pl[i] = l[i] >> generation;
296 return Key(n - generation, pl);
297 }
298
299
300 bool
301 is_child_of(const Key& key) const {
302 if (this->n < key.n) {
303 return false; // I can't be child of something lower on the tree
304 }
305 else if (this->n == key.n) {
306 return (*this == key); // I am child of myself
307 }
308 else {
309 Level dn = this->n - key.n;
310 Key mama = this->parent(dn);
311 return (mama == key);
312 }
313 }
314
315
316 bool
317 is_parent_of(const Key& key) const {
318 return (key.is_child_of(*this));
319 }
320
321 /// Assuming keys are at the same level, returns true if displaced by no more than 1 in any direction
322
323 /// Assumes key and this are at the same level
324 bool
325 is_neighbor_of(const Key& key, const array_of_bools<NDIM>& bperiodic) const {
326 Translation dist = 0;
327 Translation TWON1 = (Translation(1)<<n) - 1;
328 for (std::size_t i=0; i<NDIM; ++i)
329 {
330 Translation ll = std::abs(l[i] - key.l[i]);
331 if (bperiodic[i] && ll==TWON1) ll=1;
332 dist = std::max(dist, ll);
333 }
334 return (dist <= 1);
335 }
336
337 /// True iff this box is a neighbor of a point in simulation coordinates
338
339 /// Geometrically: this box's closure overlaps the closed box of
340 /// half-width 1 (one box-width at this level) centered on `simpt`.
341 /// Equivalently, the Chebyshev distance from this box to `simpt`
342 /// (measured in box-widths) is at most 1.
343 ///
344 /// This is the point-argument analogue of the key-vs-key overload
345 /// `is_neighbor_of(Key, bperiodic)`; both express "within one
346 /// box-width" adjacency. It supersedes the legacy idiom
347 /// `simpt2key(simpt, n).is_neighbor_of(*this, ...)`, which was
348 /// asymmetric for points lying on box boundaries because
349 /// `simpt2key` truncates to a single key. The new test reports
350 /// face-, edge-, and corner-coincident points as contained in
351 /// *every* box that shares the face/edge/corner — and therefore
352 /// every neighbor of those boxes is correctly flagged too.
353 ///
354 /// @param[in] simpt point in simulation coordinates
355 /// (in [0,1]^NDIM, modulo 1 in periodic dimensions)
356 /// @param[in] bperiodic per-dimension periodic-boundary flags
357 template <typename T>
358 bool
360 const array_of_bools<NDIM>& bperiodic) const {
361 const double twon = std::ldexp(1.0, n); // 2^n
362 const double period = twon; // sim domain has unit length
363 // round-off in d = twon*simpt - l is ~ period * eps; pad by a few
364 // ULPs so points within machine noise of an edge deterministically
365 // count as on it.
366 const double tol = 8.0 * period * std::numeric_limits<double>::epsilon();
367 for (std::size_t i = 0; i < NDIM; ++i) {
368 // signed distance from this box's lower edge, in box-widths
369 double d = twon * static_cast<double>(simpt[i]) - static_cast<double>(l[i]);
370 if (bperiodic[i]) {
371 // fold to the nearest periodic image: d ∈ [-period/2, period/2)
372 d -= period * std::floor((d + 0.5 * period) / period);
373 }
374 if (d < -1.0 - tol || d > 2.0 + tol)
375 return false;
376 }
377 return true;
378 }
379
380 /// given a displacement, generate a neighbor key; ignore boundary conditions and disp's level
381
382 /// @param[in] disp the displacement
383 /// @return a new key
384 Key neighbor(const Key<NDIM>& disp) const {
386 return Key(this->level(),l);
387 }
388
389 /// given a displacement, generate a neighbor key; ignore boundary conditions and disp's level
390
391 /// @param[in] disp the displacement
392 /// @return a new key
395 return Key(this->level(),l);
396 }
397
398
399 /// check if this MultiIndex contains point x, disregarding these two dimensions
400 bool thisKeyContains(const Vector<double,NDIM>& x, const unsigned int& dim0,
401 const unsigned int& dim1) const {
402
403 // it's sufficient if one single dimension is out
404 bool contains=true;
405 const double twotoN = std::pow(2.0,double(n));
406 MADNESS_ASSERT(dim0<NDIM and dim1<NDIM);
407
408 for (unsigned int i=0; i<NDIM; i++ ) {
409
410 // check bounds
411 MADNESS_ASSERT((x[i]>=0.0) and (x[i]<=1.0));
412
413 // leave these two dimensions out
414 if ((i==dim0) or (i==dim1)) continue;
415
416 const int ll=int (x[i]*twotoN);
417 if (not (l[i]==ll)) contains=false;
418 }
419 return contains;
420 }
421
422 /// break key into two low-dimensional keys
423 template<std::size_t LDIM, std::size_t KDIM>
424 void break_apart(Key<LDIM>& key1, Key<KDIM>& key2) const {
425
426 // if LDIM==NDIM the 2nd key will be constructed empty
427 // static_assert((LDIM+KDIM==NDIM) or (LDIM==NDIM));
430 if constexpr((LDIM+KDIM==NDIM) or (LDIM==NDIM)) {
431 for (size_t i=0; i<LDIM; ++i) {
432 l1[i]=l[i];
433 }
434 for (size_t i=LDIM; i<NDIM; ++i) {
435 l2[i-LDIM]=l[i];
436 }
437
438 key1=Key<LDIM>(n,l1);
439 key2=Key<KDIM>(n,l2);
440 } else {
441 MADNESS_EXCEPTION("Key::break_apart: LDIM+KDIM must equal NDIM or LDIM==NDIM",1);
442 }
443 }
444
445 /// extract a new key consisting of first VDIM dimensions of this
446 template<std::size_t VDIM>
448 static_assert(VDIM <= NDIM, "VDIM must be less than or equal to NDIM");
450 for (size_t i = 0; i < VDIM; ++i) t[i] = this->translation()[i];
451 return Key<VDIM>(this->level(),t);
452 }
453
454 /// extract a new key consisting of last VDIM dimensions of this
455 template<std::size_t VDIM>
457 static_assert(VDIM <= NDIM, "VDIM must be less than or equal to NDIM");
459 for (size_t i = 0; i < VDIM; ++i) t[i] = this->translation()[NDIM-VDIM+i];
460 return Key<VDIM>(this->level(),t);
461 }
462
463 /// extract a new key with the Translations indicated in the v array
464 template<std::size_t VDIM>
465 Key<VDIM> extract_key(const std::array<int,VDIM>& v) const {
467 for (size_t i = 0; i < VDIM; ++i) t[i] = this->translation()[v[i]];
468 return Key<VDIM>(this->level(),t);
469 };
470
471 /// extract a new key with the Translations complementary to the ones indicated in the v array
472 template<std::size_t VDIM>
473 Key<NDIM-VDIM> extract_complement_key(const std::array<int,VDIM>& v) const {
474
475 // return the complement of v, e.g. v={0,1}, v_complement={2,3,4} if NDIM==5
476 // v must be contiguous and ascending (i.e. 1,2,3 or 2,3,4)
477 auto v_complement = [](const std::array<int, VDIM>& v) {
478 std::array<int, NDIM - VDIM> result;
479 for (std::size_t i = 0; i < NDIM - VDIM; i++) result[i] = (v.back() + i + 1) % NDIM;
480 return result;
481 };
482 return extract_key(v_complement(v));
483 };
484
485 /// merge with other key (ie concatenate), use level of rhs, not of this
486 template<std::size_t LDIM>
489 for (size_t i=0; i<NDIM; ++i) t[i] =this->l[i];
490 for (size_t i=0; i<LDIM; ++i) t[NDIM+i]=rhs.translation()[i];
491 return Key<NDIM+LDIM>(rhs.level(),t);
492 }
493
494 /// return if the other key is pointing in the same direction and is farther out
495
496 /// unlike in distsq() the direction is taken into account, and other must be
497 /// longer than this in each dimension
498 /// @param[in] other a key
499 /// @return if other is farther out
500 bool is_farther_out_than(const Key<NDIM>& other) const {
501 for (size_t i=0; i<NDIM; ++i) {
502 if ((other.translation()[i]>0) and (other.translation()[i]>l[i])) return false;
503 if ((other.translation()[i]<0) and (other.translation()[i]<l[i])) return false;
504 }
505 return true;
506 }
507
508
509 /// Recomputes hashval ... presently only done when reading from external storage
510 void
512 //hashval = sdbm(sizeof(n)+sizeof(l), (unsigned char*)(&n));
513 // default hash is still best
514
517 }
518 };
519
520 template<std::size_t NDIM>
521 std::ostream&
522 operator<<(std::ostream& s, const Key<NDIM>& key) {
523 s << "(" << key.level() << "," << key.translation() << ")";
524 return s;
525 }
526
527 /// given a source and a target, return the displacement in translation
528
529 /// @param[in] source the source key
530 /// @param[in] target the target key
531 /// @return disp such that target = source + disp
532 template<size_t NDIM>
534 MADNESS_ASSERT(source.level()==target.level());
535 const Vector<Translation,NDIM> l = target.translation()-source.translation();
536 return Key<NDIM>(source.level(),l);
537 }
538
539
540
541 /// Iterates in lexical order thru all children of a key
542
543 /// Example usage:
544 /// \code
545 /// for (KeyChildIterator<NDIM> it(key); it; ++it) print(it.key());
546 /// \endcode
547 template<std::size_t NDIM>
553
554 public:
556 p(0), finished(true) {
557 }
558
560 parent(parent), child(parent.n + 1, parent.l * 2), p(0),
561 finished(false) {
562 }
563
564 /// Pre-increment of an iterator (i.e., ++it)
567 if (finished)
568 return *this;
569 std::size_t i;
570 for (i = 0; i < NDIM; ++i) {
571 if (p[i] == 0) {
572 ++(p[i]);
573 ++(child.l[i]);
574 for (std::size_t j = 0; j < i; ++j) {
575 --(p[j]);
576 --(child.l[j]);
577 }
578 break;
579 }
580 }
581 finished = (i == NDIM);
582 child.rehash();
583 return *this;
584 }
585
586 /// True if iterator is not at end
587 operator bool() const {
588 return !finished;
589 }
590
591 template<typename Archive>
592 inline void
593 serialize(Archive& ar) {
594 ar & archive::wrap((unsigned char*) this, sizeof(*this));
595 }
596
597 /// Returns the key of the child
598 inline const Key<NDIM>&
599 key() const {
600 return child;
601 }
602 };
603
604 /// Applies op(key) to each child key of parent
605 template<std::size_t NDIM, typename opT>
606 inline void
607 foreach_child(const Key<NDIM>& parent, opT& op) {
609 it(parent); it; ++it)
610 op(it.key());
611 }
612
613 /// Applies member function of obj to each child key of parent
614 template<std::size_t NDIM, typename objT>
615 inline void
616 foreach_child(const Key<NDIM>& parent, objT* obj, void
617 (objT::*memfun)(const Key<NDIM>&)) {
619 it(parent); it; ++it)
620 (obj ->* memfun)(it.key());
621 }
622
623 namespace archive {
624
625 // For efficiency serialize opaque so is just one memcpy, but
626 // when reading from external storage rehash() so that we
627 // can read data even if hash algorithm/function has changed.
628
629 template <class Archive, std::size_t NDIM>
630 struct ArchiveLoadImpl< Archive, Key<NDIM> > {
631 static void load(const Archive& ar, Key<NDIM>& t) {
632 ar & archive::wrap((unsigned char*) &t, sizeof(t));
633 }
634 };
635
636 template <std::size_t NDIM>
638 static void load(const BinaryFstreamInputArchive& ar, Key<NDIM>& t) {
639 ar & archive::wrap((unsigned char*) &t, sizeof(t));
640 t.rehash(); // <<<<<<<<<< This is the point
641 }
642 };
643
644 template <class Archive, std::size_t NDIM>
645 struct ArchiveStoreImpl< Archive, Key<NDIM> > {
646 static void store(const Archive& ar, const Key<NDIM>& t) {
647 ar & archive::wrap((unsigned char*) &t, sizeof(t));
648 }
649 };
650 }
651
652}
653
654#endif // MADNESS_MRA_KEY_H__INCLUDED
655
Provides BoundaryConditions.
Implements an archive wrapping a binary filestream.
Iterates in lexical order thru all children of a key.
Definition key.h:548
Vector< Translation, NDIM > p
Definition key.h:551
KeyChildIterator(const Key< NDIM > &parent)
Definition key.h:559
bool finished
Definition key.h:552
const Key< NDIM > & key() const
Returns the key of the child.
Definition key.h:599
KeyChildIterator()
Definition key.h:555
Key< NDIM > child
Definition key.h:550
Key< NDIM > parent
Definition key.h:549
void serialize(Archive &ar)
Definition key.h:593
KeyChildIterator & operator++()
Pre-increment of an iterator (i.e., ++it)
Definition key.h:566
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:70
Key< VDIM > extract_back() const
extract a new key consisting of last VDIM dimensions of this
Definition key.h:456
Key< NDIM+LDIM > merge_with(const Key< LDIM > &rhs) const
merge with other key (ie concatenate), use level of rhs, not of this
Definition key.h:487
Level level() const
Definition key.h:169
uint64_t distsq_bc(const array_of_bools< NDIM > &is_periodic) const
like distsq() but accounts for periodicity
Definition key.h:205
bool is_farther_out_than(const Key< NDIM > &other) const
return if the other key is pointing in the same direction and is farther out
Definition key.h:500
Vector< Translation, NDIM > l
Definition key.h:78
double real_distsq(const madness::Tensor< double > &widths) const
Definition key.h:193
Key neighbor(const Vector< Translation, NDIM > &disp) const
given a displacement, generate a neighbor key; ignore boundary conditions and disp's level
Definition key.h:393
Key(int n)
Constructor with given n and l=0.
Definition key.h:95
Key(Level n, const Vector< Translation, NDIM > &l)
Constructor with given n, l.
Definition key.h:88
bool is_parent_of(const Key &key) const
Definition key.h:317
bool is_neighbor_of(const Key &key, const array_of_bools< NDIM > &bperiodic) const
Assuming keys are at the same level, returns true if displaced by no more than 1 in any direction.
Definition key.h:325
Key()
Default constructor makes an uninitialized key.
Definition key.h:85
bool is_valid() const
Checks if a key is valid.
Definition key.h:124
hashT hash() const
Definition key.h:158
bool thisKeyContains(const Vector< double, NDIM > &x, const unsigned int &dim0, const unsigned int &dim1) const
check if this MultiIndex contains point x, disregarding these two dimensions
Definition key.h:400
bool is_invalid() const
Checks if a key is invalid.
Definition key.h:119
bool operator==(const Key &other) const
Equality test.
Definition key.h:129
const Translation & operator[](std::size_t d) const
const accessor to elements of this->translation()
Definition key.h:179
Level n
Definition key.h:77
static const std::size_t static_size
Definition key.h:73
uint64_t distsq_bc(const array_of_bools< NDIM > &is_periodic, const std::array< std::size_t, NDIM2 > &axes) const
Definition key.h:256
bool operator!=(const Key &other) const
Definition key.h:137
Key< NDIM-VDIM > extract_complement_key(const std::array< int, VDIM > &v) const
extract a new key with the Translations complementary to the ones indicated in the v array
Definition key.h:473
Key< VDIM > extract_front() const
extract a new key consisting of first VDIM dimensions of this
Definition key.h:447
double real_distsq_bc(const array_of_bools< NDIM > &is_periodic, const Tensor< double > &widths) const
like real_distsq() but accounts for periodicity
Definition key.h:228
Key< VDIM > extract_key(const std::array< int, VDIM > &v) const
extract a new key with the Translations indicated in the v array
Definition key.h:465
bool is_neighbor_of(const Vector< T, NDIM > &simpt, const array_of_bools< NDIM > &bperiodic) const
True iff this box is a neighbor of a point in simulation coordinates.
Definition key.h:359
hashT hashval
Definition key.h:79
Key parent(int generation=1) const
Returns the key of the parent.
Definition key.h:290
void rehash()
Recomputes hashval ... presently only done when reading from external storage.
Definition key.h:511
const Vector< Translation, NDIM > & translation() const
Definition key.h:174
bool operator<(const Key &other) const
Comparison operator less than to enable storage in STL map.
Definition key.h:142
static Key< NDIM > invalid()
Returns an invalid key.
Definition key.h:110
uint64_t distsq() const
Definition key.h:184
Key neighbor(const Key< NDIM > &disp) const
given a displacement, generate a neighbor key; ignore boundary conditions and disp's level
Definition key.h:384
bool is_child_of(const Key &key) const
Definition key.h:301
void break_apart(Key< LDIM > &key1, Key< KDIM > &key2) const
break key into two low-dimensional keys
Definition key.h:424
A tensor is a multidimensional array.
Definition tensor.h:317
A simple, fixed dimension vector.
Definition vector.h:64
Wraps an archive around a binary filestream for input.
Definition binary_fstream_archive.h:104
syntactic sugar for std::array<bool, N>
Definition array_of_bools.h:19
archive_array< T > wrap(const T *, unsigned int)
Factory function to wrap a dynamically allocated pointer as a typed archive_array.
Definition archive.h:914
static const double v
Definition hatom_sf_dirac.cc:20
Tensor< double > op(const Tensor< double > &x)
Definition kain.cc:508
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#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
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
std::ostream & operator<<(std::ostream &os, const particle< PDIM > &p)
Definition lowrankfunction.h:401
void hash_combine(hashT &seed, const T &v)
Combine hash values.
Definition worldhash.h:260
int64_t Translation
Definition key.h:58
Key< NDIM > displacement(const Key< NDIM > &source, const Key< NDIM > &target)
given a source and a target, return the displacement in translation
Definition key.h:533
int Level
Definition key.h:59
std::size_t hashT
The hash value type.
Definition worldhash.h:145
void foreach_child(const Key< NDIM > &parent, opT &op)
Applies op(key) to each child key of parent.
Definition key.h:607
madness::hashT hash_value(const std::array< T, N > &a)
Hash std::array with madness hash.
Definition array_addons.h:78
static long abs(long a)
Definition tensor.h:218
static const double d
Definition nonlinschro.cc:121
static const double a
Definition nonlinschro.cc:118
static void load(const Archive &ar, Key< NDIM > &t)
Definition key.h:631
static void load(const BinaryFstreamInputArchive &ar, Key< NDIM > &t)
Definition key.h:638
Default load of an object via serialize(ar, t).
Definition archive.h:667
static void store(const Archive &ar, const Key< NDIM > &t)
Definition key.h:646
Default store of an object via serialize(ar, t).
Definition archive.h:612
Defines and implements most of Tensor.
double dist(const Vector< double, 3 > v1, const Vector< double, 3 > v2)
distance between v1 and v2
Definition test_localizer.cc:38
constexpr std::size_t NDIM
Definition testgconv.cc:54
double source(const coordT &r)
Definition testperiodic.cc:48
Implement the madness:Vector class, an extension of std::array that supports some mathematical operat...
Defines hash functions for use in distributed containers.
FLOAT target(const FLOAT &x)
Definition y.cc:295