33#ifndef MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
34#define MADNESS_MRA_DISPLACEMENTS_H__INCLUDED
65 template <std::
size_t NDIM>
68 inline static std::vector< Key<NDIM> >
disp = {};
78 if (
NDIM == 1) bmax = 7;
79 else if (
NDIM == 2) bmax = 5;
80 else if (
NDIM == 3) bmax = 4;
81 else if (
NDIM == 4) bmax = 3;
82 else if (
NDIM == 5) bmax = 3;
83 else if (
NDIM == 6) bmax = 3;
90 const auto a_width =
a.real_distsq(
widths);
91 const auto b_width =
b.real_distsq(
widths);
92 if (a_width == 0 and a_width == b_width)
return a.distsq() <
b.distsq();
93 else return a_width < b_width;
100 else return a_width < b_width;
108 for (std::size_t i=0; i<
NDIM; ++i) num *= (2*bmax + 1);
113 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
116 else if (
NDIM == 2) {
117 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
118 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
121 else if (
NDIM == 3) {
122 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
123 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
124 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
127 else if (
NDIM == 4) {
128 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
129 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
130 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
131 for (
d[3]=-bmax;
d[3]<=bmax; ++
d[3])
134 else if (
NDIM == 5) {
135 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
136 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
137 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
138 for (
d[3]=-bmax;
d[3]<=bmax; ++
d[3])
139 for (
d[4]=-bmax;
d[4]<=bmax; ++
d[4])
143 else if (
NDIM == 6) {
144 for (
d[0]=-bmax;
d[0]<=bmax; ++
d[0])
145 for (
d[1]=-bmax;
d[1]<=bmax; ++
d[1])
146 for (
d[2]=-bmax;
d[2]<=bmax; ++
d[2])
147 for (
d[3]=-bmax;
d[3]<=bmax; ++
d[3])
148 for (
d[4]=-bmax;
d[4]<=bmax; ++
d[4])
149 for (
d[5]=-bmax;
d[5]<=bmax; ++
d[5])
163 if (bmax > (twon-1)) bmax=twon-1;
166 std::vector<Translation> bp(4*bmax+1);
167 std::vector<Translation> bnp(2*bmax+1);
172 if ((lx < 0) && (lx+twon > bmax)) bp[ip++] = lx + twon;
173 if ((lx > 0) && (lx-twon <-bmax)) bp[ip++] = lx - twon;
179 const int nbnp = inp;
186 for(
size_t i=0; i!=
NDIM; ++i) {
191 for (std::size_t i=0; i<
NDIM; ++i) {
224 if constexpr (
NDIM <= 3) {
242 if (kernel_lattice_sum_axes.
any()) {
245 if ((kernel_lattice_sum_axes &&
periodic_axes) != kernel_lattice_sum_axes) {
247 "Displacements<" + std::to_string(
NDIM) +
248 ">::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";
284 for (
Level n = 0; n < nmax; ++n)
295 for (
size_t n = 0; n < 64; ++n) {
303 template <std::
size_t N, std::
size_t M>
304 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) {
305 std::array<std::size_t,
N - M> result;
306 if constexpr (
N != M) {
307 std::size_t nadded = 0;
308 auto value_to_skip_it = values_to_skip_sorted.begin();
309 assert(*value_to_skip_it <
N);
310 auto value_to_skip = *value_to_skip_it;
311 for (std::size_t i = 0; i <
N; ++i) {
312 if (i < value_to_skip) {
313 result[nadded++] = i;
314 }
else if (value_to_skip_it != values_to_skip_sorted.end()) {
316 if (value_to_skip_it != values_to_skip_sorted.end()) {
317 value_to_skip = *value_to_skip_it;
332 template<std::
size_t NDIM>
346 using Box = std::array<std::pair<Translation, Translation>,
NDIM>;
374 mutable std::optional<Displacement>
disp;
424 auto increment_along_dim = [
this](
size_t dim) {
433 for (
size_t i =
NDIM; i > 0; --i) {
434 const size_t cur_dim = i - 1;
438 increment_along_dim(cur_dim);
447 const auto filtered_out = [&,
this]() {
449 const auto& validator = this->parent->
validator_;
453 std::optional<Displacement> nulldisp;
454 result = !validator(
point.level(), point_pattern, nulldisp);
490 for (
size_t i = 0; i <
NDIM; ++i) {
498 const auto filtered_out = [&]() ->
bool {
506 while (!done && filtered_out()) {
517 const auto is_fixed_dim = dim ==
fixed_dim;
544 const Translation first_equiv_class = last_equiv_class - period + 1;
545 l_dim_min = std::max(first_equiv_class, l_dim_min);
555 const auto filtered_out = [&,
this]() {
557 const auto& validator = this->parent->
validator_;
561 std::optional<Displacement> nulldisp;
562 result = !validator(
point.level(), point_pattern, nulldisp);
567 if (filtered_out()) {
568 bool have_another_surface_layer;
611 for (
size_t d = 0;
d !=
NDIM; ++
d) {
661 if (
a.done &&
b.done)
return true;
662 if (
a.done ||
b.done)
return false;
663 return a.fixed_dim ==
b.fixed_dim &&
698 std::optional<Translation> probe_offset_radius = {})
703 bool has_finite_dimensions =
false;
704 const auto n =
center_.level();
705 for (
size_t d=0;
d!=
NDIM; ++
d) {
709 r = (n == 0) ? (r+1)/2 : (r *
Translation(1) << (n-1));
712 has_finite_dimensions =
true;
719 for (
size_t d=0;
d!=
NDIM; ++
d) {
800 const auto face_origin_is_center = [
this](
size_t d) {
811 const auto sort_key = [&](
size_t d) {
817 size_t face_dimension =
NDIM;
818 for (
size_t d=0;
d !=
NDIM; ++
d) {
820 if (face_dimension ==
NDIM || sort_key(
d) < sort_key(face_dimension)) face_dimension =
d;
826 const auto n =
center_.level();
829 r = (n == 0) ? (r+1)/2 : (r *
Translation(1) << (n-1));
831 probing_displacement_vec[face_dimension] = r;
835 if (!face_origin_is_center(face_dimension) || n == 0 ||
NDIM == 1)
848 size_t offset_dimension =
NDIM;
849 size_t unrestricted_dimension =
NDIM;
850 for (
size_t d=0;
d !=
NDIM; ++
d) {
851 if (
d == face_dimension)
continue;
854 offset_dimension =
d;
855 }
else if (unrestricted_dimension ==
NDIM) {
856 unrestricted_dimension =
d;
867 if (offset_dimension !=
NDIM) {
870 probing_displacement_vec[offset_dimension] =
offset;
874 const auto d = unrestricted_dimension;
877 const auto sign = right_distance >= left_distance ? +1 : -1;
878 probing_displacement_vec[
d] = sign *
offset;
891 template <
size_t NDIM>
908 const std::array<KernelRange, NDIM>& range,
910 double max_distsq_reached
915 for (
size_t i = 0; i <
NDIM; i++) {
916 if (is_lattice_summed[i]) {
918 }
else if (is_infinite_domain[i]) {
946 const auto twon = (
static_cast<Translation>(1) << level);
949 const auto map_to_range_twon = [&,
mask = ((~(
static_cast<std::uint64_t
>(0)) << (64-level)) >> (64-level))](std::int64_t x) -> std::int64_t {
950 const std::int64_t x_mapped = x &
mask;
955 const auto out_of_domain = [&](
const Translation& t) ->
bool {
956 return t < 0 || t >= twon;
960 const bool dest_is_in_domain = [&]() {
961 for(
size_t d=0;
d!=
NDIM; ++
d) {
967 if (dest_is_in_domain) {
975 bool among_standard_displacements =
true;
976 for(
size_t d=0;
d!=
NDIM; ++
d) {
977 const auto disp_d = (*displacement)[
d];
982 auto disp_d_eff_abs =
std::abs(disp_d);
985 const std::int64_t disp_d_eff = map_to_range_twon(disp_d);
986 disp_d_eff_abs = std::min(disp_d_eff,
std::abs(disp_d_eff-twon));
990 if (dest[
d].has_value()) {
992 const auto dest_d_in_cell = map_to_range_twon(dest_d);
996 auto t = (*displacement).translation();
997 t[
d] += (dest_d_in_cell - dest_d);
1005 if (disp_d_eff_abs > bmax_standard) {
1006 among_standard_displacements =
false;
1011 if (among_standard_displacements) {
Iterator class for lazy generation of surface points.
Definition displacements.h:368
std::optional< Displacement > disp
Memoized displacement from parent->center_ to point, computed by displacement(), reset by advance()
Definition displacements.h:374
Iterator(const BoxSurfaceDisplacementRange *p, Type type)
Constructs an iterator.
Definition displacements.h:603
Type
Definition displacements.h:370
@ End
Definition displacements.h:370
@ Begin
Definition displacements.h:370
size_t fixed_dim
Current fixed dimension (i.e. faces perpendicular to this axis are being iterated over)
Definition displacements.h:375
const std::optional< Displacement > & displacement() const
Definition displacements.h:582
friend bool operator!=(const Iterator &a, const Iterator &b)
Inequality comparison operator.
Definition displacements.h:673
bool done
Flag indicating iteration completion.
Definition displacements.h:384
const Point * pointer
Definition displacements.h:594
pointer operator->() const
Arrow operator for member access.
Definition displacements.h:633
Box unprocessed_bounds
Definition displacements.h:376
Iterator operator++(int)
Post-increment operator.
Definition displacements.h:648
std::ptrdiff_t difference_type
Definition displacements.h:593
std::input_iterator_tag iterator_category
Definition displacements.h:591
const BoxSurfaceDisplacementRange * parent
Pointer to parent surface.
Definition displacements.h:372
bool next_surface_layer()
Definition displacements.h:388
reference operator*() const
Dereferences the iterator.
Definition displacements.h:627
Point value_type
Definition displacements.h:592
void reset_along_dim(size_t dim)
Definition displacements.h:516
void advance_till_valid()
Perform advance, repeating if you are at a filtered point.
Definition displacements.h:496
Point point
Current point / box. This is always free to leave the simulation cell.
Definition displacements.h:373
friend bool operator==(const Iterator &a, const Iterator &b)
Equality comparison operator.
Definition displacements.h:660
Iterator & operator++()
Pre-increment operator.
Definition displacements.h:639
const Point & reference
Definition displacements.h:595
void advance()
Advances the iterator to the next surface point.
Definition displacements.h:421
Definition displacements.h:333
Displacement probing_displacement_
displacement to a nearby point on the surface; it may not be able to pass the filter,...
Definition displacements.h:360
std::function< bool(Level, const PointPattern &, std::optional< Displacement > &)> Validator
Definition displacements.h:341
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={}, std::optional< Translation > probe_offset_radius={})
Constructs a box with different radii and thicknesses for each dimension.
Definition displacements.h:693
Key< NDIM > Point
Definition displacements.h:335
const Key< NDIM > & center() const
Definition displacements.h:752
std::array< std::optional< Translation >, NDIM > SurfaceThickness
Definition displacements.h:345
const std::array< std::optional< int64_t >, NDIM > & box_radius() const
Definition displacements.h:757
const array_of_bools< NDIM > & is_lattice_summed() const
Definition displacements.h:767
Periodicity is_lattice_summed_
which dimensions are lattice summed?
Definition displacements.h:356
Validator validator_
optional validator function
Definition displacements.h:357
SurfaceThickness surface_thickness_
surface thickness in each dimension, measured in boxes. Real-space surface size is thus n-dependent.
Definition displacements.h:353
std::array< std::optional< Translation >, NDIM > BoxRadius
Definition displacements.h:344
const Displacement compute_probing_displacement()
Definition displacements.h:777
const std::array< std::optional< int64_t >, NDIM > & surface_thickness() const
Definition displacements.h:762
Hollowness hollowness_
does box contain non-surface points along each dimension?
Definition displacements.h:355
std::optional< Translation > probe_offset_radius_
Definition displacements.h:358
auto begin() const
Returns an iterator to the beginning of the surface points.
Definition displacements.h:731
Box box_
box bounds in each dimension.
Definition displacements.h:354
const Displacement & probing_displacement() const
Definition displacements.h:772
Point center_
Center point of the box.
Definition displacements.h:350
Key< NDIM > Displacement
Definition displacements.h:337
std::array< bool, NDIM > Hollowness
Definition displacements.h:347
auto end() const
Returns an iterator to the end of the surface points.
Definition displacements.h:737
Vector< std::optional< Translation >, NDIM > PointPattern
Definition displacements.h:336
std::array< std::pair< Translation, Translation >, NDIM > Box
Definition displacements.h:346
BoxRadius box_radius_
halved size of the box in each dimension, in half-SimulationCells.
Definition displacements.h:351
Definition displacements.h:892
std::function< double(const Displacement &)> DistanceSquaredFunc
Definition displacements.h:898
Vector< std::optional< Translation >, NDIM > PointPattern
Definition displacements.h:895
DistanceSquaredFunc default_distance_squared_
Definition displacements.h:1032
Key< NDIM > Displacement
Definition displacements.h:896
std::array< ExtraDomainPolicy, NDIM > domain_policies_
Definition displacements.h:1030
Key< NDIM > Point
Definition displacements.h:894
double max_distsq_reached_
Definition displacements.h:1033
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:940
std::array< KernelRange, NDIM > range_
Definition displacements.h:1031
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, double max_distsq_reached)
Definition displacements.h:905
Holds displacements for applying operators to avoid replicating for all operators.
Definition displacements.h:66
static std::array< std::vector< Key< NDIM > >, 64 > disp_periodic
displacements to be used with lattice-summed kernels
Definition displacements.h:70
static bool cmp_keys(const Key< NDIM > &a, const Key< NDIM > &b)
Definition displacements.h:89
const std::vector< Key< NDIM > > & get_disp()
return the standard displacements appropriate for operators w/o lattice summation
Definition displacements.h:261
const std::vector< Key< NDIM > > & get_disp(Level n, const array_of_bools< NDIM > &kernel_lattice_sum_axes)
Definition displacements.h:237
static std::vector< Key< NDIM > > disp
standard displacements to be used with standard kernels (range-unrestricted, no lattice sum)
Definition displacements.h:68
static Tensor< double > widths
cell width, used to order displacements from least to most real space distance
Definition displacements.h:71
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:275
static void make_disp(int bmax)
Definition displacements.h:103
static void make_disp_periodic(int bmax, Level n)
Definition displacements.h:159
static int bmax_default()
Definition displacements.h:74
static bool cmp_keys_periodic(const Key< NDIM > &a, const Key< NDIM > &b)
Definition displacements.h:96
static array_of_bools< NDIM > periodic_axes
along which axes lattice summation is performed?
Definition displacements.h:69
static void set_width(const Tensor< double > &width)
Definition displacements.h:290
Displacements()
Definition displacements.h:214
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:70
A tensor is a multidimensional array.
Definition tensor.h:318
float_scalar_type normf() const
Returns the Frobenius norm of the tensor.
Definition tensor.h:1727
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:13
ExtraDomainPolicy
Definition displacements.h:53
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
static double pop(std::vector< double > &v)
Definition SCF.cc:117
constexpr std::array< std::size_t, N-M > iota_array(std::array< std::size_t, M > values_to_skip_sorted)
Definition displacements.h:304
std::string type(const PairType &n)
Definition PNOParameters.h:18
static long abs(long a)
Definition tensor.h:219
static const double b
Definition nonlinschro.cc:119
static const double d
Definition nonlinschro.cc:121
static const double a
Definition nonlinschro.cc:118
Defines and implements most of Tensor.
void e()
Definition test_sig.cc:75
#define N
Definition testconv.cc:37
const double offset
Definition testfuns.cc:143
constexpr std::size_t NDIM
Definition testgconv.cc:54