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