PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
complexGeomObjects.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2026 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#include "complexGeomObjects.h"
12#include "geomUtilFunctions.h"
13#include "util/function.h"
14#include "util/vecMethods.h"
15#include "util/io.h"
16#include <vector>
17#include <set>
18
19namespace {
20 std::string printErrMsg(const std::string &geom_type,
21 const std::vector<double> &params,
22 const std::vector<size_t> &num_params_needed) {
23
24 std::ostringstream oss;
25
26 oss << "Error: Number of parameters needed to create geometry = "
27 << geom_type << " are "
28 << util::io::printStr(num_params_needed, 0)
29 << ". But the number of parameters provided are "
30 << params.size()
31 << " and the parameters are "
32 << util::io::printStr(params, 0)
33 << ". Exiting.\n";
34
35 return oss.str();
36 }
37};
38
39//
40// AnnulusGeomObject
41//
42namespace geom {
43
45 return d_outObj_p->volume() - d_inObj_p->volume();
46 }
47
49
50 // we use the formula for centroid of composite objects
51 // x = sum_i sign(i) V_i x_i / sum_i sign(i) V_i
52 // where sign(i) = +1 if object is filling
53 // sign(i) = -1 if object is empty
54 auto vol = volume();
55 if (util::isGreater(vol, 0.))
56 return (1./vol) * (d_outObj_p->volume() * d_outObj_p->center()
58 else
59 return d_outObj_p->center();
60 }
61
62 std::pair<util::Point, util::Point> AnnulusGeomObject::box
63 () const {
64 return d_outObj_p->box();
65 }
66
67 std::pair<util::Point, util::Point> AnnulusGeomObject::box
68 (const double &tol) const {
69 return d_outObj_p->box(tol);
70 }
71
73
75 }
76
78
79 return d_outObj_p->boundingRadius();
80 }
81
82 bool
84
85 // should be outside inner object and inside outer object
86 return !d_inObj_p->isInside(x) && d_outObj_p->isInside(x);
87 }
88
89 bool
91 return !isInside(x);
92 }
93
95 const double &tol) const {
96
97 return d_outObj_p->isNear(x, tol) || d_inObj_p->isNear(x, tol);
98 }
99
101 const double &tol,
102 const bool
103 &within) const {
104
105 return d_outObj_p->isNearBoundary(x, tol, within) ||
106 d_inObj_p->isNearBoundary(x, tol, within);
107 }
108
110 const util::Point &x) const {
111
112 return isNearBoundary(x, 1.0E-8, false);
113 }
114
116 const std::pair<util::Point, util::Point> &box) const {
117
118 for (auto p: geom::getCornerPoints(d_dim, box))
119 if (!this->isInside(p))
120 return false;
121
122 return true;
123 }
124
126 const std::pair<util::Point, util::Point> &box) const {
127
128 bool intersect = false;
129 for (auto p: geom::getCornerPoints(d_dim, box))
130 intersect = this->isInside(p);
131
132 return !intersect;
133 }
134
136 const std::pair<util::Point, util::Point> &box,
137 const double &tol) const {
138
139 return d_outObj_p->isNear(box, tol) || d_inObj_p->isNear(box, tol);
140 }
141
143 const std::pair<util::Point, util::Point> &box) const {
144
145 // need to check all four corner points
146 for (auto p: geom::getCornerPoints(d_dim, box))
147 if (this->isInside(p))
148 return true;
149
150 return false;
151 }
152
153 std::string
154 AnnulusGeomObject::printStr(int nt, int lvl) const {
155
156 auto tabS = util::io::getTabS(nt);
157
158 std::ostringstream oss;
159
160 oss << tabS << "------- AnnulusGeomObject --------" << std::endl
161 << std::endl;
162 oss << tabS << "Name = " << d_name << std::endl;
163 oss << tabS << "Center = " << center().printStr() << std::endl;
164 oss << tabS << "Inner object info:" << std::endl;
165 oss << d_inObj_p->printStr(nt + 1, lvl);
166 oss << tabS << "Outer object info:" << std::endl;
167 oss << d_outObj_p->printStr(nt + 1, lvl);
168
169 if (lvl > 0)
170 oss << tabS << "Bounding box: "
171 << util::io::printBoxStr(box(0.), nt + 1);
172
173 if (lvl == 0)
174 oss << std::endl;
175
176 return oss.str();
177 }
178
179}// AnnulusGeomObject
180
181//
182// ComplexGeomObject
183//
184namespace geom {
186
187 double volume = 0.;
188 for (size_t i = 0; i < d_objFlag.size(); i++)
189 volume += d_obj[i]->volume() * d_objFlagInt[i];
190
191 return volume;
192 }
193
195
196 // use formula for centroid of composite objects
197 auto vol = volume();
198 if (util::isGreater(vol, 0.)) {
199 auto center = util::Point();
200 for (size_t i = 0; i < d_objFlag.size(); i++)
201 center += d_obj[i]->volume() * d_objFlagInt[i] * d_obj[i]->center();
202 return (1./vol) * center;
203 }
204 else {
205
206 // find biggest object that has positive d_objFlagInt
207 // (that is it is a filling and not void object)
208 std::vector<double> vol_vec(d_obj.size());
209 for (size_t i = 0; i < d_obj.size(); i++)
210 vol_vec[i] = d_obj[i]->volume() * d_objFlagInt[i];
211
212 auto max_vol_obj = util::methods::maxIndex(vol_vec);
213 return d_obj[max_vol_obj]->center();
214 }
215 }
216
217 std::pair<util::Point, util::Point> ComplexGeomObject::box
218 () const {
219
220 return box(0.);
221 }
222
223 std::pair<util::Point, util::Point> ComplexGeomObject::box
224 (const double &tol) const {
225
226 auto p1 = d_obj[0]->box(tol).first;
227 auto p2 = d_obj[0]->box(tol).second;
228
229 for (size_t i = 1; i < d_objFlag.size(); i++) {
230
231 auto q1 = d_obj[i]->box(tol).first;
232 auto q2 = d_obj[i]->box(tol).second;
233
234 for (size_t i = 0; i < 3; i++) {
235 if (q1[i] < p1[i])
236 p1[i] = q1[i];
237 if (q2[i] > p2[i])
238 p2[i] = q2[i];
239 }
240 }
241
242 return std::make_pair(p1, p2);
243 }
244
246
247 auto box = this->box();
248 return 0.5 * (box.first - box.second).length();
249 }
250
252
253 auto box = this->box();
254 return 0.5 * (box.first - box.second).length();
255 }
256
257 bool
259
260 // point inside means x should be inside in the object with plus flag and
261 // outside in the object with minus flag
262 bool point_inside = d_obj[0]->isInside(x);
263 for (size_t i = 1; i < d_objFlag.size(); i++) {
264
265 const auto &obj_i = d_obj[i];
266 if (d_objFlagInt[i] < 0)
267 point_inside = point_inside and !obj_i->isInside(x);
268 else
269 point_inside = point_inside or obj_i->isInside(x);
270 }
271
272 return point_inside;
273 }
274
275 bool
277 return !isInside(x);
278 }
279
281 const double &tol) const {
282
283 bool is_near = d_obj[0]->isNear(x, tol);
284 for (size_t i = 1; i < d_objFlag.size(); i++) {
285
286 const auto &obj_i = d_obj[i];
287 is_near = is_near or obj_i->isNear(x, tol);
288 }
289
290 return is_near;
291 }
292
294 const double &tol,
295 const bool
296 &within) const {
297
298 bool is_near = d_obj[0]->isNearBoundary(x, tol, within);
299 for (size_t i = 1; i < d_objFlag.size(); i++) {
300
301 const auto &obj_i = d_obj[i];
302 is_near = is_near or obj_i->isNearBoundary(x, tol, within);
303 }
304
305 return is_near;
306 }
307
309 const util::Point &x) const {
310
311 return isNearBoundary(x, 1.0E-8, false);
312 }
313
315 const std::pair<util::Point, util::Point> &box) const {
316
317 for (auto p: geom::getCornerPoints(d_dim, box))
318 if (!this->isInside(p))
319 return false;
320
321 return true;
322 }
323
325 const std::pair<util::Point, util::Point> &box) const {
326
327 bool intersect = false;
328 for (auto p: geom::getCornerPoints(d_dim, box))
329 intersect = this->isInside(p);
330
331 return !intersect;
332 }
333
335 const std::pair<util::Point, util::Point> &box,
336 const double &tol) const {
337
338 bool is_near = d_obj[0]->isNear(box, tol);
339 for (size_t i = 1; i < d_objFlag.size(); i++) {
340
341 const auto &obj_i = d_obj[i];
342 is_near = is_near or obj_i->isNear(box, tol);
343 }
344
345 return is_near;
346 }
347
349 const std::pair<util::Point, util::Point> &box) const {
350
351 // need to check all four corner points
352 for (auto p: geom::getCornerPoints(d_dim, box))
353 if (this->isInside(p))
354 return true;
355
356 return false;
357 }
358
359 std::string
360 ComplexGeomObject::printStr(int nt, int lvl) const {
361
362 auto tabS = util::io::getTabS(nt);
363
364 std::ostringstream oss;
365
366 oss << tabS << "------- ComplexGeomObject --------" << std::endl
367 << std::endl;
368 oss << tabS << "Name = " << d_name << std::endl;
369 oss << tabS << "Center = " << center().printStr() << std::endl;
370 oss << tabS << "Object info:" << std::endl;
371 auto ocount = 0;
372 for (const auto &p: d_obj) {
373 oss << tabS << "Object id: " << ocount << std::endl;
374 oss << tabS << "Object flag: " << d_objFlag[ocount] << std::endl;
375 oss << tabS << "Object int flag: " << d_objFlagInt[ocount] << std::endl;
376 oss << p->printStr(nt + 1, lvl);
377 ocount++;
378 }
379
380 if (lvl > 0)
381 oss << tabS << "Bounding box: "
382 << util::io::printBoxStr(box(0.), nt + 1);
383
384 if (lvl == 0)
385 oss << std::endl;
386
387 return oss.str();
388 }
389
390}// ComplexGeomObject
std::string printStr(int nt, int lvl) const override
Returns the string containing printable information about the object.
bool doesIntersect(const util::Point &x) const override
Checks if point lies exactly on the boundary.
bool isNear(const util::Point &x, const double &tol) const override
Checks if point is within given distance of this object.
double inscribedRadius() const override
Computes the radius of biggest circle/sphere completely within the object.
bool isOutside(const util::Point &x) const override
Checks if point is outside of this object.
GeomObject * d_outObj_p
Outer object.
util::Point center() const override
Computes the center of object.
double boundingRadius() const override
Computes the radius of smallest circle/sphere such that object can be fit into it.
size_t d_dim
Dimension objects live in.
bool isInside(const util::Point &x) const override
Checks if point is inside this object.
double volume() const override
Computes the volume (area in 2d, length in 1d) of object.
std::pair< util::Point, util::Point > box() const override
Computes the bounding box of object.
GeomObject * d_inObj_p
Inner object.
bool isNearBoundary(const util::Point &x, const double &tol, const bool &within) const override
cons
bool isNear(const util::Point &x, const double &tol) const override
Checks if point is within given distance of this object.
bool isOutside(const util::Point &x) const override
Checks if point is outside of this object.
bool isInside(const util::Point &x) const override
Checks if point is inside this object.
double boundingRadius() const override
Computes the radius of smallest circle/sphere such that object can be fit into it.
std::vector< int > d_objFlagInt
Object integer flags. Here, +1 means object is filling and -1 means object is void.
bool doesIntersect(const util::Point &x) const override
Checks if point lies exactly on the boundary.
size_t d_dim
Dimension objects live in.
double inscribedRadius() const override
Computes the radius of biggest circle/sphere completely within the object.
double volume() const override
Computes the volume (area in 2d, length in 1d) of object.
bool isNearBoundary(const util::Point &x, const double &tol, const bool &within) const override
cons
std::pair< util::Point, util::Point > box() const override
Computes the bounding box of object.
util::Point center() const override
Computes the center of object.
std::vector< std::string > d_objFlag
Object flag.
std::vector< std::shared_ptr< GeomObject > > d_obj
Object.
std::string printStr(int nt, int lvl) const override
Returns the string containing printable information about the object.
virtual std::pair< util::Point, util::Point > box() const
Computes the bounding box of object.
virtual bool isNearBoundary(const util::Point &x, const double &tol, const bool &within) const
Checks if point is within given distance of this object.
virtual bool isNear(const util::Point &x, const double &tol) const
Checks if point is within given distance of this object.
virtual std::string printStr(int nt, int lvl) const
Returns the string containing printable information about the object.
virtual bool isInside(const util::Point &x) const
Checks if point is inside this object.
virtual double volume() const
Computes the volume (area in 2d, length in 1d) of object.
virtual util::Point center() const
Computes the center of object.
const std::string d_name
name of object
virtual double boundingRadius() const
Computes the radius of smallest circle/sphere such that object can be fit into it.
virtual double inscribedRadius() const
Computes the radius of biggest circle/sphere completely within the object.
std::string printErrMsg(const std::string &geom_type, const std::vector< double > &params, const std::vector< size_t > &num_params_needed)
std::vector< util::Point > getCornerPoints(size_t dim, const std::pair< util::Point, util::Point > &box)
Returns all corner points in the box.
std::string printBoxStr(const std::pair< util::Point, util::Point > &box, int nt=print_default_tab)
Returns formatted string for output.
Definition io.h:188
std::string getTabS(int nt)
Returns tab spaces of a given size.
Definition io.h:39
std::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
Definition io.h:53
size_t maxIndex(const std::vector< T > &data)
Returns the index corresponding to maximum from list of data.
Definition vecMethods.h:38
bool isGreater(const double &a, const double &b)
Returns true if a > b.
Definition function.cpp:15
A structure to represent 3d vectors.
Definition point.h:30
std::string printStr(int nt=0, int lvl=0) const
Returns the string containing printable information about the object.
Definition point.h:94