23 plucker_coordinates_abscissa_ =
nullptr;
24 plucker_coordinates_triangle_.resize(3,
nullptr);
25 plucker_products_.resize(3,
nullptr);
36 plucker_coordinates_abscissa_ =
new Plucker(*abscissa.
node(0),
37 *abscissa.
node(1),
true);
38 scale_line_=plucker_coordinates_abscissa_->
scale();
40 plucker_coordinates_triangle_.resize(3);
41 plucker_products_.resize(3);
42 scale_triangle_=std::numeric_limits<double>::max();
43 for(
unsigned int side = 0; side < 3; side++){
47 scale_triangle_ = std::min( scale_triangle_, plucker_coordinates_triangle_[side]->scale());
50 plucker_products_[side] =
new double((*plucker_coordinates_abscissa_)*(*plucker_coordinates_triangle_[side]));
56 if(plucker_coordinates_abscissa_ !=
nullptr)
57 delete plucker_coordinates_abscissa_;
59 for(
unsigned int side = 0; side < RefElement<2>::n_sides; side++){
60 if(plucker_products_[side] !=
nullptr)
61 delete plucker_products_[side];
62 if(plucker_coordinates_triangle_[side] !=
nullptr)
63 delete plucker_coordinates_triangle_[side];
70 for(
unsigned int side = 0; side < RefElement<2>::n_sides; side++)
72 plucker_products_[side] =
nullptr;
73 plucker_coordinates_triangle_[side] =
nullptr;
75 plucker_coordinates_abscissa_ =
nullptr;
81 plucker_coordinates_abscissa_->compute();
82 scale_line_=plucker_coordinates_abscissa_->scale();
87 scale_triangle_=std::numeric_limits<double>::max();
89 for(
unsigned int side = 0; side < RefElement<2>::n_sides; side++){
90 plucker_coordinates_triangle_[side]->compute();
91 scale_triangle_ = std::min( scale_triangle_, plucker_coordinates_triangle_[side]->scale());
93 ASSERT_DBG(plucker_products_[side]).error(
"Undefined plucker product.");
95 *plucker_products_[side] = (*plucker_coordinates_abscissa_)*(*plucker_coordinates_triangle_[side]);
108 int sign = (t < tol ? -2 : (t > 1+tol ? +2 : 0) );
109 if (std::abs(t) <= tol){
113 else if (std::abs(1-t) <= tol){
142 (local[0])(local[1])(local[2]);
146 arma::vec3 local_triangle({local[2],local[1],local[0]});
152 arma::vec3 u = plucker_coordinates_abscissa_->get_u_vector();
157 if(fabs((
double)u[1]) > fabs(max)){ max = u[1]; i = 1;}
158 if(fabs((
double)u[2]) > fabs(max)){ max = u[2]; i = 2;}
161 double isect_coord_i =
167 double t = (-plucker_coordinates_abscissa_->point(0)[i] + isect_coord_i)/max;
169 arma::vec2 local_abscissa = {1-t, t};
188 compute_plucker_products();
197 signed_plucker_product(1),
198 signed_plucker_product(2)};
199 double w_sum = w[0] + w[1] + w[2];
201 unsigned int n_positive = 0;
202 unsigned int n_negative = 0;
203 unsigned int zero_idx_sum =0;
208 double scaled_epsilon =
geometry_epsilon*scale_line_*scale_triangle_*scale_triangle_;
209 if(std::fabs(w_sum) > scaled_epsilon) {
211 for (
unsigned int i=0; i < 3; i++) {
226 for (
unsigned int i=0; i < 3; i++) {
228 if (w[i] > scaled_epsilon || w[i] < -scaled_epsilon) n_negative++;
240 if (n_positive > 0) {
242 compute_plucker(IP, w);
244 unsigned int non_zero_idx=0;
245 if (n_positive == 2) {
249 non_zero_idx = (zero_idx_sum + 1) % 3;
251 else if (n_positive == 1) {
255 non_zero_idx = 3-zero_idx_sum;
283 int sign = check_abscissa_topology(IP);
285 if(std::abs(sign) > 1)
return 0;
293 return compute_final_in_plane(IP12s);
321 arma::vec3 A = plucker_coordinates_abscissa_->point(0);
323 arma::vec3 U = plucker_coordinates_abscissa_->get_u_vector();
327 arma::vec3 V = plucker_coordinates_triangle_[side]->get_u_vector();
345 unsigned int max_index = 0;
346 double maximum = fabs(Det[0]);
347 if(fabs((
double)Det[1]) > maximum){
348 maximum = fabs(Det[1]);
351 if(fabs((
double)Det[2]) > maximum){
352 maximum = fabs(Det[2]);
366 unsigned int i = (max_index+1)%3,
369 double DetX = -K[i]*V[j] + K[j]*V[i];
370 double DetY = -K[i]*U[j] + K[j]*U[i];
372 double s = DetX/Det[max_index];
373 double t = DetY/Det[max_index];
384 if(t >= -tol && t <= 1+tol){
393 arma::vec2 local_abscissa({1-s, s});
414 for(
unsigned int i = 0; i < 3;i++){
416 if(IP12s.size() == 2)
break;
419 if (compute_degenerate(i,IP))
421 uint s = check_abscissa_topology(IP);
430 if(IP12s.size() == 0)
return IP12s.size();
433 if(IP12s.size() == 1){
434 if(std::abs(sign[0]) > 1) IP12s.pop_back();
447 if (sign[0] == sign[1] && std::abs(sign[0]) > 1) {
453 if(IP12s[0].local_bcoords_A()[1] > IP12s[1].local_bcoords_A()[1]){
459 const int ip_sign[] = {-2, +2};
460 for(
unsigned int ip=0; ip<2; ip++) {
462 if (sign[ip] == ip_sign[ip]) {
464 correct_triangle_ip_topology(
double(ip), ip, IP12s);
465 IP12s[ip].set_topology_A(ip, 0);
470 if(IP12s[0].topology_equal(IP12s[1])){
482 ips[0].local_bcoords_B(), ips[1].local_bcoords_B(),
483 ips[0].local_bcoords_A()[1], ips[1].local_bcoords_A()[1], t);
484 arma::vec2 local_abscissa({1 - t, t});
485 ips[ip].set_coordinates(local_abscissa, local_tria);
490 std::pair<unsigned int, unsigned int> zeros =
503 default: ips[ip].set_topology_B(0,2);
514 os <<
"\tPluckerCoordinates Abscissa[0]";
515 if(plucker_coordinates_abscissa_ ==
nullptr){
516 os <<
"NULL" << endl;
518 os << plucker_coordinates_abscissa_;
520 for(
unsigned int i = 0; i < 3;i++){
521 os <<
"\tPluckerCoordinates Triangle[" << i <<
"]";
522 if(plucker_coordinates_triangle_[i] ==
nullptr){
523 os <<
"NULL" << endl;
525 os << plucker_coordinates_triangle_[i];
551 for(
unsigned int side = 0; side < RefElement<2>::n_sides; side++){
560 for(
unsigned int p = 0; p < 3*RefElement<2>::n_sides; p++){
568 for(
unsigned int side = 0; side < 2*RefElement<2>::n_sides; side++)
569 CI12[side].clear_all();
572 for(
unsigned int side = 0; side < 2*RefElement<2>::n_sides; side++){
573 if(plucker_coordinates_[side] !=
nullptr)
574 delete plucker_coordinates_[side];
577 for(
unsigned int p = 0; p < 3*RefElement<2>::n_sides; p++){
578 if(plucker_products_[p] !=
nullptr)
579 delete plucker_products_[p];
586 for(
unsigned int side = 0; side < 2*RefElement<2>::n_sides; side++)
588 plucker_coordinates_[side] =
nullptr;
590 for(
unsigned int p = 0; p < 3*RefElement<2>::n_sides; p++){
591 plucker_products_[p] =
nullptr;
598 for(
unsigned int i = 0; i < RefElement<2>::n_sides; i++){
600 for(
unsigned int j = 0; j < RefElement<2>::n_sides; j++)
601 CI12[i].set_pc_triangle(plucker_coordinates_[3+j], j);
603 CI12[i].set_pc_abscissa(plucker_coordinates_[i]);
606 for(
unsigned int j = 0; j < RefElement<2>::n_sides; j++)
612 for(
unsigned int j = 0; j < RefElement<2>::n_sides; j++)
615 CI12[i].set_plucker_product(get_plucker_product(i,j),j);
631 unsigned int ip_coutner = 0;
634 for(
unsigned int i = 0; i < 2*RefElement<2>::n_sides && ip_coutner < 2; i++){
635 if(!CI12[i].is_computed())
638 if(CI12[i].compute_final(IP12s) == 0)
continue;
640 unsigned int triangle_side = i%3;
644 IPAux22 IP22(IP.switch_objects(), triangle_side);
650 if( IP22.dim_A() == 0 )
657 for(
unsigned int s=0; s < RefElement<2>::n_sides_per_node; s++)
660 if( IP22.dim_B() == 0 )
664 for(
unsigned int s=0; s < RefElement<2>::n_sides_per_node; s++)
667 else if( IP22.dim_B() == 1 )
671 CI12[3 + IP22.idx_B()].set_computed();
674 else if( IP22.dim_B() == 0 )
682 for(
unsigned int s=0; s < RefElement<2>::n_sides_per_node; s++)
687 IP22s.push_back(IP22);
725 for(
unsigned int i = 0; i < RefElement<2>::n_lines; i++){
726 os <<
"\tPluckerCoordinates Triangle A[" << i <<
"]";
727 if(plucker_coordinates_[i] ==
nullptr){
728 os <<
"NULL" << endl;
730 os << plucker_coordinates_[i];
733 for(
unsigned int i = 0; i < RefElement<2>::n_lines; i++){
734 os <<
"\tPluckerCoordinates Triangle B[" << i <<
"]";
736 os <<
"NULL" << endl;
738 os << plucker_coordinates_[RefElement<2>::n_lines + i];
744 os <<
"ComputeIntersection<2,2> Plucker Coordinates Tree:" << endl;
745 print_plucker_coordinates(os);
746 for(
unsigned int i = 0; i < 6;i++){
747 os <<
"ComputeIntersection<1,2>["<< i <<
"] Plucker Coordinates:" << endl;
748 CI12[i].print_plucker_coordinates(os);
758 plucker_coordinates_abscissa_ =
nullptr;
759 plucker_coordinates_tetrahedron.resize(6,
nullptr);
760 plucker_products_.resize(6,
nullptr);
770 plucker_coordinates_abscissa_ =
new Plucker(*abscissa.
node(0), *abscissa.
node(1));
771 plucker_coordinates_tetrahedron.resize(6);
772 plucker_products_.resize(6);
774 for(
unsigned int line = 0; line < RefElement<3>::n_lines; line++){
785 for(
unsigned int side = 0; side < RefElement<3>::n_sides; side++)
786 CI12[side].clear_all();
789 if(plucker_coordinates_abscissa_ !=
nullptr)
790 delete plucker_coordinates_abscissa_;
792 for(
unsigned int line = 0; line < RefElement<3>::n_lines; line++){
793 if(plucker_products_[line] !=
nullptr)
794 delete plucker_products_[line];
795 if(plucker_coordinates_tetrahedron[line] !=
nullptr)
796 delete plucker_coordinates_tetrahedron[line];
803 for(
unsigned int side = 0; side < RefElement<3>::n_lines; side++)
805 plucker_products_[side] =
nullptr;
806 plucker_coordinates_tetrahedron[side] =
nullptr;
808 plucker_coordinates_abscissa_ =
nullptr;
813 for(
unsigned int side = 0; side < RefElement<3>::n_sides; side++){
814 for(
unsigned int line = 0; line < RefElement<3>::n_lines_per_side; line++){
815 CI12[side].set_pc_triangle(plucker_coordinates_tetrahedron[
818 CI12[side].set_plucker_product(
822 CI12[side].set_pc_abscissa(plucker_coordinates_abscissa_);
837 for(
unsigned int face = 0; face < RefElement<3>::n_sides && IP13s.size() < 2; face++){
839 if (CI12[face].is_computed())
continue;
847 sign.push_back(CI12[face].check_abscissa_topology(IP12));
849 IPAux IP13(IP12, face);
851 IP13s.push_back(IP13);
854 if(IP13.
dim_B() == 0)
858 CI12[node_face].set_computed();
860 else if(IP13.
dim_B() == 1)
863 CI12[edge_face].set_computed();
867 if (IP13s.size() == 0)
return IP13s.size();
870 if(IP13s.size() == 1){
871 if(std::abs(sign[0]) > 1) IP13s.pop_back();
879 if (sign[0] == sign[1] && std::abs(sign[0]) > 1) {
885 if(IP13s[0].local_bcoords_A()[1] > IP13s[1].local_bcoords_A()[1]){
891 const int ip_sign[] = {-2, +2};
892 for(
unsigned int ip=0; ip<2; ip++) {
894 if (sign[ip] == ip_sign[ip]) {
896 correct_tetrahedron_ip_topology(
double(ip), ip, IP13s);
897 IP13s[ip].set_topology_A(ip, 0);
902 if(IP13s[0].topology_equal(IP13s[1])){
913 ips[0].local_bcoords_B(), ips[1].local_bcoords_B(),
914 ips[0].local_bcoords_A()[1], ips[1].local_bcoords_A()[1], t);
915 arma::vec2 local_abscissa({1 - t, t});
916 ips[ip].set_coordinates(local_abscissa, local_tetra);
921 unsigned int zeros = 0;
922 unsigned int n_zeros = 0;
923 for(
char i=0; i < 4; i++){
926 zeros = zeros | (1 << i);
940 default: ips[ip].set_topology_B(0,3);
953 os <<
"\tPluckerCoordinates Abscissa[0]";
954 if(plucker_coordinates_abscissa_ ==
nullptr){
955 os <<
"NULL" << endl;
957 os << plucker_coordinates_abscissa_;
960 for(
unsigned int i = 0; i < 6;i++){
961 os <<
"\tPluckerCoordinates Tetrahedron[" << i <<
"]";
962 if(plucker_coordinates_tetrahedron[i] ==
nullptr){
963 os <<
"NULL" << endl;
965 os << plucker_coordinates_tetrahedron[i];
971 os <<
"ComputeIntersection<1,3> Plucker Coordinates Tree:" << endl;
972 print_plucker_coordinates(os);
973 for(
unsigned int i = 0; i < 4;i++){
974 os <<
"ComputeIntersection<1,2>["<< i <<
"] Plucker Coordinates:" << endl;
975 CI12[i].print_plucker_coordinates(os);
986 s3_dim_starts({0, 4, 10, 14}),
987 s2_dim_starts({15, 18, 21}),
988 object_next(22, no_idx),
989 on_faces(_on_faces())
992 plucker_coordinates_triangle_.resize(3,
nullptr);
993 plucker_coordinates_tetrahedron.resize(6,
nullptr);
994 plucker_products_.resize(3*6,
nullptr);
1004 plucker_coordinates_triangle_.resize(3);
1005 plucker_coordinates_tetrahedron.resize(6);
1008 for(
unsigned int i = 0; i < RefElement<3>::n_lines; i++){
1013 for(
unsigned int i = 0; i < RefElement<2>::n_lines;i++){
1022 plucker_products_.resize(np,
nullptr);
1023 for(
unsigned int line = 0; line < np; line++){
1032 for(
unsigned int triangle_side = 0; triangle_side < RefElement<2>::n_sides; triangle_side++)
1033 CI13[triangle_side].clear_all();
1035 for(
unsigned int line = 0; line < RefElement<3>::n_lines; line++)
1036 CI12[line].clear_all();
1040 for(
unsigned int line = 0; line < np; line++){
1041 if(plucker_products_[line] !=
nullptr)
1042 delete plucker_products_[line];
1045 for(
unsigned int i = 0; i < RefElement<3>::n_lines;i++){
1046 if(plucker_coordinates_tetrahedron[i] !=
nullptr)
1047 delete plucker_coordinates_tetrahedron[i];
1049 for(
unsigned int i = 0; i < RefElement<2>::n_sides;i++){
1050 if(plucker_coordinates_triangle_[i] !=
nullptr)
1051 delete plucker_coordinates_triangle_[i];
1060 for(
unsigned int triangle_side = 0; triangle_side < RefElement<2>::n_sides; triangle_side++){
1061 for(
unsigned int line = 0; line < RefElement<3>::n_lines; line++){
1062 CI13[triangle_side].set_plucker_product(
1065 CI12[line].set_plucker_product(
1069 CI13[triangle_side].set_pc_tetrahedron(plucker_coordinates_tetrahedron[line],line);
1070 CI12[line].set_pc_triangle(plucker_coordinates_triangle_[triangle_side],triangle_side);
1072 CI13[triangle_side].set_pc_abscissa(plucker_coordinates_triangle_[triangle_side]);
1073 CI13[triangle_side].init();
1077 for(
unsigned int line = 0; line < RefElement<3>::n_lines; line++)
1078 CI12[line].set_pc_abscissa(plucker_coordinates_tetrahedron[line]);
1086 unsigned int ip = object_next[i_obj];
1087 if (ip == no_idx)
return false;
1089 return IP_next[ip] == i_obj;
1097 if (have_backlink(obj_after_ip)) {
1103 (mesh_->element_accessor(intersection_->component_ele_idx()).idx())
1104 (mesh_->element_accessor(intersection_->bulk_ele_idx()).idx())
1105 (obj_before_ip)(ip_idx)(obj_after_ip);
1106 object_next[obj_before_ip] = ip_idx;
1107 IP_next.push_back( obj_after_ip);
1108 if (object_next[obj_after_ip] == no_idx) {
1109 object_next[obj_after_ip] = ip_idx;
1117 intersection_= &intersection;
1124 std::fill(object_next.begin(), object_next.end(), no_idx);
1127 std::array<bool, 6> edge_touch={
false,
false,
false,
false,
false,
false};
1128 unsigned int object_before_ip, object_after_ip;
1141 for(
unsigned int _i_side = 0; _i_side < RefElement<2>::n_lines; _i_side++) {
1142 unsigned int i_side = cycle_sides[_i_side];
1144 CI13[ i_side ].compute(IP13s);
1146 if (IP13s.size() == 0)
continue;
1147 for(
unsigned int _ip=0; _ip < IP13s.size(); _ip++) {
1151 unsigned int ip = (side_cycle_orientation[_i_side] + _ip) % IP13s.size();
1162 unsigned int tetra_object = s3_dim_starts[IP23.
dim_B()] + IP23.
idx_B();
1163 unsigned int side_object = s2_dim_starts[1] + i_side;
1165 object_before_ip = tetra_object;
1166 object_after_ip = side_object;
1174 object_before_ip = s2_dim_starts[0]+IP23.
idx_A();
1178 if (IP13s.size() == 1 ) {
1179 if (IP23.
dim_B() == 0) {
1182 if (IP23.
dim_A() == 0) {
1183 object_before_ip = tetra_object;
1184 object_after_ip = s2_dim_starts[0]+IP23.
idx_A();
1194 edge_touch[IP23.
idx_B()]=
true;
1195 std::swap(object_before_ip, object_after_ip);
1199 IP23_list.push_back(IP23);
1201 unsigned int ip_idx = IP23_list.size()-1;
1204 set_links(object_before_ip, ip_idx, object_after_ip);
1224 for(
unsigned int tetra_edge = 0; tetra_edge < 6; tetra_edge++) {
1226 CI12[tetra_edge].compute(IP12);
1230 IP12s_.push_back(IP12);
1234 for(
unsigned int tetra_edge = 0; tetra_edge < 6;tetra_edge++) {
1235 if (! processed_edge[tetra_edge]) {
1237 IPAux12 &IP12 = IP12s_[tetra_edge];
1240 int sign = CI12[tetra_edge].check_abscissa_topology(IP12);
1242 if(std::abs(sign) > 1)
continue;
1244 IPAux23 IP23(IP12s_[tetra_edge].switch_objects(), tetra_edge);
1250 if ( edge_dim == 0) {
1251 face_pair = vertex_faces(i_edge);
1254 processed_edge[ie] = 1;
1257 face_pair = edge_faces(i_edge);
1261 IP23_list.push_back(IP23);
1262 unsigned int ip_idx = IP23_list.size()-1;
1264 unsigned int s3_object = s3_dim_starts[edge_dim] + i_edge;
1267 if (IP23.
dim_A() < 2
1268 && (! edge_touch[i_edge])
1269 && object_next[s3_object] != no_idx) {
1271 if ( have_backlink(s3_object) ) {
1272 set_links(s3_object, ip_idx, face_pair[1]);
1274 set_links(face_pair[0], ip_idx, s3_object);
1279 set_links(face_pair[0], ip_idx, face_pair[1]);
1281 if ( have_backlink(s3_object) ) {
1282 object_next[s3_object]=ip_idx;
1292 if (IP23_list.size() == 0)
return;
1298 for(
auto obj : IP_next) {
1300 unsigned int ip = object_next[obj];
1301 if (ip < IP_next.size()) have_predecessor[ip]=1;
1303 unsigned int ip_init=0;
1304 for(
unsigned int i=0; i< IP23_list.size(); i++)
if (! have_predecessor[i]) ip_init=i;
1306 arma::uvec::fixed<RefElement<3>::n_sides> ips_face_counter;
1307 ips_face_counter.zeros();
1310 unsigned int ip=ip_init;
1312 intersection.
points().push_back(IP23_list[ip]);
1317 unsigned int object = IP_next[ip];
1320 ip = object_next[object];
1321 object_next[object]=no_idx;
1322 if ((ip == no_idx))
break;
1325 if ( ! IP23_list[ip].topology_equal(intersection.
points().back()) ) {
1328 intersection.
points().push_back(IP);
1330 ips_face_counter += on_faces[IP.
dim_B()][IP.
idx_B()];
1334 if (intersection.
points().size() == 1)
return;
1336 if (IP23_list[ip_init].topology_equal(intersection.
points().back()) )
1337 intersection.
points().pop_back();
1339 if (intersection.
points().size() > 2){
1340 for(
uint i=0; i< ips_face_counter.n_elem; i++){
1341 if(ips_face_counter(i) >= intersection.
points().size()){
1353 unsigned int ip_ori = (
unsigned int)(IP12s_[i_edge].result());
1359 return { s3_dim_starts[2] + line_faces[1-ip_ori], s3_dim_starts[2] + line_faces[ip_ori] };
1366 std::array<unsigned int, 3> n_ori, sum_idx;
1369 for(
unsigned int ie=0; ie <3; ie++) {
1370 unsigned int edge_ip_ori = (
unsigned int)(IP12s_[ vtx_edges[ie]].result());
1373 edge_ip_ori = (edge_ip_ori +1)%2;
1375 if (edge_ip_ori == 3) edge_ip_ori=2;
1376 n_ori[edge_ip_ori]++;
1377 sum_idx[edge_ip_ori]+=ie;
1384 if ( n_degen == 2 ) {
1388 unsigned int i_edge = 3 - sum_degen;
1389 FacePair pair = edge_faces(vtx_edges[i_edge]);
1392 if (pair[0] == s3_dim_starts[2] + vtx_faces[(i_edge+1)%3])
1393 return { s3_dim_starts[1] + (i_edge+2)%3, s3_dim_starts[1] + (i_edge+1)%3 };
1395 return { s3_dim_starts[1] + (i_edge+1)%3, s3_dim_starts[1] + (i_edge+2)%3 };
1397 }
else if (n_degen == 1) {
1399 unsigned int i_edge = sum_degen;
1400 ASSERT( n_positive + n_negative == 2);
1401 if ( n_positive == 1) {
1404 FacePair pair = edge_faces(vtx_edges[(i_edge+1)%3]);
1408 if (pair[0] == s3_dim_starts[2] + face)
1409 return { s3_dim_starts[2] + face, s3_dim_starts[1] + vtx_edges[i_edge]};
1411 return { s3_dim_starts[1] + vtx_edges[i_edge], s3_dim_starts[2] + face };
1416 ASSERT(n_positive == 0 || n_positive== 2);
1417 return { s3_dim_starts[0]+i_vertex, s3_dim_starts[1] + vtx_edges[i_edge]};
1423 ASSERT( n_positive + n_negative == 3);
1425 if (n_positive == 1) {
1427 return edge_faces(vtx_edges[i_edge]);
1428 }
else if (n_negative == 1) {
1430 return edge_faces(vtx_edges[i_edge]);
1433 ASSERT( n_positive == 0 || n_positive == 3);
1434 return { s3_dim_starts[0]+i_vertex, s3_dim_starts[0]+i_vertex};
1445 arma::uvec::fixed<RefElement<3>::n_sides> v; v.zeros();
1448 for(
uint i=0; i<RefElement<3>::n_nodes; i++)
1449 for(
uint j=0; j<RefElement<3>::n_sides_per_node; j++)
1453 for(
uint i=0; i<RefElement<3>::n_lines; i++)
1454 for(
uint j=0; j<RefElement<3>::n_sides_per_line; j++)
1458 for(
uint i=0; i<RefElement<3>::n_sides; i++)
1459 on_faces[2][i](i) = 1;
1473 for(
unsigned int i = 0; i < 3;i++){
1474 os <<
"\tPluckerCoordinates Triangle[" << i <<
"]";
1475 if(plucker_coordinates_triangle_[i] ==
nullptr){
1476 os <<
"NULL" << endl;
1478 os << plucker_coordinates_triangle_[i];
1481 for(
unsigned int i = 0; i < 6;i++){
1482 os <<
"\tPluckerCoordinates Tetrahedron[" << i <<
"]";
1483 if(plucker_coordinates_tetrahedron[i] ==
nullptr){
1484 os <<
"NULL" << endl;
1486 os << plucker_coordinates_tetrahedron[i];
1492 os <<
"ComputeIntersection<2,3> Plucker Coordinates Tree:" << endl;
1493 print_plucker_coordinates(os);
1494 for(
unsigned int i = 0; i < 6;i++){
1495 os <<
"ComputeIntersection<1,2>["<< i <<
"] Plucker Coordinates:" << endl;
1496 CI12[i].print_plucker_coordinates(os);
1498 for(
unsigned int i = 0; i < 3;i++){
1499 CI13[i].print_plucker_coordinates_tree(os);
unsigned int dim_A() const
Returns dimension of object A.
#define ASSERT_EQ_DBG(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
void set_topology_B(unsigned int idx, unsigned int dim_B)
Sets the topology of object B in Simplex<M>.
std::vector< IntersectionPointAux< dimA, dimB > > i_points_
Vector of internal intersection points.
Plucker coordinates class.
IntersectionResult result() const
Result: 0 - negative sign, 1 - positive sign, 2 - degenerate (zero for all sides), 3 - none.
static BaryPoint line_barycentric_interpolation(BaryPoint first_coords, BaryPoint second_coords, double first_theta, double second_theta, double theta)
Fundamental simplicial intersections.
void set_topology_A(unsigned int idx, unsigned int dim_A)
Sets the topology of object A in Simplex<N>.
unsigned int size() const
Returns number of intersection points.
static const double geometry_epsilon
static std::pair< unsigned int, unsigned int > zeros_positions(const BaryPoint &barycentric, double tolerance=std::numeric_limits< double >::epsilon()*2)
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
const arma::vec::fixed< N+1 > & local_bcoords_A() const
Returns barycentric coordinates in the Simplex<N>.
NodeAccessor< 3 > node(unsigned int ni) const
static unsigned int normal_orientation(unsigned int sid)
unsigned int idx_A() const
Returns the index of Simplex<N>.
unsigned int dim_B() const
Returns dimension of object B.
static LocalPoint bary_to_local(const BaryPoint &bp)
Converts from barycentric to local coordinates.
void set_coordinates(const arma::vec::fixed< N+1 > &lcA, const arma::vec::fixed< M+1 > &lcB)
Setter for coordinates.
static const IdxVector< (InDim >OutDim?InDim+1:dim-InDim) > interact(TInteraction< OutDim, InDim > interaction)
std::vector< IntersectionPointAux< dimA, dimB > > & points()
Returns intersection points by a reference.
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
std::array< unsigned int, Size > IdxVector
std::array< uint, 2 > FacePair
bool topology_equal(const IntersectionPointAux< N, M > &other) const
Returns true, if other intersection point has the same topology.
IntersectionPointAux< M, N > switch_objects() const
Switches the object A and B.
static const double plucker_empty
Auxiliary value for Plucker product. If equal this value, it is supposed not to be set yet...
void set_ips_in_face(unsigned int face_idx)
Internal auxiliary class represents an intersection point of simplex<N> and simplex<M>.
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
unsigned int idx_B() const
void set_result(IntersectionResult result)
Setter orientation flag.
Internal class representing intersection point.
Plucker coordinates representing line given by points A,B.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Internal class representing intersection object.
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.