1 #ifndef MEDUSA_BITS_DOMAINS_BOXSHAPE_HPP_
2 #define MEDUSA_BITS_DOMAINS_BOXSHAPE_HPP_
20 template <
typename vec_t>
22 for (
int i = 0; i <
dim; ++i) {
24 "Box has no volume, sides in dimension %d have same coordinate %g.",
30 template <
typename vec_t>
32 for (
int i = 0; i <
dim; ++i) {
33 if (!(beg_[i] - margin_ <= point[i] && point[i] <= end_[i] + margin_)) {
40 template <
typename vec_t>
44 for (
int i = 0; i <
dim; ++i) counts[i] =
iceil((end_[i] - beg_[i]) / step) + 1;
45 return discretizeBoundary(counts, type);
48 template <
typename vec_t>
51 for (
int x : counts) {
52 assert_msg(x >= 2,
"All counts must be greater than 2, got counts = %s", counts);
59 }
else if (
dim == 2) {
60 const int TOP = (type == 0) ? -4 : type;
61 const int RIGHT = (type == 0) ? -2 : type;
62 const int BOTTOM = (type == 0) ? -3 : type;
63 const int LEFT = (type == 0) ? -1 : type;
65 scalar_t step = (end_[0] - beg_[0]) / (counts[0] - 1);
66 for (
int i = 1; i < counts[0]-1; ++i) {
67 point[0] = beg_[0] + i*step;
69 normal[0] = 0; normal[1] = -1;
72 normal[0] = 0; normal[1] = 1;
75 step = (end_[1] - beg_[1]) / (counts[1] - 1);
76 for (
int i = 1; i < counts[1]-1; ++i) {
77 point[1] = beg_[1] + i*step;
79 normal[0] = -1; normal[1] = 0;
82 normal[0] = 1; normal[1] = 0;
87 domain.
addBoundaryNode(vec_t({beg_[0], end_[1]}), TOP, vec_t({-1, 1}).normalized());
88 domain.
addBoundaryNode(vec_t({end_[0], beg_[1]}), BOTTOM, vec_t({1, -1}).normalized());
89 }
else if (
dim == 3) {
90 int LEFT = -1, RIGHT = -2, FRONT = -3, BACK = -4, BOTTOM = -5, TOP = -6;
91 if (type != 0) LEFT = RIGHT = FRONT = BACK = BOTTOM = TOP = type;
92 scalar_t step = (end_[0] - beg_[0]) / (counts[0] - 1);
93 for (
int i = 1; i < counts[0]-1; ++i) {
94 point[0] = beg_[0] + i*step;
97 normal = vec_t({0, -1, -1}).normalized();
101 normal = vec_t({0, -1, 1}).normalized();
105 normal = vec_t({0, 1, -1}).normalized();
109 normal = vec_t({0, 1, 1}).normalized();
112 scalar_t inner_step = (end_[1] - beg_[1]) / (counts[1] - 1);
113 for (
int j = 1; j < counts[1]-1; ++j) {
114 point[1] = beg_[1] + j*inner_step;
116 normal = vec_t({0, 0, -1});
119 normal = vec_t({0, 0, 1});
122 inner_step = (end_[2] - beg_[2]) / (counts[2] - 1);
123 for (
int j = 1; j < counts[2]-1; ++j) {
124 point[2] = beg_[2] + j*inner_step;
126 normal = vec_t({0, -1, 0});
129 normal = vec_t({0, 1, 0});
133 step = (end_[1] - beg_[1]) / (counts[1] - 1);
134 for (
int i = 1; i < counts[1]-1; ++i) {
135 point[1] = beg_[1] + i*step;
138 normal = vec_t({-1, 0, -1}).normalized();
142 normal = vec_t({-1, 0, 1}).normalized();
146 normal = vec_t({1, 0, -1}).normalized();
150 normal = vec_t({1, 0, 1}).normalized();
153 scalar_t inner_step = (end_[2] - beg_[2]) / (counts[2] - 1);
154 for (
int j = 1; j < counts[2]-1; ++j) {
155 point[2] = beg_[2] + j*inner_step;
157 normal = vec_t({-1, 0, 0});
160 normal = vec_t({1, 0, 0});
164 step = (end_[2] - beg_[2]) / (counts[2] - 1);
165 for (
int i = 1; i < counts[2]-1; ++i) {
166 point[2] = beg_[2] + i*step;
169 normal = vec_t({-1, -1, 0}).normalized();
173 normal = vec_t({-1, 1, 0}).normalized();
177 normal = vec_t({1, -1, 0}).normalized();
181 normal = vec_t({1, 1, 0}).normalized();
184 domain.
addBoundaryNode(beg_, BOTTOM, vec_t({-1, -1, -1}).normalized());
187 vec_t({1, -1, -1}).normalized());
189 vec_t({-1, 1, 1}).normalized());
191 vec_t({1, 1, -1}).normalized());
193 vec_t({-1, 1, -1}).normalized());
195 vec_t({-1, -1, 1}).normalized());
197 vec_t({1, -1, 1}).normalized());
202 template <
typename vec_t>
204 return os <<
"BoxShape(" << beg_.transpose() <<
", " << end_.transpose() <<
")";
207 template <
typename vec_t>
211 static_assert(0 <=
dim &&
dim <= 3,
"Only dimensions up to 3 are supported.");
216 }
else if (
dim == 2) {
217 const int TOP = (type == 0) ? -4 : type;
218 const int RIGHT = (type == 0) ? -2 : type;
219 const int BOTTOM = (type == 0) ? -3 : type;
220 const int LEFT = (type == 0) ? -1 : type;
223 vec_t p2 = {beg_[0], end_[1]};
225 vec_t p4 = {end_[0], beg_[1]};
244 }
else if (
dim == 3) {
245 int LEFT = -1, RIGHT = -2, FRONT = -3, BACK = -4, BOTTOM = -5, TOP = -6;
246 if (type != 0) LEFT = RIGHT = FRONT = BACK = BOTTOM = TOP = type;
251 side_beg[0] = beg_[1]; side_beg[1] = beg_[2];
252 side_end[0] = end_[1]; side_end[1] = end_[2];
254 auto dr2 = [&](
const Vec<scalar_t, 2>& p) {
return dr({beg_[0], p[0], p[1]}); };
256 vec_t pos; pos[0] = beg_[0];
257 for (
int i : domain2d.interior()) {
258 pos[1] = domain2d.pos(i, 0); pos[2] = domain2d.pos(i, 1);
261 auto dr22 = [&](
const Vec<scalar_t, 2>& p) {
return dr({end_[0], p[0], p[1]}); };
264 for (
int i : domain2d.interior()) {
265 pos[1] = domain2d.pos(i, 0); pos[2] = domain2d.pos(i, 1);
270 side_beg[0] = beg_[0]; side_beg[1] = beg_[2];
271 side_end[0] = end_[0]; side_end[1] = end_[2];
273 auto dr2 = [&](
const Vec<scalar_t, 2>& p) {
return dr({p[0], beg_[1], p[1]}); };
275 vec_t pos; pos[1] = beg_[1];
276 for (
int i : domain2d.interior()) {
277 pos[0] = domain2d.pos(i, 0); pos[2] = domain2d.pos(i, 1);
280 auto dr22 = [&](
const Vec<scalar_t, 2>& p) {
return dr({p[0], end_[1], p[1]}); };
283 for (
int i : domain2d.interior()) {
284 pos[0] = domain2d.pos(i, 0); pos[2] = domain2d.pos(i, 1);
289 side_beg[0] = beg_[0]; side_beg[1] = beg_[1];
290 side_end[0] = end_[0]; side_end[1] = end_[1];
292 auto dr2 = [&](
const Vec<scalar_t, 2>& p) {
return dr({p[0], p[1], beg_[2]}); };
294 vec_t pos; pos[2] = beg_[2];
295 for (
int i : domain2d.interior()) {
296 pos[0] = domain2d.pos(i, 0); pos[1] = domain2d.pos(i, 1);
299 auto dr22 = [&](
const Vec<scalar_t, 2>& p) {
return dr({p[0], p[1], end_[2]}); };
302 for (
int i : domain2d.interior()) {
303 pos[0] = domain2d.pos(i, 0); pos[1] = domain2d.pos(i, 1);
311 template <
typename vec_t>
313 scalar_t step,
int internal_type,
int boundary_type)
const {
315 for (
int i = 0; i <
dim; ++i) counts[i] =
iceil((end_[i] - beg_[i]) / step) + 1;
316 return discretize(counts, internal_type, boundary_type);
319 template <
typename vec_t>
321 const Vec<int, dim>& counts,
int internal_type,
int boundary_type)
const {
322 auto domain = discretizeBoundary(counts, boundary_type);
324 if (internal_type == 0) internal_type = 1;
325 for (
const vec_t& p :
linspace(beg_, end_, counts_internal,
false)) {
326 domain.addInternalNode(p, internal_type);
333 #endif // MEDUSA_BITS_DOMAINS_BOXSHAPE_HPP_