PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
geomObjectsUtil.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 "geomObjects.h"
12#include "complexGeomObjects.h"
13#include "openRectChannel2D.h"
14#include "openCuboidChannel3D.h"
15#include "geomObjectsUtil.h"
16#include <iostream>
17#include "geomUtilFunctions.h"
18#include "util/function.h"
19#include "util/vecMethods.h"
20#include "util/io.h"
21#include "util/json.h"
22#include <set>
23#include <stdexcept>
24#include <vector>
25
26namespace {
27 std::string printErrMsg(const std::string &geom_type,
28 const std::vector<double> &params,
29 const std::vector<size_t> &num_params_needed) {
30
31 std::ostringstream oss;
32
33 oss << "Error: Number of parameters needed to create geometry = "
34 << geom_type << " are "
35 << util::io::printStr(num_params_needed, 0)
36 << ". But the number of parameters provided are "
37 << params.size()
38 << " and the parameters are "
39 << util::io::printStr(params, 0)
40 << ". Exiting.\n";
41
42 return oss.str();
43 }
44};
45
46namespace geom {
47 std::vector<size_t> getNumParamsRequired(std::string geom_type) {
48
49 if (geom_type == "line")
50 return {1, 4, 6};
51 else if (geom_type == "plane")
52 return {6};
53 else if (geom_type == "triangle")
54 return {1, 4, 7, 9};
55 else if (geom_type == "square")
56 return {1, 4, 6};
57 else if (geom_type == "rectangle")
58 return {2, 5, 6};
59 else if (geom_type == "hexagon")
60 return {1, 4, 7};
61 else if (geom_type == "drum2d")
62 return {2, 5, 8};
63 else if (geom_type == "cube")
64 return {1, 4, 6};
65 else if (geom_type == "cuboid")
66 return {3, 6};
67 else if (geom_type == "circle")
68 return {1, 4};
69 else if (geom_type == "sphere")
70 return {1, 4};
71 else if (geom_type == "ellipse")
72 return {6};
73 else if (geom_type == "ellipsoid")
74 return {6, 10};
75 else if (geom_type == "cylinder")
76 return {7, 8};
77 else if (geom_type == "angled_rectangle")
78 return {6};
79 else if (geom_type == "angled_cuboid")
80 return {6};
81 else if (geom_type == "rectangle_minus_rectangle")
82 return {12};
83 else if (geom_type == "cuboid_minus_cuboid")
84 return {12};
85 else if (geom_type == "circle_minus_circle")
86 return {5};
87 else if (geom_type == "ellipse_minus_ellipse")
88 return {8};
89 else if (geom_type == "sphere_minus_sphere")
90 return {5};
91 else if (geom_type == "open_rect_channel_2d")
92 return {6};
93 else if (geom_type == "open_cuboid_channel_3d")
94 return {8};
95 else {
96 throw std::invalid_argument(
98 << "Error: Invalid geometry type: " << geom_type << std::endl);
99 }
100 }
101
102 bool
103 isNumberOfParamForGeometryValid(size_t n, std::string geom_type) {
104
105 return util::methods::isInList(n, getNumParamsRequired(geom_type));
106 }
107
109 std::string geom_type,
110 std::vector<std::string> vec_type) {
111
112 int num_params = 0;
113 for (const auto &s: vec_type) {
114 // only consider the biggest parameter set from the list
115 auto nps = getNumParamsRequired(s);
116 if (nps.size() > 0)
117 num_params += nps[nps.size() - 1];
118 else {
119 throw std::invalid_argument(
121 << "Error: Geometry type = " << s
122 << " has zero number of parameters required. \n");
123 }
124 }
125 return n == num_params;
126 }
127
128 bool
129 checkParamForGeometry(size_t n, std::string geom_type) {
130
131 return !isNumberOfParamForGeometryValid(n, geom_type);
132 }
133
135 std::string geom_type,
136 std::vector<std::string> vec_type) {
137
138 return !isNumberOfParamForComplexGeometryValid(n, geom_type, vec_type);
139 }
140
141
142
143 void createGeomObjectOld(const std::string &type,
144 const std::vector<double> &params,
145 const std::vector<std::string> &vec_type,
146 const std::vector<std::string> &vec_flag,
147 std::shared_ptr<geom::GeomObject> &obj,
148 bool perform_check) {
149
150 // for any of the objects below, issue error if number of parameters not
151 // sufficient regardless of perform_check value
152 std::vector<std::string> no_default_obj = {"cylinder", "complex",
153 "rectangle_minus_rectangle",
154 "cuboid_minus_cuboid",
155 "circle_minus_circle",
156 "ellipse_minus_ellipse",
157 "sphere_minus_sphere",
158 "open_rect_channel_2d",
159 "open_cuboid_channel_3d"};
160
161 bool check_passed; // true means check passed
162 if (type != "complex")
163 check_passed = isNumberOfParamForGeometryValid(params.size(), type);
164 else
165 check_passed = isNumberOfParamForComplexGeometryValid(params.size(), type,
166 vec_type);
167
168 std::ostringstream oss;
169 if (!check_passed) {
170 oss << "Error: Data maybe invalid. Can not create geometrical object: "
171 << type << " with params: " << util::io::printStr(params)
172 << ", vec type: " << util::io::printStr(vec_type)
173 << ", vec flag: " << util::io::printStr(vec_flag) << std::endl;
174 }
175
176 // issue error
177 if (!check_passed) {
178 if (perform_check || util::methods::isTagInList(type, no_default_obj)) {
179 throw std::invalid_argument(
181 << oss.str());
182 }
183 }
184
185 // create object
186 if (type == "circle") {
187
188 if (check_passed) {
189 // if check is passed
190 obj = std::make_shared<geom::Circle>(
191 params[0], util::Point(params[1], params[2], params[3]));
192 } else {
193 // if check is failed check if we can use other constructor
194 if (params.size() < 1) {
195 // if params are not adequate
196 throw std::invalid_argument(
198 << "Error: need at least " << 1
199 << " parameters for creating circle. "
200 "Number of params provided = "
201 << params.size()
202 << ", params = "
203 << util::io::printStr(params) << " \n");
204 }
205
206 // reached here it means we have adequate parameters
207 obj = std::make_shared<geom::Circle>(params[0],
208 util::Point());
209 } // if else check_failed
210 } // if circle
211 else if (type == "rectangle") {
212
213 if (check_passed) {
214 // if check is passed
215 obj = std::make_shared<geom::Rectangle>(
216 params[0], params[1],
217 util::Point(params[2], params[3], params[4]));
218 } else {
219 // if check is failed check if we can use other constructor
220 if (params.size() != 6 or params.size() != 5) {
221 // if params are not adequate
222 throw std::invalid_argument(
224 << "Error: need either 5 or 6"
225 << " parameters for creating Rectangle. "
226 "Number of params provided = "
227 << params.size()
228 << ", params = "
229 << util::io::printStr(params) << " \n");
230 }
231
232 // reached here it means we have adequate parameters
233 if (params.size() == 6)
234 obj = std::make_shared<geom::Rectangle>(
235 util::Point(params[0], params[1], params[2]),
236 util::Point(params[3], params[4], params[5]));
237 else if (params.size() == 5)
238 obj = std::make_shared<geom::Rectangle>(
239 params[0], params[1],
240 util::Point(params[2], params[3], params[4]));
241 } // if else check_failed
242 } // if rectangle
243 else if (type == "square") {
244
245 if (check_passed) {
246 // if check is passed
247 obj = std::make_shared<geom::Square>(
248 params[0],
249 util::Point(params[2], params[3], params[4]));
250 } else {
251 // if check is failed check if we can use other constructor
252 if (params.size() != 6) {
253 // if params are not adequate
254 throw std::invalid_argument(
256 << "Error: need " << 6
257 << " parameters for creating Square. "
258 "Number of params provided = "
259 << params.size()
260 << ", params = "
261 << util::io::printStr(params) << " \n");
262 }
263
264 // reached here it means we have adequate parameters
265 obj = std::make_shared<geom::Square>(
266 util::Point(params[0], params[1], params[2]),
267 util::Point(params[3], params[4], params[5]));
268 } // if else check_failed
269 } // if square
270 else if (type == "triangle") {
271
272 if (check_passed) {
273 // if check is passed
274 obj = std::make_shared<geom::Triangle>(
275 params[0], util::Point(params[1], params[2], params[3]),
276 util::Point(params[4], params[5], params[6]));
277 } else {
278 // if check is failed check if we can use other constructor
279 if (params.size() != 4) {
280 // if params are not adequate
281 throw std::invalid_argument(
283 << "Error: need at least " << 4
284 << " parameters for creating triangle. "
285 "Number of params provided = "
286 << params.size()
287 << ", params = "
288 << util::io::printStr(params) << " \n");
289 }
290
291 // reached here it means we have adequate parameters
292 obj = std::make_shared<geom::Triangle>(
293 params[0], util::Point(params[1], params[2], params[3]));
294 }// if else check_failed
295 }// if triangle
296 else if (type == "hexagon") {
297
298 if (check_passed) {
299 // if check is passed
300 obj = std::make_shared<geom::Hexagon>(
301 params[0], util::Point(params[1], params[2], params[3]),
302 util::Point(params[4], params[5], params[6]));
303 } else {
304 // if check is failed check if we can use other constructor
305 if (params.size() != 4) {
306 // if params are not adequate
307 throw std::invalid_argument(
309 << "Error: need at least " << 4
310 << " parameters for creating hexagon. "
311 "Number of params provided = "
312 << params.size()
313 << ", params = "
314 << util::io::printStr(params) << " \n");
315 }
316
317 // reached here it means we have adequate parameters
318 obj = std::make_shared<geom::Hexagon>(
319 params[0], util::Point(params[1], params[2], params[3]));
320 }// if else check_failed
321 }// if hexagon
322 else if (type == "drum2d") {
323
324 if (check_passed) {
325 // if check is passed
326 obj = std::make_shared<geom::Drum2D>(
327 params[0], params[1],
328 util::Point(params[2], params[3], params[4]),
329 util::Point(params[5], params[6], params[7]));
330 } else {
331 // if check is failed check if we can use other constructor
332 if (params.size() < 5) {
333 // if params are not adequate
334 throw std::invalid_argument(
336 << "Error: need at least " << 5
337 << " parameters for creating drum2d. "
338 "Number of params provided = "
339 << params.size()
340 << ", params = "
341 << util::io::printStr(params) << " \n");
342 }
343
344 // reached here it means we have adequate parameters
345 obj = std::make_shared<geom::Drum2D>(
346 params[0], params[1],
347 util::Point(params[2], params[3], params[4]));
348 }// if else check_failed
349 }// if drum2d
350 else if (type == "sphere") {
351
352 if (check_passed) {
353 // if check is passed
354 obj = std::make_shared<geom::Sphere>(
355 params[0], util::Point(params[1], params[2], params[3]));
356 } else {
357 // if check is failed check if we can use other constructor
358 if (params.size() < 1) {
359 // if params are not adequate
360 throw std::invalid_argument(
362 << "Error: need at least " << 1
363 << " parameters for creating sphere. "
364 "Number of params provided = "
365 << params.size()
366 << ", params = "
367 << util::io::printStr(params) << " \n");
368 }
369
370 // reached here it means we have adequate parameters
371 obj = std::make_shared<geom::Sphere>(params[0],
372 util::Point());
373 }// if else check_failed
374 }// if sphere
375 else if (type == "ellipse") {
376
377 if (check_passed) {
378 obj = std::make_shared<geom::Ellipse>(
379 params[0], params[1], params[2],
380 util::Point(params[3], params[4], params[5]));
381 } else {
382 throw std::invalid_argument(
384 << "Error: need at least " << 6
385 << " parameters for creating ellipse (a, b, theta, cx, cy, cz). "
386 "Number of params provided = "
387 << params.size()
388 << ", params = "
389 << util::io::printStr(params) << " \n");
390 }
391 } // ellipse
392 else if (type == "ellipsoid") {
393
394 if (check_passed) {
395 if (params.size() == 6) {
396 obj = std::make_shared<geom::Ellipsoid>(
397 params[0], params[1], params[2],
398 util::Point(params[4], params[5], params[6]));
399 } else {
400 obj = std::make_shared<geom::Ellipsoid>(
401 params[0], params[1], params[2], params[3],
402 util::Point(params[4], params[5], params[6]),
403 util::Point(params[7], params[8], params[9]));
404 }
405 } else {
406 throw std::invalid_argument(
408 << "Error: need 6 parameters (cx, cy, cz, r1, r2, r3) or 10 parameters "
409 "(cx, cy, cz, r1, r2, r3, ax, ay, az, theta) for creating ellipsoid. "
410 "Number of params provided = "
411 << params.size()
412 << ", params = "
413 << util::io::printStr(params) << " \n");
414 }
415 } // ellipsoid
416 else if (type == "cuboid") {
417
418 if (check_passed) {
419 // if check is passed
420 obj = std::make_shared<geom::Cuboid>(
421 params[0], params[1], params[2],
422 util::Point(params[3], params[4], params[5]));
423 } else {
424 throw std::invalid_argument(
426 << "Error: need at least " << 6
427 << " parameters for creating cuboid. "
428 "Number of params provided = "
429 << params.size()
430 << ", params = "
431 << util::io::printStr(params) << " \n");
432 }// if else check_failed
433 }// if cuboid
434 else if (type == "cube") {
435
436 if (check_passed) {
437 // if check is passed
438 obj = std::make_shared<geom::Cube>(
439 params[0],
440 util::Point(params[2], params[3], params[4]));
441 } else {
442 // if check is failed check if we can use other constructor
443 if (params.size() < 6) {
444 // if params are not adequate
445 throw std::invalid_argument(
447 << "Error: need " << 6
448 << " parameters for creating Cube. "
449 "Number of params provided = "
450 << params.size()
451 << ", params = "
452 << util::io::printStr(params) << " \n");
453 }
454
455 // reached here it means we have adequate parameters
456 obj = std::make_shared<geom::Cube>(
457 util::Point(params[0], params[1], params[2]),
458 util::Point(params[3], params[4], params[5]));
459 } // if else check_failed
460 } // if cube
461 else if (type == "cylinder") {
462
463 if (check_passed) {
464 // Seven params: r, center of beginning cross-section, vector from beginning to end of cylinder
465 obj = std::make_shared<geom::Cylinder>(
466 params[0], util::Point(params[1], params[2], params[3]),
467 util::Point(params[4], params[5], params[6]));
468 } else {
469 throw std::invalid_argument(
471 << "Error: need at least " << 7
472 << " parameters for creating Cylinder. "
473 "Number of params provided = "
474 << params.size()
475 << ", params = "
476 << util::io::printStr(params) << " \n");
477 }// if else check_failed
478 }// if cylinder
479 else if (type == "rectangle_minus_rectangle") {
480
481 if (check_passed) {
482 // if check is passed
483 auto rin = new geom::Rectangle(
484 util::Point(params[0], params[1],
485 params[2]),
486 util::Point(params[3], params[4], params[5]));
487 auto rout = new geom::Rectangle(
488 util::Point(params[6], params[7],
489 params[8]),
490 util::Point(params[9], params[10],
491 params[11]));
492
493 obj = std::make_shared<geom::AnnulusGeomObject>
494 (rin, rout);
495 } else {
496 throw std::invalid_argument(
498 << "Error: need at least " << 12
499 << " parameters for creating rectangle_minus_rectangle. "
500 "Number of params provided = "
501 << params.size()
502 << ", params = "
503 << util::io::printStr(params) << " \n");
504 }// if else check_failed
505 }// if rectangle_minus_rectangle
506 else if (type == "cuboid_minus_cuboid") {
507
508 if (check_passed) {
509 // if check is passed
510 auto rin = new geom::Cuboid(
511 util::Point(params[0], params[1],
512 params[2]),
513 util::Point(params[3], params[4],
514 params[5]));
515 auto rout = new geom::Cuboid(
516 util::Point(params[6], params[7],
517 params[8]),
518 util::Point(params[9], params[10],
519 params[11]));
520
521 obj = std::make_shared<geom::AnnulusGeomObject>
522 (rin, rout);
523 } else {
524 throw std::invalid_argument(
526 << "Error: need at least " << 12
527 << " parameters for creating cuboid_minus_cuboid. "
528 "Number of params provided = "
529 << params.size()
530 << ", params = "
531 << util::io::printStr(params) << " \n");
532 }// if else check_failed
533 }// if cuboid_minus_cuboid
534 else if (type == "circle_minus_circle") {
535
536 if (check_passed) {
537 const double cx = params[0];
538 const double cy = params[1];
539 const double cz = params[2];
540 const double r_outer = params[3];
541 const double r_inner = params[4];
542 if (r_inner <= 0. || r_outer <= r_inner)
543 throw std::runtime_error(
544 "circle_minus_circle: require 0 < r_inner < r_outer (params: cx,cy,cz,r_outer,r_inner).");
545 auto *cin = new geom::Circle(r_inner, util::Point(cx, cy, cz));
546 auto *cout = new geom::Circle(r_outer, util::Point(cx, cy, cz));
547 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
548 } else {
549 throw std::invalid_argument(
551 << "Error: need " << 5
552 << " parameters for creating circle_minus_circle (cx, cy, cz, r_outer, r_inner). "
553 "Number of params provided = "
554 << params.size()
555 << ", params = "
556 << util::io::printStr(params) << " \n");
557 }
558 } // circle_minus_circle
559 else if (type == "ellipse_minus_ellipse") {
560
561 if (check_passed) {
562 // a_out, b_out, a_in, b_in, theta, cx, cy, cz (concentric, same θ)
563 const double a_out = params[0];
564 const double b_out = params[1];
565 const double a_in = params[2];
566 const double b_in = params[3];
567 const double theta = params[4];
568 const util::Point c(params[5], params[6], params[7]);
569 if (a_in <= 0. || b_in <= 0. || a_out <= a_in || b_out <= b_in)
570 throw std::runtime_error(
571 "ellipse_minus_ellipse: require 0 < a_in < a_out and 0 < b_in < b_out.");
572 auto *ein = new geom::Ellipse(a_in, b_in, theta, c);
573 auto *eout = new geom::Ellipse(a_out, b_out, theta, c);
574 obj = std::make_shared<geom::AnnulusGeomObject>(ein, eout);
575 } else {
576 throw std::invalid_argument(
578 << "Error: need " << 8
579 << " parameters for creating ellipse_minus_ellipse "
580 "(a_out, b_out, a_in, b_in, theta, cx, cy, cz). "
581 "Number of params provided = "
582 << params.size()
583 << ", params = "
584 << util::io::printStr(params) << " \n");
585 }
586 } // ellipse_minus_ellipse
587 else if (type == "sphere_minus_sphere") {
588
589 if (check_passed) {
590 const double cx = params[0];
591 const double cy = params[1];
592 const double cz = params[2];
593 const double r_outer = params[3];
594 const double r_inner = params[4];
595 if (r_inner <= 0. || r_outer <= r_inner)
596 throw std::runtime_error(
597 "sphere_minus_sphere: require 0 < r_inner < r_outer (params: cx,cy,cz,r_outer,r_inner).");
598 auto *cin = new geom::Sphere(r_inner, util::Point(cx, cy, cz));
599 auto *cout = new geom::Sphere(r_outer, util::Point(cx, cy, cz));
600 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
601 } else {
602 throw std::invalid_argument(
604 << "Error: need " << 5
605 << " parameters for creating sphere_minus_sphere (cx, cy, cz, r_outer, r_inner). "
606 "Number of params provided = "
607 << params.size()
608 << ", params = "
609 << util::io::printStr(params) << " \n");
610 }
611 } // sphere_minus_sphere
612 else if (type == "open_rect_channel_2d") {
613
614 if (check_passed) {
615 obj = std::make_shared<geom::OpenRectChannel2D>(
616 params[0], params[1], params[2], params[3], params[4], params[5]);
617 } else {
618 throw std::invalid_argument(
620 << "Error: need " << 6
621 << " parameters for open_rect_channel_2d (x0,y0,x1,y1,t,z). "
622 "Number of params provided = "
623 << params.size()
624 << ", params = "
625 << util::io::printStr(params) << " \n");
626 }
627 } // open_rect_channel_2d
628 else if (type == "open_cuboid_channel_3d") {
629
630 if (check_passed) {
631 obj = std::make_shared<geom::OpenCuboidChannel3D>(
632 params[0], params[1], params[2], params[3], params[4], params[5], params[6],
633 static_cast<int>(params[7]));
634 } else {
635 throw std::invalid_argument(
637 << "Error: need " << 8
638 << " parameters for open_cuboid_channel_3d "
639 "(x0,y0,z0,x1,y1,z1,t,open_face 0..5). "
640 "Number of params provided = "
641 << params.size()
642 << ", params = "
643 << util::io::printStr(params) << " \n");
644 }
645 } // open_cuboid_channel_3d
646 else if (type == "complex") {
647
648 if (check_passed) {
649 // if check is passed
650 std::vector<std::shared_ptr<geom::GeomObject>> vec_obj(
651 vec_type.size());
652
653 size_t param_start = 0;
654 for (size_t i = 0; i < vec_type.size(); i++) {
655 auto geom_type = vec_type[i];
656 auto geom_flag = vec_flag[i];
657 auto num_params = getNumParamsRequired(geom_type)[0];
658
659 // get slice of full param vector
660 auto p1 = params.begin() + param_start;
661 auto p2 = params.begin() + param_start + num_params;
662 auto geom_param = std::vector<double>(p1, p2);
663
664 // create geom object
665 createGeomObject(geom_type, geom_param, std::vector<std::string>(),
666 std::vector<std::string>(), vec_obj[i]);
667
668 param_start += num_params;
669 }
670
671 // create complex geom object
673 obj = std::make_shared<geom::ComplexGeomObject>(vec_obj,
674 vec_flag);
675 //obj->print();
676 } else {
677 throw std::invalid_argument(
679 << "Error: Not enough parameters for creating complex. "
680 "Number of params provided = "
681 << params.size()
682 << ", params = "
683 << util::io::printStr(params) << " \n");
684 }// if else check_failed
685 }// if complex
686 }
687
688 void createGeomObject(const std::string &geom_type,
689 const std::vector<double> &params,
690 const std::vector<std::string> &vec_type,
691 const std::vector<std::string> &vec_flag,
692 std::shared_ptr<geom::GeomObject> &obj,
693 bool perform_check) {
694
695 std::vector<size_t> num_params_needed;
696
697 if (geom_type == "line") {
698
699 num_params_needed = {1, 4, 6};
700
701 for (auto n: num_params_needed) {
702 if (params.size() == n) {
703 if (n == 1) {
704 obj = std::make_shared<geom::Line>(params[0]);
705 return;
706 } else if (n == 4) {
707 obj = std::make_shared<geom::Line>(params[0],
709 params[1],
710 params[2],
711 params[3]));
712
713 return;
714 } else if (n == 6) {
715 obj = std::make_shared<geom::Line>(
716 util::Point(params[0], params[1], params[2]),
717 util::Point(params[3], params[4], params[5]));
718
719 return;
720 }
721 } // if params.size() == n
722 } // loop over n
723 } // Line
724 else if (geom_type == "plane") {
725 if (params.size() == 6) {
726 obj = std::make_shared<geom::Plane>(
727 util::Point(params[0], params[1], params[2]),
728 util::Point(params[3], params[4], params[5]));
729 return;
730 }
731 }
732 else if (geom_type == "triangle") {
733
734 num_params_needed = {1, 4, 7, 9};
735
736 for (auto n: num_params_needed) {
737 if (params.size() == n) {
738 if (n == 1) {
739 obj = std::make_shared<geom::Triangle>(params[0]);
740 return;
741 } else if (n == 4) {
742 obj = std::make_shared<geom::Triangle>(
743 params[0],
744 util::Point(params[1], params[2], params[3]));
745
746 return;
747 } else if (n == 7) {
748 obj = std::make_shared<geom::Triangle>(
749 params[0],
750 util::Point(params[1],params[2],params[3]),
751 util::Point(params[4],params[5],params[6]));
752
753 return;
754 } else if (n == 9) {
755 obj = std::make_shared<geom::Triangle>(
756 util::Point(params[0], params[1], params[2]),
757 util::Point(params[3], params[4], params[5]),
758 util::Point(params[6], params[7], params[8]));
759 return;
760 }
761 } // if params.size() == n
762 } // loop over n
763 } // Triangle
764 else if (geom_type == "square") {
765
766 num_params_needed = {1, 4, 6};
767
768 for (auto n: num_params_needed) {
769 if (params.size() == n) {
770 if (n == 1) {
771 obj = std::make_shared<geom::Square>(params[0]);
772 return;
773 } else if (n == 4) {
774 obj = std::make_shared<geom::Square>(params[0],
776 params[1],
777 params[2],
778 params[3]));
779 return;
780 } else if (n == 6) {
781 obj = std::make_shared<geom::Square>(
782 util::Point(params[0], params[1], params[2]),
783 util::Point(params[3], params[4], params[5]));
784 return;
785 }
786 } // if params.size() == n
787 } // loop over n
788 } // Square
789 else if (geom_type == "rectangle") {
790
791 num_params_needed = {2, 5, 6};
792
793 for (auto n: num_params_needed) {
794 if (params.size() == n) {
795 if (n == 2) {
796 obj = std::make_shared<geom::Rectangle>(params[0],
797 params[1]);
798 return;
799 } else if (n == 5) {
800 obj = std::make_shared<geom::Rectangle>(
801 params[0], params[1],
802 util::Point(params[2], params[3], params[4]));
803 return;
804 } else if (n == 6) {
805 obj = std::make_shared<geom::Rectangle>(
806 util::Point(params[0], params[1], params[2]),
807 util::Point(params[3], params[4], params[5]));
808 return;
809 }
810 } // if params.size() == n
811 } // loop over n
812 } // Rectangle
813 else if (geom_type == "hexagon") {
814
815 num_params_needed = {1, 4, 7};
816
817 for (auto n: num_params_needed) {
818 if (params.size() == n) {
819 if (n == 1) {
820 obj = std::make_shared<geom::Hexagon>(params[0]);
821 return;
822 } else if (n == 4) {
823 // r, cx, cy, cz — same layout as triangle/circle 4-param branches (not params[2..4]).
824 obj = std::make_shared<geom::Hexagon>(
825 params[0], util::Point(params[1], params[2], params[3]));
826 return;
827 } else if (n == 7) {
828 obj = std::make_shared<geom::Hexagon>(
829 params[0],
830 util::Point(params[1], params[2], params[3]),
831 util::Point(params[4], params[5], params[6]));
832 return;
833 }
834 } // if params.size() == n
835 } // loop over n
836 } // Hexagon
837 else if (geom_type == "drum2d") {
838
839 num_params_needed = {2, 5, 8};
840
841 for (auto n: num_params_needed) {
842 if (params.size() == n) {
843 if (n == 2) {
844 obj = std::make_shared<geom::Drum2D>(
845 params[0], params[1]);
846 return;
847 } else if (n == 5) {
848 obj = std::make_shared<geom::Drum2D>(
849 params[0], params[1],
850 util::Point(params[2], params[3], params[4]));
851 return;
852 } else if (n == 8) {
853 obj = std::make_shared<geom::Drum2D>(
854 params[0], params[1],
855 util::Point(params[2], params[3], params[4]),
856 util::Point(params[5], params[6], params[7]));
857 return;
858 }
859 } // if params.size() == n
860 } // loop over n
861 } // Drum2D
862 else if (geom_type == "cube") {
863
864 num_params_needed = {1, 4, 6};
865
866 for (auto n: num_params_needed) {
867 if (params.size() == n) {
868 if (n == 1) {
869 obj = std::make_shared<geom::Cube>(params[0]);
870 return;
871 } else if (n == 4) {
872 obj = std::make_shared<geom::Cube>(
873 params[0],
874 util::Point(params[1], params[2], params[3]));
875 return;
876 } else if (n == 6) {
877 obj = std::make_shared<geom::Cube>(
878 util::Point(params[0], params[1], params[2]),
879 util::Point(params[3], params[4], params[5]));
880 return;
881 }
882 } // if params.size() == n
883 } // loop over n
884 } // Cube
885 else if (geom_type == "cuboid") {
886
887 num_params_needed = {3, 6};
888
889 for (auto n: num_params_needed) {
890 if (params.size() == n) {
891 if (n == 3) {
892 obj = std::make_shared<geom::Cuboid>(
893 params[0], params[1], params[2]);
894 return;
895 } else if (n == 6) {
896 obj = std::make_shared<geom::Cuboid>(
897 util::Point(params[0], params[1], params[2]),
898 util::Point(params[3], params[4], params[5]));
899 return;
900 }
901 } // if params.size() == n
902 } // loop over n
903 } // Cuboid
904 else if (geom_type == "circle") {
905
906 num_params_needed = {1, 4};
907
908 for (auto n: num_params_needed) {
909 if (params.size() == n) {
910 if (n == 1) {
911 obj = std::make_shared<geom::Circle>(params[0]);
912 return;
913 } else if (n == 4) {
914 obj = std::make_shared<geom::Circle>(
915 params[0],
916 util::Point(params[1], params[2], params[3]));
917 return;
918 }
919 } // if params.size() == n
920 } // loop over n
921 } // Circle
922 else if (geom_type == "sphere") {
923
924 num_params_needed = {1, 4};
925
926 for (auto n: num_params_needed) {
927 if (params.size() == n) {
928 if (n == 1) {
929 obj = std::make_shared<geom::Sphere>(params[0]);
930 return;
931 } else if (n == 4) {
932 obj = std::make_shared<geom::Sphere>(
933 params[0],
934 util::Point(params[1], params[2], params[3]));
935 return;
936 }
937 } // if params.size() == n
938 } // loop over n
939 } // Sphere
940 else if (geom_type == "ellipse") {
941
942 num_params_needed = {6};
943
944 for (auto n: num_params_needed) {
945 if (params.size() == n) {
946 if (n == 6) {
947 obj = std::make_shared<geom::Ellipse>(
948 params[0], params[1], params[2],
949 util::Point(params[3], params[4], params[5]));
950 return;
951 }
952 }
953 }
954 } // Ellipse
955 else if (geom_type == "ellipsoid") {
956
957 num_params_needed = {6, 10};
958
959 for (auto n: num_params_needed) {
960 if (params.size() == n) {
961 if (n == 6) {
962 obj = std::make_shared<geom::Ellipsoid>(
963 params[0], params[1], params[2],
964 util::Point(params[3], params[4], params[5]));
965 return;
966 }
967 if (n == 10) {
968 obj = std::make_shared<geom::Ellipsoid>(
969 params[0], params[1], params[2], params[3],
970 util::Point(params[4], params[5], params[6]),
971 util::Point(params[7], params[8], params[9]));
972 return;
973 }
974 }
975 }
976 } // Ellipsoid
977 else if (geom_type == "cylinder") {
978
979 num_params_needed = {7, 8};
980
981 for (auto n: num_params_needed) {
982 if (params.size() == n) {
983 if (n == 7) {
984 // r, center begin, axis vector (no normalization as length of axis is length of cylinder)
985 obj = std::make_shared<geom::Cylinder>(
986 params[0],
987 util::Point(params[1], params[2], params[3]),
988 util::Point(params[4], params[5], params[6]));
989 return;
990 } else if (n == 8) {
991 // r, length, center begin, unit axis vector
992 obj = std::make_shared<geom::Cylinder>(
993 params[0], params[1],
994 util::Point(params[2], params[3], params[4]),
995 util::Point(params[5], params[6], params[7]));
996 return;
997 }
998 } // if params.size() == n
999 } // loop over n
1000 } // Cylinder
1001 else if (geom_type == "angled_rectangle") {
1002
1003 num_params_needed = {6};
1004
1005 for (auto n: num_params_needed) {
1006 if (params.size() == n) {
1007 if (n == 6) {
1008 obj = std::make_shared<geom::Rectangle>(
1009 util::Point(params[0], params[1], params[2]),
1010 util::Point(params[3], params[4], params[5]));
1011
1012 return;
1013 }
1014 } // if params.size() == n
1015 } // loop over n
1016 } // angled_rectangle
1017 else if (geom_type == "angled_cuboid") {
1018
1019 num_params_needed = {6};
1020
1021 for (auto n: num_params_needed) {
1022 if (params.size() == n) {
1023 if (n == 6) {
1024 obj = std::make_shared<geom::Cuboid>(
1025 util::Point(params[0], params[1], params[2]),
1026 util::Point(params[3], params[4], params[5]));
1027
1028 return;
1029 }
1030 } // if params.size() == n
1031 } // loop over n
1032 } // angled_cuboid
1033 else if (geom_type == "rectangle_minus_rectangle") {
1034
1035 num_params_needed = {12};
1036
1037 for (auto n: num_params_needed) {
1038 if (params.size() == n) {
1039 if (n == 12) {
1040
1041 auto rin = new geom::Rectangle(
1042 util::Point(params[0], params[1], params[2]),
1043 util::Point(params[3], params[4], params[5]));
1044 auto rout = new geom::Rectangle(
1045 util::Point(params[6], params[7], params[8]),
1046 util::Point(params[9], params[10], params[11]));
1047
1048 obj = std::make_shared<geom::AnnulusGeomObject>
1049 (rin, rout);
1050
1051 return;
1052 }
1053 } // if params.size() == n
1054 } // loop over n
1055 } // rectangle_minus_rectangle
1056 else if (geom_type == "cuboid_minus_cuboid") {
1057
1058 num_params_needed = {12};
1059
1060 for (auto n: num_params_needed) {
1061 if (params.size() == n) {
1062 if (n == 12) {
1063
1064 auto rin = new geom::Cuboid(
1065 util::Point(params[0], params[1], params[2]),
1066 util::Point(params[3], params[4], params[5]));
1067 auto rout = new geom::Cuboid(
1068 util::Point(params[6], params[7], params[8]),
1069 util::Point(params[9], params[10], params[11]));
1070
1071 obj = std::make_shared<geom::AnnulusGeomObject>
1072 (rin, rout);
1073
1074 return;
1075 }
1076 } // if params.size() == n
1077 } // loop over n
1078 } // cuboid_minus_cuboid
1079 else if (geom_type == "circle_minus_circle") {
1080
1081 num_params_needed = {5};
1082
1083 for (auto n: num_params_needed) {
1084 if (params.size() == n) {
1085 if (n == 5) {
1086 const double cx = params[0];
1087 const double cy = params[1];
1088 const double cz = params[2];
1089 const double r_outer = params[3];
1090 const double r_inner = params[4];
1091 if (r_inner <= 0. || r_outer <= r_inner)
1092 throw std::runtime_error(
1093 "circle_minus_circle: require 0 < r_inner < r_outer (cx,cy,cz,r_outer,r_inner).");
1094 auto *cin = new geom::Circle(r_inner, util::Point(cx, cy, cz));
1095 auto *cout = new geom::Circle(r_outer, util::Point(cx, cy, cz));
1096 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
1097 return;
1098 }
1099 }
1100 }
1101 } // circle_minus_circle
1102 else if (geom_type == "ellipse_minus_ellipse") {
1103
1104 num_params_needed = {8};
1105
1106 for (auto n: num_params_needed) {
1107 if (params.size() == n) {
1108 if (n == 8) {
1109 const double a_out = params[0];
1110 const double b_out = params[1];
1111 const double a_in = params[2];
1112 const double b_in = params[3];
1113 const double theta = params[4];
1114 const util::Point c(params[5], params[6], params[7]);
1115 if (a_in <= 0. || b_in <= 0. || a_out <= a_in || b_out <= b_in)
1116 throw std::runtime_error(
1117 "ellipse_minus_ellipse: require 0 < a_in < a_out and 0 < b_in < b_out.");
1118 auto *ein = new geom::Ellipse(a_in, b_in, theta, c);
1119 auto *eout = new geom::Ellipse(a_out, b_out, theta, c);
1120 obj = std::make_shared<geom::AnnulusGeomObject>(ein, eout);
1121 return;
1122 }
1123 }
1124 }
1125 } // ellipse_minus_ellipse
1126 else if (geom_type == "sphere_minus_sphere") {
1127
1128 num_params_needed = {5};
1129
1130 for (auto n: num_params_needed) {
1131 if (params.size() == n) {
1132 if (n == 5) {
1133 const double cx = params[0];
1134 const double cy = params[1];
1135 const double cz = params[2];
1136 const double r_outer = params[3];
1137 const double r_inner = params[4];
1138 if (r_inner <= 0. || r_outer <= r_inner)
1139 throw std::runtime_error(
1140 "sphere_minus_sphere: require 0 < r_inner < r_outer (cx,cy,cz,r_outer,r_inner).");
1141 auto *cin = new geom::Sphere(r_inner, util::Point(cx, cy, cz));
1142 auto *cout = new geom::Sphere(r_outer, util::Point(cx, cy, cz));
1143 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
1144 return;
1145 }
1146 }
1147 }
1148 } // sphere_minus_sphere
1149 else if (geom_type == "open_rect_channel_2d") {
1150
1151 num_params_needed = {6};
1152
1153 for (auto n: num_params_needed) {
1154 if (params.size() == n) {
1155 if (n == 6) {
1156 obj = std::make_shared<geom::OpenRectChannel2D>(
1157 params[0], params[1], params[2], params[3], params[4], params[5]);
1158 return;
1159 }
1160 }
1161 }
1162 } // open_rect_channel_2d
1163 else if (geom_type == "open_cuboid_channel_3d") {
1164
1165 num_params_needed = {8};
1166
1167 for (auto n: num_params_needed) {
1168 if (params.size() == n) {
1169 if (n == 8) {
1170 const int face = static_cast<int>(params[7]);
1171 if (face < 0 || face > 5)
1172 throw std::runtime_error(
1173 "open_cuboid_channel_3d: open_face must be 0..5 (±x,±y,±z).");
1174 obj = std::make_shared<geom::OpenCuboidChannel3D>(
1175 params[0], params[1], params[2], params[3], params[4], params[5], params[6],
1176 face);
1177 return;
1178 }
1179 }
1180 }
1181 } // open_cuboid_channel_3d
1182 else if (geom_type == "complex") {
1183
1184 /*
1185 std::cout << "vec_type = " << util::io::printStr(vec_type, 0)
1186 << ", vec_flag = " << util::io::printStr(vec_flag, 0)
1187 << "\n";
1188 */
1189
1190 num_params_needed = {0};
1191 std::vector<size_t> params_level(vec_type.size());
1192 for (size_t i = 0; i < vec_type.size(); i++) {
1193
1194 // only consider the biggest parameter set from the list
1195 auto nps = getNumParamsRequired(vec_type[i]);
1196 if (nps.size() > 0)
1197 params_level[i] = nps[nps.size() - 1];
1198 else {
1199 throw std::invalid_argument(
1201 << "Error: Geometry type = " << vec_type[i]
1202 << " has zero number of parameters required. \n");
1203 }
1204
1205 //std::cout << "Geom type = " << vec_type[i]
1206 // << ", params required = " << params_level[i] << "\n";
1207
1208 num_params_needed[0] += params_level[i];
1209 }
1210
1211 std::vector<std::shared_ptr<geom::GeomObject>> objs(vec_type.size());
1212 std::vector<std::string> obj_flags(vec_type.size());
1213
1214 if (params.size() == num_params_needed[0]) {
1215
1216 // loop over objects and create
1217 size_t param_start = 0;
1218 for (size_t i = 0; i < vec_type.size(); i++) {
1219
1220 auto geom_type_temp = vec_type[i];
1221 auto geom_flag_temp = vec_flag[i];
1222
1223 std::vector<std::string> vec_type_temp;
1224 std::vector<std::string> vec_flag_temp;
1225
1226 // find what range of parameters we need to provide
1227 std::vector<double> params_temp;
1228 for (size_t j=0; j<params_level[i]; j++)
1229 params_temp.push_back(params[j + param_start]);
1230
1231 // call this function recursively
1232 obj_flags[i] = vec_flag[i];
1234 geom_type_temp, params_temp, vec_type_temp, vec_flag_temp,
1235 objs[i], perform_check);
1236
1237 param_start += params_level[i];
1238 } // loop over objects
1239
1240 // now create a composite object
1241 obj = std::make_shared<geom::ComplexGeomObject>(objs, obj_flags);
1242
1243 return;
1244 } // if params.size() == n
1245 } // complex
1246 else {
1247 throw std::invalid_argument(
1249 << "Error: Invalid geometry type: " << geom_type << std::endl);
1250 }
1251
1252
1253 throw std::invalid_argument(
1255 << printErrMsg(geom_type, params, num_params_needed));
1256 }
1257
1259 bool perform_check) {
1260
1261 createGeomObject(geomData.d_geomName, geomData.d_geomParams,
1262 geomData.d_geomComplexInfo.first,
1263 geomData.d_geomComplexInfo.second,
1264 geomData.d_geom_p, perform_check);
1265 }
1266
1267 std::vector<double> exampleGeomParams(const std::string &geom_type, const util::Point &c,
1268 double s) {
1269 if (geom_type == "circle")
1270 return {s, c.d_x, c.d_y, c.d_z};
1271 if (geom_type == "plane")
1272 return {0., 1., 0., c.d_x, c.d_y, c.d_z};
1273 if (geom_type == "square")
1274 return {c.d_x - s, c.d_y - s, c.d_z, c.d_x + s, c.d_y + s, c.d_z};
1275 if (geom_type == "rectangle")
1276 return {c.d_x - 1.2 * s, c.d_y - 0.8 * s, c.d_z, c.d_x + 1.2 * s, c.d_y + 0.8 * s, c.d_z};
1277 if (geom_type == "triangle")
1278 return {s, c.d_x, c.d_y, c.d_z, 1.0, 0.0, 0.0};
1279 if (geom_type == "hexagon")
1280 return {s, c.d_x, c.d_y, c.d_z, 1.0, 0.0, 0.0};
1281 if (geom_type == "drum2d") {
1282 const double r = 1.2 * s;
1283 const double w = 0.35 * s;
1284 return {r, w, c.d_x, c.d_y, c.d_z, 1.0, 0.0, 0.0};
1285 }
1286 if (geom_type == "sphere")
1287 return {s, c.d_x, c.d_y, c.d_z};
1288 if (geom_type == "cube")
1289 return {2.0 * s, c.d_x, c.d_y, c.d_z};
1290 if (geom_type == "cuboid")
1291 return {c.d_x - s, c.d_y - 0.75 * s, c.d_z - 0.6 * s, c.d_x + s, c.d_y + 0.75 * s,
1292 c.d_z + 0.6 * s};
1293 if (geom_type == "cylinder")
1294 return {0.5 * s, c.d_x, c.d_y - s, c.d_z, 0., 2. * s, 0.};
1295 if (geom_type == "ellipse")
1296 return {1.2 * s, 0.85 * s, 0.25, c.d_x, c.d_y, c.d_z};
1297 if (geom_type == "ellipsoid")
1298 return {2. * s, 1. * s, 1.5 * s, c.d_x, c.d_y, c.d_z};
1299 if (geom_type == "circle_minus_circle")
1300 return {c.d_x, c.d_y, c.d_z, s, 0.35 * s};
1301 if (geom_type == "ellipse_minus_ellipse")
1302 return {1.2 * s, 0.85 * s, 0.7 * s, 0.5 * s, 0.25, c.d_x, c.d_y, c.d_z};
1303 if (geom_type == "sphere_minus_sphere")
1304 return {c.d_x, c.d_y, c.d_z, s, 0.35 * s};
1305 if (geom_type == "rectangle_minus_rectangle") {
1306 const double ri = 0.35 * s;
1307 const double lo_ix = c.d_x - ri, lo_iy = c.d_y - ri, lo_iz = c.d_z;
1308 const double hi_ix = c.d_x + ri, hi_iy = c.d_y + ri, hi_iz = c.d_z;
1309 const double lo_ox = c.d_x - s, lo_oy = c.d_y - s, lo_oz = c.d_z;
1310 const double hi_ox = c.d_x + s, hi_oy = c.d_y + s, hi_oz = c.d_z;
1311 return {lo_ix, lo_iy, lo_iz, hi_ix, hi_iy, hi_iz, lo_ox, lo_oy, lo_oz, hi_ox, hi_oy, hi_oz};
1312 }
1313 if (geom_type == "cuboid_minus_cuboid") {
1314 const double sx = s, sy = 0.75 * s, sz = 0.6 * s;
1315 const double f = 0.35;
1316 const double lo_ix = c.d_x - f * sx, lo_iy = c.d_y - f * sy, lo_iz = c.d_z - f * sz;
1317 const double hi_ix = c.d_x + f * sx, hi_iy = c.d_y + f * sy, hi_iz = c.d_z + f * sz;
1318 const double lo_ox = c.d_x - sx, lo_oy = c.d_y - sy, lo_oz = c.d_z - sz;
1319 const double hi_ox = c.d_x + sx, hi_oy = c.d_y + sy, hi_oz = c.d_z + sz;
1320 return {lo_ix, lo_iy, lo_iz, hi_ix, hi_iy, hi_iz, lo_ox, lo_oy, lo_oz, hi_ox, hi_oy, hi_oz};
1321 }
1322 if (geom_type == "open_rect_channel_2d") {
1323 const double wall_t = 0.35 * s;
1324 return {c.d_x - s, c.d_y - s, c.d_x + s, c.d_y + s, wall_t, c.d_z};
1325 }
1326 if (geom_type == "open_cuboid_channel_3d") {
1327 const double wall_t = 0.35 * s;
1328 const double open_face = 4.; // +z (matches 2D “open up”)
1329 return {c.d_x - s, c.d_y - s, c.d_z - s, c.d_x + s, c.d_y + s, c.d_z + s, wall_t, open_face};
1330 }
1331 throw std::runtime_error("exampleGeomParams: unknown geometry \"" + geom_type + "\"");
1332 }
1333
1334 std::shared_ptr<GeomObject> makeExampleGeomObject(const std::string &geom_type, const util::Point &c,
1335 double s) {
1336 std::shared_ptr<GeomObject> obj;
1337 createGeomObject(geom_type, exampleGeomParams(geom_type, c, s), {}, {}, obj, false);
1338 return obj;
1339 }
1340
1342 z.d_geomName = d_geomName;
1343 z.d_geomParams = d_geomParams;
1344 z.d_geomComplexInfo = d_geomComplexInfo;
1345
1346 if (d_geom_p->d_name == "null") {
1347 z.d_geom_p =
1348 std::make_shared<geom::NullGeomObject>(
1349 d_geom_p->d_description);
1350 } else if (d_geom_p->d_name.empty()) {
1351 z.d_geom_p =
1352 std::make_shared<geom::GeomObject>(
1353 d_geom_p->d_name, d_geom_p->d_description);
1354 } else {
1356 }
1357 }
1358
1359 void geom::GeomData::copyGeometry(std::string &name,
1360 std::vector<double> &params,
1361 std::pair<std::vector<std::string>, std::vector<std::string>> &complexInfo,
1362 std::shared_ptr<geom::GeomObject> &geom) {
1363 name = d_geomName;
1364 params = d_geomParams;
1365 complexInfo = d_geomComplexInfo;
1366
1367 if (d_geom_p->d_name == "null") {
1368 geom =
1369 std::make_shared<geom::NullGeomObject>(
1370 d_geom_p->d_description);
1371 } else if (d_geom_p->d_name.empty()) {
1372 geom =
1373 std::make_shared<geom::GeomObject>(
1374 d_geom_p->d_name, d_geom_p->d_description);
1375 } else {
1377 params,
1378 complexInfo.first,
1379 complexInfo.second,
1380 geom);
1381 }
1382 }
1383
1384}// Utility functions
1385
1386// read and write geometry from json object
1387namespace geom {
1388
1389 void writeGeometry(json &j, const geom::GeomData &geomData) {
1390 j["Type"] = geomData.d_geomName;
1391
1392 if (geomData.d_geomName == "complex") {
1393 j["Vec_type"] = geomData.d_geomComplexInfo.first;
1394 j["Vec_flag"] = geomData.d_geomComplexInfo.second;
1395 }
1396
1397 j["Parameters"] = geomData.d_geomParams;
1398 }
1399
1400 void readGeometry(const json &j, geom::GeomData &geomData) {
1401
1402 if (j.find("Type") == j.end()) {
1403 throw std::invalid_argument(
1405 << "Error: Geometry type not found in json file.\n");
1406 }
1407 geomData.d_geomName = j.at("Type");
1408
1409 if (geomData.d_geomName == "complex") {
1410 if ((j.find("Vec_type") == j.end()) or (j.find("Vec_flag") == j.end())) {
1411 throw std::invalid_argument(
1413 << "Error: Geometry type and/or flag not found in json file.\n");
1414 }
1415 geomData.d_geomComplexInfo.first = j.at("Vec_type").get<std::vector<std::string>>();
1416 geomData.d_geomComplexInfo.second = j.at("Vec_flag").get<std::vector<std::string>>();
1417 }
1418
1419 if (j.find("Parameters") == j.end()) {
1420 throw std::invalid_argument(
1422 << "Error: Geometry parameters not found in json file.\n");
1423 }
1424
1425 for (auto a: j.at("Parameters"))
1426 geomData.d_geomParams.push_back(a);
1427 }
1428
1430 if (!obj)
1431 return nullptr;
1432
1433 const std::string &type = obj->d_name;
1434 if (type == "null")
1435 return new NullGeomObject(*dynamic_cast<const NullGeomObject *>(obj));
1436 if (type == "plane")
1437 return new Plane(*dynamic_cast<const Plane *>(obj));
1438 if (type == "line")
1439 return new Line(*dynamic_cast<const Line *>(obj));
1440 if (type == "triangle")
1441 return new Triangle(*dynamic_cast<const Triangle *>(obj));
1442 if (type == "square")
1443 return new Square(*dynamic_cast<const Square *>(obj));
1444 if (type == "rectangle")
1445 return new Rectangle(*dynamic_cast<const Rectangle *>(obj));
1446 if (type == "hexagon")
1447 return new Hexagon(*dynamic_cast<const Hexagon *>(obj));
1448 if (type == "drum2d")
1449 return new Drum2D(*dynamic_cast<const Drum2D *>(obj));
1450 if (type == "cube")
1451 return new Cube(*dynamic_cast<const Cube *>(obj));
1452 if (type == "cuboid")
1453 return new Cuboid(*dynamic_cast<const Cuboid *>(obj));
1454 if (type == "circle")
1455 return new Circle(*dynamic_cast<const Circle *>(obj));
1456 if (type == "sphere")
1457 return new Sphere(*dynamic_cast<const Sphere *>(obj));
1458 if (type == "cylinder")
1459 return new Cylinder(*dynamic_cast<const Cylinder *>(obj));
1460 if (type == "ellipse")
1461 return new Ellipse(*dynamic_cast<const Ellipse *>(obj));
1462 if (type == "ellipsoid")
1463 return new Ellipsoid(*dynamic_cast<const Ellipsoid *>(obj));
1464 if (type == "annulus_object")
1465 return new AnnulusGeomObject(*dynamic_cast<const AnnulusGeomObject *>(obj));
1466 if (type == "open_rect_channel_2d")
1467 return new OpenRectChannel2D(*dynamic_cast<const OpenRectChannel2D *>(obj));
1468 if (type == "open_cuboid_channel_3d")
1469 return new OpenCuboidChannel3D(*dynamic_cast<const OpenCuboidChannel3D *>(obj));
1470 if (type == "complex")
1471 return new ComplexGeomObject(*dynamic_cast<const ComplexGeomObject *>(obj));
1472
1473 throw std::invalid_argument(
1475 << "Error: Unsupported object type '" << type << "' in createGeomDeepCopy\n");
1476 }
1477
1478}
Defines annulus rectangle.
Defines circle.
Defines complex geometrical object.
Defines cube.
Defines cuboid.
Defines cylinder.
Defines Drum2D.
Filled ellipse in the plane z = center.d_z, semi-axes in the xy plane.
Ellipsoid: center , semi-axes in a body frame rotated from world by axis–angle (Rodrigues)....
Defines abstract geometrical domain.
const std::string d_name
name of object
Defines Hexagon.
Defines Line.
Defines null (empty) geom object.
Hollow axis-aligned cuboid shell with uniform wall thickness and one outer face open.
2D U-shaped cavity: thick rectangular frame with the top (+y) side open.
Infinite plane: free space is the half-space in the normal direction.
Defines Rectangle.
Defines sphere.
Defines Square.
Defines Triangle.
Collects a message with stream syntax for use in an exception.
Definition io.h:52
std::string str() const
The message built so far.
Definition io.h:67
nlohmann::ordered_json json
std::string printErrMsg(const std::string &geom_type, const std::vector< double > &params, const std::vector< size_t > &num_params_needed)
void createGeomObject(const std::string &geom_type, const std::vector< double > &params, const std::vector< std::string > &vec_type, const std::vector< std::string > &vec_flag, std::shared_ptr< geom::GeomObject > &obj, bool perform_check)
GeomObject * createGeomDeepCopy(GeomObject *obj)
Creates a deep copy of a geometric object.
void readGeometry(const json &j, geom::GeomData &geomData)
bool isNumberOfParamForComplexGeometryValid(size_t n, std::string geom_type, std::vector< std::string > vec_type)
Ascertain if number of parameters are correct for the given geometry.
std::shared_ptr< GeomObject > makeExampleGeomObject(const std::string &geom_type, const util::Point &c, double s)
One-liner: createGeomObject(exampleGeomParams(...)). Prefer this over per-class static factories so a...
void createGeomObjectOld(const std::string &type, const std::vector< double > &params, const std::vector< std::string > &vec_type, const std::vector< std::string > &vec_flag, std::shared_ptr< geom::GeomObject > &obj, bool perform_check)
Create geometrical object from the given data.
bool checkParamForComplexGeometry(size_t n, std::string geom_type, std::vector< std::string > vec_type)
Check parameter data for validity.
void writeGeometry(json &j, const geom::GeomData &geomData)
bool checkParamForGeometry(size_t n, std::string geom_type)
Check parameter data for validity.
std::vector< double > exampleGeomParams(const std::string &geom_type, const util::Point &c, double s)
Canonical parameter vector for examples, mesh generation tests, and demos.
std::vector< size_t > getNumParamsRequired(std::string geom_type)
Get num params required for creation of object.
bool isNumberOfParamForGeometryValid(size_t n, std::string geom_type)
Ascertain if number of parameters are correct for the given geometry.
std::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
Definition io.h:96
bool isInList(const T &i, const std::vector< T > &list)
Find if data is in the list.
Definition vecMethods.h:270
bool isTagInList(const std::string &tag, const std::vector< std::string > &tags)
Returns true if tag is found in the list of tags.
Definition vecMethods.h:284
Input data for geometrical objects.
std::shared_ptr< geom::GeomObject > d_geom_p
Zone geometry.
void copyGeometry(GeomData &z)
Copies the geometry details.
std::vector< double > d_geomParams
Zone parameters.
std::string d_geomName
Zone type.
std::pair< std::vector< std::string >, std::vector< std::string > > d_geomComplexInfo
Zone geometry info if it is a complex type.
A structure to represent 3d vectors.
Definition point.h:30
double d_y
the y coordinate
Definition point.h:36
double d_z
the z coordinate
Definition point.h:39
double d_x
the x coordinate
Definition point.h:33