MADNESS 0.10.1
bc.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_BC_H__INCLUDED
33#define MADNESS_MRA_BC_H__INCLUDED
34
35
36/// \file bc.h
37/// \brief Provides BoundaryConditions
38/// \ingroup mrabcext
39
43
44#include <array>
45#include <cstddef>
46#include <iostream>
47
48namespace madness {
49
58
59/*!
60 \brief This class is used to specify boundary conditions for all operators
61 \ingroup mrabcext
62
63 Exterior boundary conditions (i.e., on the simulation domain)
64 are associated with operators (not functions). The types of
65 boundary conditions available are in the enum BCType.
66
67 The default boundary conditions are obtained from the FunctionDefaults.
68 For non-zero Dirichlet and Neumann conditions additional information
69 must be provided when derivative operators are constructed. For integral
70 operators, only periodic and free space are supported.
71*/
72template <std::size_t NDIM> class BoundaryConditions {
73private:
74 // Used to use STL vector but static data on a MAC was
75 // causing problems.
77
78public:
79 /// Constructor. Default boundary condition set to free space
81 for (std::size_t i = 0; i < NDIM * 2; ++i)
82 bc[i] = code;
83 }
84
85 /// Constructor sets boundary condition per axis
86 template <std::size_t N = NDIM, typename = std::enable_if_t<N!=0>>
87 BoundaryConditions(const std::array<BCType, N>& bc_per_axis) {
88 for (std::size_t i = 0; i < NDIM * 2; ++i)
89 bc[i] = bc_per_axis[i / 2];
90 }
91
92 /// Constructor sets boundary condition per boundary
93 template <std::size_t N = NDIM, typename = std::enable_if_t<N!=0>>
94 BoundaryConditions(const std::array<BCType, N*2>& bc_per_boundary) {
95 for (std::size_t i = 0; i < NDIM * 2; ++i)
96 bc[i] = bc_per_boundary[i];
97 }
98
99 /// Copy constructor is deep
100 BoundaryConditions(const BoundaryConditions<NDIM> &other) { *this = other; }
101
102 /// Assignment makes deep copy
104 if (&other != this) {
105 for (std::size_t i = 0; i < NDIM * 2; ++i)
106 bc[i] = other.bc[i];
107 }
108 return *this;
109 }
110
111 /// Returns value of boundary condition
112
113 /// @param d Dimension (0,...,NDIM-1) for boundary condition
114 /// @param i Side (0=left, 1=right) for boundary condition
115 /// @return Value of boundary condition
116 BCType operator()(std::size_t d, int i) const {
117 MADNESS_ASSERT(d < NDIM && i >= 0 && i < 2);
118 return bc[2 * d + i];
119 }
120
121 /// Returns reference to boundary condition
122
123 /// @param d Dimension (0,...,NDIM-1) for boundary condition
124 /// @param i Side (0=left, 1=right) for boundary condition
125 /// @return Value of boundary condition
126 BCType &operator()(std::size_t d, int i) {
127 MADNESS_ASSERT(d < NDIM && i >= 0 && i < 2);
128 return bc[2 * d + i];
129 }
130
131 template <typename Archive> void serialize(const Archive &ar) { ar & bc; }
132
133 /// Translates code into human readable string
134
135 /// @param code Code for boundary condition
136 /// @return String describing boundary condition code
137 static const char *code_as_string(BCType code) {
138 static const char *codes[] = {"zero", "periodic", "free",
139 "Dirichlet", "zero Neumann", "Neumann"};
140 return codes[code];
141 }
142
143 /// Convenience for application of integral operators
144
145 /// @return Returns a vector indicating if dimensions [0, ND) are periodic
146 template <std::size_t ND = NDIM>
147 std::enable_if_t<ND <= NDIM, array_of_bools<ND>> is_periodic() const {
148 array_of_bools<ND> v(false);
149 for (std::size_t d = 0; d < ND; ++d) {
150 MADNESS_ASSERT(bc[2 * d + 1] == bc[2 * d]);
151 v[d] = (bc[2 * d] == BC_PERIODIC);
152 }
153 return v;
154 }
155
156 /// Checks whether the boundary condition along any axis is periodic
157
158 /// @return Returns true if any dimension is periodic
159 bool is_periodic_any() const {
160 for (std::size_t d = 0; d < NDIM; ++d) {
161 MADNESS_ASSERT(bc[2 * d + 1] == bc[2 * d]);
162 if (bc[2 * d] == BC_PERIODIC)
163 return true;
164 }
165 return false;
166 }
167
168 /// Checks whether the boundary condition along all axes is periodic
169
170 /// @return Returns true if every dimension is periodic
171 bool is_periodic_all() const {
172 for (std::size_t d = 0; d < NDIM; ++d) {
173 MADNESS_ASSERT(bc[2 * d + 1] == bc[2 * d]);
174 if (bc[2 * d] != BC_PERIODIC)
175 return false;
176 }
177 return true;
178 }
179
180 /// Convenience for construction of range-restricted integral operators
181
182 /// constructs array of KernelRange objects for every dimension; for every periodic dimension the range is restricted according to \p r and \p sigma
183 /// @param r range extent in simulation cell units; kernel is restricted to `[-r/2, r/2]`
184 /// @param sigma optional smoothing paramter (in simulation cell units); if given, use erf-attenuated range restriction (\sa KernelRange::Type)
185 /// @return an array of kernel ranges for each dimension
186 template <std::size_t ND = NDIM>
187 std::enable_if_t<ND <= NDIM, std::array<KernelRange, ND>> make_range(unsigned int r, std::optional<double> sigma = {}) const {
188 std::array<KernelRange, ND> result;
189 for (std::size_t d = 0; d < ND; ++d) {
190 MADNESS_ASSERT(bc[2 * d + 1] == bc[2 * d]);
191 if (bc[2 * d] == BC_PERIODIC)
192 result[d] = sigma ? KernelRange{r, *sigma} : KernelRange{r};
193 }
194 return result;
195 }
196
197 /// Convenience for construction of range-restricted integral operators
198
199 /// \note same as make_range(), but makes a std::vector
200 /// constructs vector of KernelRange objects for every dimension; for every periodic dimension the range is restricted according to \p r and \p sigma
201 /// @param r range extent in simulation cell units; kernel is restricted to `[-r/2, r/2]`
202 /// @param sigma optional smoothing paramter (in simulation cell units); if given, use erf-attenuated range restriction (\sa KernelRange::Type)
203 /// @return a vector of kernel ranges for each dimension
204 std::vector<KernelRange> make_range_vector(unsigned int r, std::optional<double> sigma = {}) const {
205 const auto result_array = make_range(r, sigma);
206 return std::vector<KernelRange>(result_array.begin(), result_array.end());
207 }
208
209};
210
211template <std::size_t NDIM>
212static inline std::ostream &operator<<(std::ostream &s,
213 const BoundaryConditions<NDIM> &bc) {
214 s << "BoundaryConditions(";
215 for (unsigned int d = 0; d < NDIM; ++d) {
216 s << bc.code_as_string(bc(d, 0)) << ":" << bc.code_as_string(bc(d, 1));
217 if (d == NDIM - 1)
218 s << ")";
219 else
220 s << ", ";
221 }
222 return s;
223}
224
225template <std::size_t NDIM>
229
230template <std::size_t NDIM>
234
235} // namespace madness
236
237#endif // MADNESS_MRA_BC_H__INCLUDED
This class is used to specify boundary conditions for all operators.
Definition bc.h:72
BCType bc[NDIM *2]
Definition bc.h:76
BoundaryConditions(BCType code=BC_FREE)
Constructor. Default boundary condition set to free space.
Definition bc.h:80
BoundaryConditions(const std::array< BCType, N > &bc_per_axis)
Constructor sets boundary condition per axis.
Definition bc.h:87
BCType operator()(std::size_t d, int i) const
Returns value of boundary condition.
Definition bc.h:116
BoundaryConditions< NDIM > & operator=(const BoundaryConditions< NDIM > &other)
Assignment makes deep copy.
Definition bc.h:103
BCType & operator()(std::size_t d, int i)
Returns reference to boundary condition.
Definition bc.h:126
BoundaryConditions(const BoundaryConditions< NDIM > &other)
Copy constructor is deep.
Definition bc.h:100
static const char * code_as_string(BCType code)
Translates code into human readable string.
Definition bc.h:137
void serialize(const Archive &ar)
Definition bc.h:131
BoundaryConditions(const std::array< BCType, N *2 > &bc_per_boundary)
Constructor sets boundary condition per boundary.
Definition bc.h:94
syntactic sugar for std::array<bool, N>
Definition array_of_bools.h:19
const double sigma
Definition dielectric.cc:185
static const double v
Definition hatom_sf_dirac.cc:20
Defines madness::MadnessException for exception handling.
#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
array_of_bools< NDIM > lattice_sum()
Definition bc.h:231
BCType
Definition bc.h:50
@ BC_DIRICHLET
Definition bc.h:54
@ BC_NEUMANN
Definition bc.h:56
@ BC_ZERO
Definition bc.h:51
@ BC_PERIODIC
Definition bc.h:52
@ BC_ZERONEUMANN
Definition bc.h:55
@ BC_FREE
Definition bc.h:53
std::ostream & operator<<(std::ostream &os, const particle< PDIM > &p)
Definition lowrankfunction.h:397
array_of_bools< NDIM > no_lattice_sum()
Definition bc.h:226
static const double d
Definition nonlinschro.cc:121
constexpr std::size_t NDIM
Definition testgconv.cc:54