144 const std::vector<double> ¶ms,
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) {
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"};
162 if (type !=
"complex")
168 std::ostringstream oss;
170 oss <<
"Error: Data maybe invalid. Can not create geometrical object: "
179 throw std::invalid_argument(
186 if (type ==
"circle") {
190 obj = std::make_shared<geom::Circle>(
191 params[0],
util::Point(params[1], params[2], params[3]));
194 if (params.size() < 1) {
196 throw std::invalid_argument(
198 <<
"Error: need at least " << 1
199 <<
" parameters for creating circle. "
200 "Number of params provided = "
207 obj = std::make_shared<geom::Circle>(params[0],
211 else if (type ==
"rectangle") {
215 obj = std::make_shared<geom::Rectangle>(
216 params[0], params[1],
220 if (params.size() != 6 or params.size() != 5) {
222 throw std::invalid_argument(
224 <<
"Error: need either 5 or 6"
225 <<
" parameters for creating Rectangle. "
226 "Number of params provided = "
233 if (params.size() == 6)
234 obj = std::make_shared<geom::Rectangle>(
237 else if (params.size() == 5)
238 obj = std::make_shared<geom::Rectangle>(
239 params[0], params[1],
243 else if (type ==
"square") {
247 obj = std::make_shared<geom::Square>(
252 if (params.size() != 6) {
254 throw std::invalid_argument(
256 <<
"Error: need " << 6
257 <<
" parameters for creating Square. "
258 "Number of params provided = "
265 obj = std::make_shared<geom::Square>(
270 else if (type ==
"triangle") {
274 obj = std::make_shared<geom::Triangle>(
275 params[0],
util::Point(params[1], params[2], params[3]),
279 if (params.size() != 4) {
281 throw std::invalid_argument(
283 <<
"Error: need at least " << 4
284 <<
" parameters for creating triangle. "
285 "Number of params provided = "
292 obj = std::make_shared<geom::Triangle>(
293 params[0],
util::Point(params[1], params[2], params[3]));
296 else if (type ==
"hexagon") {
300 obj = std::make_shared<geom::Hexagon>(
301 params[0],
util::Point(params[1], params[2], params[3]),
305 if (params.size() != 4) {
307 throw std::invalid_argument(
309 <<
"Error: need at least " << 4
310 <<
" parameters for creating hexagon. "
311 "Number of params provided = "
318 obj = std::make_shared<geom::Hexagon>(
319 params[0],
util::Point(params[1], params[2], params[3]));
322 else if (type ==
"drum2d") {
326 obj = std::make_shared<geom::Drum2D>(
327 params[0], params[1],
332 if (params.size() < 5) {
334 throw std::invalid_argument(
336 <<
"Error: need at least " << 5
337 <<
" parameters for creating drum2d. "
338 "Number of params provided = "
345 obj = std::make_shared<geom::Drum2D>(
346 params[0], params[1],
350 else if (type ==
"sphere") {
354 obj = std::make_shared<geom::Sphere>(
355 params[0],
util::Point(params[1], params[2], params[3]));
358 if (params.size() < 1) {
360 throw std::invalid_argument(
362 <<
"Error: need at least " << 1
363 <<
" parameters for creating sphere. "
364 "Number of params provided = "
371 obj = std::make_shared<geom::Sphere>(params[0],
375 else if (type ==
"ellipse") {
378 obj = std::make_shared<geom::Ellipse>(
379 params[0], params[1], params[2],
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 = "
392 else if (type ==
"ellipsoid") {
395 if (params.size() == 6) {
396 obj = std::make_shared<geom::Ellipsoid>(
397 params[0], params[1], params[2],
400 obj = std::make_shared<geom::Ellipsoid>(
401 params[0], params[1], params[2], params[3],
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 = "
416 else if (type ==
"cuboid") {
420 obj = std::make_shared<geom::Cuboid>(
421 params[0], params[1], params[2],
424 throw std::invalid_argument(
426 <<
"Error: need at least " << 6
427 <<
" parameters for creating cuboid. "
428 "Number of params provided = "
434 else if (type ==
"cube") {
438 obj = std::make_shared<geom::Cube>(
443 if (params.size() < 6) {
445 throw std::invalid_argument(
447 <<
"Error: need " << 6
448 <<
" parameters for creating Cube. "
449 "Number of params provided = "
456 obj = std::make_shared<geom::Cube>(
461 else if (type ==
"cylinder") {
465 obj = std::make_shared<geom::Cylinder>(
466 params[0],
util::Point(params[1], params[2], params[3]),
469 throw std::invalid_argument(
471 <<
"Error: need at least " << 7
472 <<
" parameters for creating Cylinder. "
473 "Number of params provided = "
479 else if (type ==
"rectangle_minus_rectangle") {
493 obj = std::make_shared<geom::AnnulusGeomObject>
496 throw std::invalid_argument(
498 <<
"Error: need at least " << 12
499 <<
" parameters for creating rectangle_minus_rectangle. "
500 "Number of params provided = "
506 else if (type ==
"cuboid_minus_cuboid") {
521 obj = std::make_shared<geom::AnnulusGeomObject>
524 throw std::invalid_argument(
526 <<
"Error: need at least " << 12
527 <<
" parameters for creating cuboid_minus_cuboid. "
528 "Number of params provided = "
534 else if (type ==
"circle_minus_circle") {
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).");
547 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
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 = "
559 else if (type ==
"ellipse_minus_ellipse") {
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.");
574 obj = std::make_shared<geom::AnnulusGeomObject>(ein, eout);
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 = "
587 else if (type ==
"sphere_minus_sphere") {
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).");
600 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
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 = "
612 else if (type ==
"open_rect_channel_2d") {
615 obj = std::make_shared<geom::OpenRectChannel2D>(
616 params[0], params[1], params[2], params[3], params[4], params[5]);
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 = "
628 else if (type ==
"open_cuboid_channel_3d") {
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]));
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 = "
646 else if (type ==
"complex") {
650 std::vector<std::shared_ptr<geom::GeomObject>> vec_obj(
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];
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);
666 std::vector<std::string>(), vec_obj[i]);
668 param_start += num_params;
673 obj = std::make_shared<geom::ComplexGeomObject>(vec_obj,
677 throw std::invalid_argument(
679 <<
"Error: Not enough parameters for creating complex. "
680 "Number of params provided = "
689 const std::vector<double> ¶ms,
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) {
695 std::vector<size_t> num_params_needed;
697 if (geom_type ==
"line") {
699 num_params_needed = {1, 4, 6};
701 for (
auto n: num_params_needed) {
702 if (params.size() == n) {
704 obj = std::make_shared<geom::Line>(params[0]);
707 obj = std::make_shared<geom::Line>(params[0],
715 obj = std::make_shared<geom::Line>(
724 else if (geom_type ==
"plane") {
725 if (params.size() == 6) {
726 obj = std::make_shared<geom::Plane>(
732 else if (geom_type ==
"triangle") {
734 num_params_needed = {1, 4, 7, 9};
736 for (
auto n: num_params_needed) {
737 if (params.size() == n) {
739 obj = std::make_shared<geom::Triangle>(params[0]);
742 obj = std::make_shared<geom::Triangle>(
748 obj = std::make_shared<geom::Triangle>(
755 obj = std::make_shared<geom::Triangle>(
764 else if (geom_type ==
"square") {
766 num_params_needed = {1, 4, 6};
768 for (
auto n: num_params_needed) {
769 if (params.size() == n) {
771 obj = std::make_shared<geom::Square>(params[0]);
774 obj = std::make_shared<geom::Square>(params[0],
781 obj = std::make_shared<geom::Square>(
789 else if (geom_type ==
"rectangle") {
791 num_params_needed = {2, 5, 6};
793 for (
auto n: num_params_needed) {
794 if (params.size() == n) {
796 obj = std::make_shared<geom::Rectangle>(params[0],
800 obj = std::make_shared<geom::Rectangle>(
801 params[0], params[1],
805 obj = std::make_shared<geom::Rectangle>(
813 else if (geom_type ==
"hexagon") {
815 num_params_needed = {1, 4, 7};
817 for (
auto n: num_params_needed) {
818 if (params.size() == n) {
820 obj = std::make_shared<geom::Hexagon>(params[0]);
824 obj = std::make_shared<geom::Hexagon>(
825 params[0],
util::Point(params[1], params[2], params[3]));
828 obj = std::make_shared<geom::Hexagon>(
837 else if (geom_type ==
"drum2d") {
839 num_params_needed = {2, 5, 8};
841 for (
auto n: num_params_needed) {
842 if (params.size() == n) {
844 obj = std::make_shared<geom::Drum2D>(
845 params[0], params[1]);
848 obj = std::make_shared<geom::Drum2D>(
849 params[0], params[1],
853 obj = std::make_shared<geom::Drum2D>(
854 params[0], params[1],
862 else if (geom_type ==
"cube") {
864 num_params_needed = {1, 4, 6};
866 for (
auto n: num_params_needed) {
867 if (params.size() == n) {
869 obj = std::make_shared<geom::Cube>(params[0]);
872 obj = std::make_shared<geom::Cube>(
877 obj = std::make_shared<geom::Cube>(
885 else if (geom_type ==
"cuboid") {
887 num_params_needed = {3, 6};
889 for (
auto n: num_params_needed) {
890 if (params.size() == n) {
892 obj = std::make_shared<geom::Cuboid>(
893 params[0], params[1], params[2]);
896 obj = std::make_shared<geom::Cuboid>(
904 else if (geom_type ==
"circle") {
906 num_params_needed = {1, 4};
908 for (
auto n: num_params_needed) {
909 if (params.size() == n) {
911 obj = std::make_shared<geom::Circle>(params[0]);
914 obj = std::make_shared<geom::Circle>(
922 else if (geom_type ==
"sphere") {
924 num_params_needed = {1, 4};
926 for (
auto n: num_params_needed) {
927 if (params.size() == n) {
929 obj = std::make_shared<geom::Sphere>(params[0]);
932 obj = std::make_shared<geom::Sphere>(
940 else if (geom_type ==
"ellipse") {
942 num_params_needed = {6};
944 for (
auto n: num_params_needed) {
945 if (params.size() == n) {
947 obj = std::make_shared<geom::Ellipse>(
948 params[0], params[1], params[2],
955 else if (geom_type ==
"ellipsoid") {
957 num_params_needed = {6, 10};
959 for (
auto n: num_params_needed) {
960 if (params.size() == n) {
962 obj = std::make_shared<geom::Ellipsoid>(
963 params[0], params[1], params[2],
968 obj = std::make_shared<geom::Ellipsoid>(
969 params[0], params[1], params[2], params[3],
977 else if (geom_type ==
"cylinder") {
979 num_params_needed = {7, 8};
981 for (
auto n: num_params_needed) {
982 if (params.size() == n) {
985 obj = std::make_shared<geom::Cylinder>(
992 obj = std::make_shared<geom::Cylinder>(
993 params[0], params[1],
1001 else if (geom_type ==
"angled_rectangle") {
1003 num_params_needed = {6};
1005 for (
auto n: num_params_needed) {
1006 if (params.size() == n) {
1008 obj = std::make_shared<geom::Rectangle>(
1017 else if (geom_type ==
"angled_cuboid") {
1019 num_params_needed = {6};
1021 for (
auto n: num_params_needed) {
1022 if (params.size() == n) {
1024 obj = std::make_shared<geom::Cuboid>(
1033 else if (geom_type ==
"rectangle_minus_rectangle") {
1035 num_params_needed = {12};
1037 for (
auto n: num_params_needed) {
1038 if (params.size() == n) {
1048 obj = std::make_shared<geom::AnnulusGeomObject>
1056 else if (geom_type ==
"cuboid_minus_cuboid") {
1058 num_params_needed = {12};
1060 for (
auto n: num_params_needed) {
1061 if (params.size() == n) {
1071 obj = std::make_shared<geom::AnnulusGeomObject>
1079 else if (geom_type ==
"circle_minus_circle") {
1081 num_params_needed = {5};
1083 for (
auto n: num_params_needed) {
1084 if (params.size() == n) {
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).");
1096 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
1102 else if (geom_type ==
"ellipse_minus_ellipse") {
1104 num_params_needed = {8};
1106 for (
auto n: num_params_needed) {
1107 if (params.size() == n) {
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.");
1120 obj = std::make_shared<geom::AnnulusGeomObject>(ein, eout);
1126 else if (geom_type ==
"sphere_minus_sphere") {
1128 num_params_needed = {5};
1130 for (
auto n: num_params_needed) {
1131 if (params.size() == n) {
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).");
1143 obj = std::make_shared<geom::AnnulusGeomObject>(cin, cout);
1149 else if (geom_type ==
"open_rect_channel_2d") {
1151 num_params_needed = {6};
1153 for (
auto n: num_params_needed) {
1154 if (params.size() == n) {
1156 obj = std::make_shared<geom::OpenRectChannel2D>(
1157 params[0], params[1], params[2], params[3], params[4], params[5]);
1163 else if (geom_type ==
"open_cuboid_channel_3d") {
1165 num_params_needed = {8};
1167 for (
auto n: num_params_needed) {
1168 if (params.size() == n) {
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],
1182 else if (geom_type ==
"complex") {
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++) {
1197 params_level[i] = nps[nps.size() - 1];
1199 throw std::invalid_argument(
1201 <<
"Error: Geometry type = " << vec_type[i]
1202 <<
" has zero number of parameters required. \n");
1208 num_params_needed[0] += params_level[i];
1211 std::vector<std::shared_ptr<geom::GeomObject>> objs(vec_type.size());
1212 std::vector<std::string> obj_flags(vec_type.size());
1214 if (params.size() == num_params_needed[0]) {
1217 size_t param_start = 0;
1218 for (
size_t i = 0; i < vec_type.size(); i++) {
1220 auto geom_type_temp = vec_type[i];
1221 auto geom_flag_temp = vec_flag[i];
1223 std::vector<std::string> vec_type_temp;
1224 std::vector<std::string> vec_flag_temp;
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]);
1232 obj_flags[i] = vec_flag[i];
1234 geom_type_temp, params_temp, vec_type_temp, vec_flag_temp,
1235 objs[i], perform_check);
1237 param_start += params_level[i];
1241 obj = std::make_shared<geom::ComplexGeomObject>(objs, obj_flags);
1247 throw std::invalid_argument(
1249 <<
"Error: Invalid geometry type: " << geom_type << std::endl);
1253 throw std::invalid_argument(
1255 << printErrMsg(geom_type, params, num_params_needed));