33#ifndef MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
34#define MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
63 template <std::
size_t NDIM>
66 static std::vector< Key<NDIM> >
disp;
73 if (
NDIM == 1) bmax = 7;
74 else if (
NDIM == 2) bmax = 5;
75 else if (
NDIM == 3) bmax = 3;
76 else if (
NDIM == 4) bmax = 3;
77 else if (
NDIM == 5) bmax = 3;
78 else if (
NDIM == 6) bmax = 3;
85 return a.distsq() <
b.distsq();
97 for (std::size_t i=0; i<
NDIM; ++i) num *= (2*bmax + 1);
102 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
105 else if (
NDIM == 2) {
106 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
107 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
110 else if (
NDIM == 3) {
111 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
112 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
113 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
116 else if (
NDIM == 4) {
117 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
118 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
119 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
120 for (
d[3]=-bmax;
d[3]<=bmax; ++
d[3])
123 else if (
NDIM == 5) {
124 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
125 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
126 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
127 for (
d[3]=-bmax;
d[3]<=bmax; ++
d[3])
128 for (
d[4]=-bmax;
d[4]<=bmax; ++
d[4])
132 else if (
NDIM == 6) {
133 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
134 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
135 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
136 for (
d[3]=-bmax;
d[3]<=bmax; ++
d[3])
137 for (
d[4]=-bmax;
d[4]<=bmax; ++
d[4])
138 for (
d[5]=-bmax;
d[5]<=bmax; ++
d[5])
152 if (bmax > (twon-1)) bmax=twon-1;
155 std::vector<Translation> bp(4*bmax+1);
156 std::vector<Translation> bnp(2*bmax+1);
161 if ((lx < 0) && (lx+twon > bmax)) bp[ip++] = lx + twon;
162 if ((lx > 0) && (lx-twon <-bmax)) bp[ip++] = lx - twon;
168 const int nbnp = inp;
175 for(
size_t i=0; i!=
NDIM; ++i) {
180 for (std::size_t i=0; i<
NDIM; ++i) {
211 if constexpr (
NDIM <= 3) {
229 if (kernel_lattice_sum_axes.
any()) {
232 if ((kernel_lattice_sum_axes &&
periodic_axes) != kernel_lattice_sum_axes) {
234 "Displacements<" + std::to_string(
NDIM) +
235 ">::get_disp(level, kernel_lattice_sum_axes): kernel_lattice_sum_axes is set for some axes that were not periodic in the FunctionDefault's boundary conditions active at the time when Displacements were initialized; invoke Displacements<NDIM>::reset_periodic_axes(kernel_lattice_sum_axes) to rebuild the periodic displacements";
271 for (
Level n = 0; n < nmax; ++n)
278 template <std::
size_t N, std::
size_t M>
279 constexpr std::enable_if_t<N>=M, std::array<std::size_t,
N-M>>
iota_array(std::array<std::size_t, M> values_to_skip_sorted) {
280 std::array<std::size_t,
N - M> result;
281 if constexpr (
N != M) {
282 std::size_t nadded = 0;
283 auto value_to_skip_it = values_to_skip_sorted.begin();
284 assert(*value_to_skip_it <
N);
285 auto value_to_skip = *value_to_skip_it;
286 for (std::size_t i = 0; i <
N; ++i) {
287 if (i < value_to_skip) {
288 result[nadded++] = i;
289 }
else if (value_to_skip_it != values_to_skip_sorted.end()) {
291 if (value_to_skip_it != values_to_skip_sorted.end()) {
292 value_to_skip = *value_to_skip_it;
307 template<std::
size_t NDIM>
321 using Box = std::array<std::pair<Translation, Translation>,
NDIM>;
349 mutable std::optional<Displacement>
disp;
399 auto increment_along_dim = [
this](
size_t dim) {
408 for (
size_t i =
NDIM; i > 0; --i) {
409 const size_t cur_dim = i - 1;
413 increment_along_dim(cur_dim);
422 const auto filtered_out = [&,
this]() {
424 const auto& validator = this->parent->
validator_;
428 std::optional<Displacement> nulldisp;
429 result = !validator(
point.level(), point_pattern, nulldisp);
465 for (
size_t i = 0; i <
NDIM; ++i) {
473 const auto filtered_out = [&]() ->
bool {
481 while (!done && filtered_out()) {
492 const auto is_fixed_dim = dim ==
fixed_dim;
519 const Translation first_equiv_class = last_equiv_class - period + 1;
520 l_dim_min = std::max(first_equiv_class, l_dim_min);
530 const auto filtered_out = [&,
this]() {
532 const auto& validator = this->parent->
validator_;
536 std::optional<Displacement> nulldisp;
537 result = !validator(
point.level(), point_pattern, nulldisp);
542 if (filtered_out()) {
543 bool have_another_surface_layer;
586 for (
size_t d = 0;
d !=
NDIM; ++
d) {
636 if (
a.done &&
b.done)
return true;
637 if (
a.done ||
b.done)
return false;
638 return a.fixed_dim ==
b.fixed_dim &&
675 bool has_finite_dimensions =
false;
676 const auto n =
center_.level();
678 for (
size_t d=0;
d!=
NDIM; ++
d) {
682 r = (n == 0) ? (r+1)/2 : (r *
Translation(1) << (n-1));
685 if (!has_finite_dimensions)
686 probing_displacement_vec[
d] = r;
687 has_finite_dimensions =
true;
694 for (
size_t d=0;
d!=
NDIM; ++
d) {
759 template <
size_t NDIM>
776 const std::array<KernelRange, NDIM>& range,
783 for (
size_t i = 0; i <
NDIM; i++) {
784 if (is_lattice_summed[i]) {
786 }
else if (is_infinite_domain[i]) {
814 const auto twon = (
static_cast<Translation>(1) << level);
817 const auto map_to_range_twon = [&,
mask = ((~(
static_cast<std::uint64_t
>(0)) << (64-level)) >> (64-level))](std::int64_t x) -> std::int64_t {
818 const std::int64_t x_mapped = x &
mask;
823 const auto out_of_domain = [&](
const Translation& t) ->
bool {
824 return t < 0 || t >= twon;
828 const bool dest_is_in_domain = [&]() {
829 for(
size_t d=0;
d!=
NDIM; ++
d) {
835 if (dest_is_in_domain) {
843 bool among_standard_displacements =
true;
844 for(
size_t d=0;
d!=
NDIM; ++
d) {
845 const auto disp_d = (*displacement)[
d];
850 auto disp_d_eff_abs =
std::abs(disp_d);
855 const std::int64_t disp_d_eff = map_to_range_twon(disp_d);
856 disp_d_eff_abs = std::min(disp_d_eff,
std::abs(disp_d_eff-twon));
860 if (dest[
d].has_value()) {
862 const auto dest_d_in_cell = map_to_range_twon(dest_d);
866 auto t = (*displacement).translation();
867 t[
d] += (dest_d_in_cell - dest_d);
875 if (disp_d_eff_abs > bmax_standard) {
876 among_standard_displacements =
false;
881 if (among_standard_displacements) {
Iterator class for lazy generation of surface points.
Definition displacements.h:343
std::optional< Displacement > disp
Memoized displacement from parent->center_ to point, computed by displacement(), reset by advance()
Definition displacements.h:349
Iterator(const BoxSurfaceDisplacementRange *p, Type type)
Constructs an iterator.
Definition displacements.h:578
Type
Definition displacements.h:345
@ End
Definition displacements.h:345
@ Begin
Definition displacements.h:345
size_t fixed_dim
Current fixed dimension (i.e. faces perpendicular to this axis are being iterated over)
Definition displacements.h:350
const std::optional< Displacement > & displacement() const
Definition displacements.h:557
friend bool operator!=(const Iterator &a, const Iterator &b)
Inequality comparison operator.
Definition displacements.h:648
bool done
Flag indicating iteration completion.
Definition displacements.h:359
const Point * pointer
Definition displacements.h:569
pointer operator->() const
Arrow operator for member access.
Definition displacements.h:608
Box unprocessed_bounds
Definition displacements.h:351
Iterator operator++(int)
Post-increment operator.
Definition displacements.h:623
std::ptrdiff_t difference_type
Definition displacements.h:568
std::input_iterator_tag iterator_category
Definition displacements.h:566
const BoxSurfaceDisplacementRange * parent
Pointer to parent surface.
Definition displacements.h:347
bool next_surface_layer()
Definition displacements.h:363
reference operator*() const
Dereferences the iterator.
Definition displacements.h:602
Point value_type
Definition displacements.h:567
void reset_along_dim(size_t dim)
Definition displacements.h:491
void advance_till_valid()
Perform advance, repeating if you are at a filtered point.
Definition displacements.h:471
Point point
Current point / box. This is always free to leave the simulation cell.
Definition displacements.h:348
friend bool operator==(const Iterator &a, const Iterator &b)
Equality comparison operator.
Definition displacements.h:635
Iterator & operator++()
Pre-increment operator.
Definition displacements.h:614
const Point & reference
Definition displacements.h:570
void advance()
Advances the iterator to the next surface point.
Definition displacements.h:396
Definition displacements.h:308
Displacement probing_displacement_
displacement to a nearby point on the surface; it may not be able to pass the filter,...
Definition displacements.h:335
std::function< bool(Level, const PointPattern &, std::optional< Displacement > &)> Validator
Definition displacements.h:316
Key< NDIM > Point
Definition displacements.h:310
const Key< NDIM > & center() const
Definition displacements.h:727
std::array< std::optional< Translation >, NDIM > SurfaceThickness
Definition displacements.h:320
const std::array< std::optional< int64_t >, NDIM > & box_radius() const
Definition displacements.h:732
const array_of_bools< NDIM > & is_lattice_summed() const
Definition displacements.h:742
Periodicity is_lattice_summed_
which dimensions are lattice summed?
Definition displacements.h:331
Validator validator_
optional validator function
Definition displacements.h:332
SurfaceThickness surface_thickness_
surface thickness in each dimension, measured in boxes. Real-space surface size is thus n-dependent.
Definition displacements.h:328
std::array< std::optional< Translation >, NDIM > BoxRadius
Definition displacements.h:319
const std::array< std::optional< int64_t >, NDIM > & surface_thickness() const
Definition displacements.h:737
BoxSurfaceDisplacementRange(const Key< NDIM > ¢er, const std::array< std::optional< std::int64_t >, NDIM > &box_radius, const std::array< std::optional< std::int64_t >, NDIM > &surface_thickness, const array_of_bools< NDIM > &is_lattice_summed, Validator validator={})
Constructs a box with different radii and thicknesses for each dimension.
Definition displacements.h:667
Hollowness hollowness_
does box contain non-surface points along each dimension?
Definition displacements.h:330
auto begin() const
Returns an iterator to the beginning of the surface points.
Definition displacements.h:706
Box box_
box bounds in each dimension.
Definition displacements.h:329
const Displacement & probing_displacement() const
Definition displacements.h:747
Point center_
Center point of the box.
Definition displacements.h:325
Key< NDIM > Displacement
Definition displacements.h:312
std::array< bool, NDIM > Hollowness
Definition displacements.h:322
auto end() const
Returns an iterator to the end of the surface points.
Definition displacements.h:712
Vector< std::optional< Translation >, NDIM > PointPattern
Definition displacements.h:311
std::array< std::pair< Translation, Translation >, NDIM > Box
Definition displacements.h:321
BoxRadius box_radius_
halved size of the box in each dimension, in half-SimulationCells.
Definition displacements.h:326
Definition displacements.h:760
Vector< std::optional< Translation >, NDIM > PointPattern
Definition displacements.h:763
DistanceSquaredFunc default_distance_squared_
Definition displacements.h:902
Key< NDIM > Displacement
Definition displacements.h:764
std::array< ExtraDomainPolicy, NDIM > domain_policies_
Definition displacements.h:900
Key< NDIM > Point
Definition displacements.h:762
std::function< Translation(const Displacement &)> DistanceSquaredFunc
Definition displacements.h:766
bool operator()(const Level level, const PointPattern &dest, std::optional< Displacement > &displacement) const
Apply filter to a displacement ending up at a point or a group of points (point pattern)
Definition displacements.h:808
Translation max_distsq_reached_
Definition displacements.h:903
std::array< KernelRange, NDIM > range_
Definition displacements.h:901
BoxSurfaceDisplacementValidator(const array_of_bools< NDIM > &is_infinite_domain, const array_of_bools< NDIM > &is_lattice_summed, const std::array< KernelRange, NDIM > &range, DistanceSquaredFunc default_distance_squared, Translation max_distsq_reached)
Definition displacements.h:773
Holds displacements for applying operators to avoid replicating for all operators.
Definition displacements.h:64
static std::vector< Key< NDIM > > disp
standard displacements to be used with standard kernels (range-unrestricted, no lattice sum)
Definition displacements.h:66
static bool cmp_keys(const Key< NDIM > &a, const Key< NDIM > &b)
Definition displacements.h:84
const std::vector< Key< NDIM > > & get_disp()
return the standard displacements appropriate for operators w/o lattice summation
Definition displacements.h:248
const std::vector< Key< NDIM > > & get_disp(Level n, const array_of_bools< NDIM > &kernel_lattice_sum_axes)
Definition displacements.h:224
static array_of_bools< NDIM > periodic_axes
along which axes lattice summation is performed?
Definition displacements.h:67
static void reset_periodic_axes(const array_of_bools< NDIM > &new_periodic_axes)
rebuilds periodic displacements so that they are optimal for the given set of periodic axes
Definition displacements.h:262
static void make_disp(int bmax)
Definition displacements.h:92
static std::vector< Key< NDIM > > disp_periodic[64]
displacements to be used with lattice-summed kernels
Definition displacements.h:68
static void make_disp_periodic(int bmax, Level n)
Definition displacements.h:148
static int bmax_default()
Definition displacements.h:71
static bool cmp_keys_periodic(const Key< NDIM > &a, const Key< NDIM > &b)
Definition displacements.h:88
Displacements()
Definition displacements.h:203
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:100
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:69
A simple, fixed dimension vector.
Definition vector.h:64
syntactic sugar for std::array<bool, N>
Definition array_of_bools.h:19
bool any() const
Definition array_of_bools.h:38
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
real_function_3d mask
Definition dirac-hatom.cc:27
Provides FunctionDefaults and utilities for coordinate transformation.
#define MADNESS_PRAGMA_CLANG(x)
Definition madness_config.h:200
#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
ExtraDomainPolicy
Definition displacements.h:51
int64_t Translation
Definition key.h:57
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:452
int Level
Definition key.h:58
static double pop(std::vector< double > &v)
Definition SCF.cc:115
constexpr std::array< std::size_t, N-M > iota_array(std::array< std::size_t, M > values_to_skip_sorted)
Definition displacements.h:279
std::string type(const PairType &n)
Definition PNOParameters.h:18
static long abs(long a)
Definition tensor.h:218
static const double b
Definition nonlinschro.cc:119
static const double d
Definition nonlinschro.cc:121
static const double a
Definition nonlinschro.cc:118
#define N
Definition testconv.cc:37
constexpr std::size_t NDIM
Definition testgconv.cc:54