107 std::map<std::pair<std::pair<int,int>,std::pair<int,int> >,std::pair<int,int> >
246 const unsigned& nnode1d)
251 (n!=(nnode1d-1)*nnode1d)&&
252 (n!=nnode1d*nnode1d-1)&&
253 (n!=(nnode1d*nnode1d)*(nnode1d-1)+0)&&
254 (n!=(nnode1d*nnode1d)*(nnode1d-1)+nnode1d-1)&&
255 (n!=(nnode1d*nnode1d)*(nnode1d-1)+(nnode1d-1)*nnode1d)&&
256 (n!=(nnode1d*nnode1d)*(nnode1d-1)+nnode1d*nnode1d-1))
258 std::ostringstream error_stream;
259 error_stream <<
"Node " << n
260 <<
" is not a vertex node in a brick element with " 261 << nnode1d <<
" nodes along each edge!";
264 OOMPH_CURRENT_FUNCTION,
265 OOMPH_EXCEPTION_LOCATION);
270 a=n / (nnode1d*nnode1d);
271 b=(n-a*nnode1d*nnode1d)/nnode1d;
272 c=n-a*nnode1d*nnode1d-b*nnode1d;
274 result_vect[0]=2*c/(nnode1d-1)-1;
275 result_vect[1]=2*b/(nnode1d-1)-1;
276 result_vect[2]=2*a/(nnode1d-1)-1;
290 const unsigned& nnode1d)
292 using namespace OcTreeNames;
295 if ((vertex!=
LDB)&&(vertex!=
RDB)&&
296 (vertex!=
LUB)&&(vertex!=
RUB)&&
297 (vertex!=
LDF)&&(vertex!=
RDF)&&
298 (vertex!=
LUF)&&(vertex!=
RUF))
300 std::ostringstream error_stream;
304 OOMPH_CURRENT_FUNCTION,
305 OOMPH_EXCEPTION_LOCATION);
322 return nnode1d*(nnode1d-1);
326 return nnode1d*nnode1d-1;
331 return nnode1d*nnode1d*(nnode1d-1);
336 return (nnode1d*nnode1d+1)*(nnode1d-1);
340 return nnode1d*nnode1d*nnode1d-nnode1d;
344 return nnode1d*nnode1d*nnode1d-1;
349 std::ostringstream error_stream;
350 error_stream <<
"Never get here. vertex: " <<
Direct_string[vertex]
353 OOMPH_CURRENT_FUNCTION,
354 OOMPH_EXCEPTION_LOCATION);
360 std::ostringstream error_stream;
361 error_stream <<
"Never get here. vertex: " <<
Direct_string[vertex]
364 OOMPH_CURRENT_FUNCTION,
365 OOMPH_EXCEPTION_LOCATION);
376 const unsigned& nnode1d)
378 using namespace OcTreeNames;
383 (n!=(nnode1d-1)*nnode1d)&&
384 (n!=nnode1d*nnode1d-1)&&
385 (n!=(nnode1d*nnode1d)*(nnode1d-1)+0)&&
386 (n!=(nnode1d*nnode1d)*(nnode1d-1)+nnode1d-1)&&
387 (n!=(nnode1d*nnode1d)*(nnode1d-1)+(nnode1d-1)*nnode1d)&&
388 (n!=(nnode1d*nnode1d)*(nnode1d-1)+nnode1d*nnode1d-1))
390 std::ostringstream error_stream;
391 error_stream <<
"Node " << n
392 <<
" is not a vertex node in a brick element with " 393 << nnode1d <<
" nodes along each edge!";
396 OOMPH_CURRENT_FUNCTION,
397 OOMPH_EXCEPTION_LOCATION);
401 if (n==0) {
return LDB;}
402 else if (n==nnode1d-1) {
return RDB;}
403 else if (n==nnode1d*(nnode1d-1)) {
return LUB;}
404 else if (n==nnode1d*nnode1d-1) {
return RUB;}
405 else if (n==nnode1d*nnode1d*(nnode1d-1)) {
return LDF;}
406 else if (n==(nnode1d*nnode1d+1)*(nnode1d-1)) {
return RDF;}
407 else if (n==nnode1d*nnode1d*nnode1d-nnode1d) {
return LUF;}
408 else if (n==nnode1d*nnode1d*nnode1d-1) {
return RUF;}
411 std::ostringstream error_stream;
412 error_stream <<
"Never get here. local node number: " << n
413 <<
" is not a vertex node in a brick element with " 414 << nnode1d <<
" nodes along each edge!" 417 OOMPH_CURRENT_FUNCTION,
418 OOMPH_EXCEPTION_LOCATION);
435 const unsigned& nnode1d,
451 for(
unsigned i=0;
i<3;
i++)
453 vect_other_face[
i]=(vect_node1[
i]+vect_node2[
i])/2-vect_face[
i];
456 if((vect_other_face[
i]!=1)&&(vect_other_face[
i]!=-1)&&
457 (vect_other_face[
i]!=0))
460 OOMPH_CURRENT_FUNCTION,
461 OOMPH_EXCEPTION_LOCATION);
479 using namespace OcTreeNames;
484 case R : a=1; b=2; c=0;
break;
485 case U : a=2; b=0; c=1;
break;
486 case F : a=0; b=1; c=2;
break;
489 OOMPH_CURRENT_FUNCTION,
490 OOMPH_EXCEPTION_LOCATION);
521 Sum+=mat1(i,k)*mat2(k,j);
543 sum+=mat(i,k)*vect1[k];
560 using namespace OcTreeNames;
563 if ((new_up!=
L)&&(new_up!=
R)&&
564 (new_up!=
F)&&(new_up!=
B)&&
565 (new_up!=
U)&&(new_up!=
D))
567 std::ostringstream error_stream;
571 OOMPH_CURRENT_FUNCTION,
572 OOMPH_EXCEPTION_LOCATION);
574 if ((new_right!=
L)&&(new_right!=
R)&&
575 (new_right!=
F)&&(new_right!=
B)&&
576 (new_right!=
U)&&(new_right!=
D))
578 std::ostringstream error_stream;
579 error_stream <<
"Wrong new_right: " <<
Direct_string[new_right]
582 OOMPH_CURRENT_FUNCTION,
583 OOMPH_EXCEPTION_LOCATION);
593 vect_new_dir=
rotate(new_up,new_right,vect_dir);
607 using namespace OcTreeNames;
610 if ((new_up!=
L)&&(new_up!=
R)&&
611 (new_up!=
F)&&(new_up!=
B)&&
612 (new_up!=
U)&&(new_up!=
D))
614 std::ostringstream error_stream;
618 OOMPH_CURRENT_FUNCTION,
619 OOMPH_EXCEPTION_LOCATION);
621 if ((new_right!=
L)&&(new_right!=
R)&&
622 (new_right!=
F)&&(new_right!=
B)&&
623 (new_right!=
U)&&(new_right!=
D))
625 std::ostringstream error_stream;
626 error_stream <<
"Wrong new_right: " <<
Direct_string[new_right]
629 OOMPH_CURRENT_FUNCTION,
630 OOMPH_EXCEPTION_LOCATION);
641 int axis1,axis2,angle1,angle2,nrot;
649 case R : angle1=0;
break;
650 case B : angle1=1;
break;
651 case L : angle1=2;
break;
652 case F : angle1=3;
break;
654 std::ostringstream error_stream;
655 error_stream <<
"new_right is " 658 <<
"it should be R, B, L, or F" << std::endl;
660 OOMPH_CURRENT_FUNCTION,
661 OOMPH_EXCEPTION_LOCATION);
686 std::ostringstream error_stream;
687 error_stream <<
"new_right is " 690 <<
"it should be R, B, L, or F" << std::endl;
692 OOMPH_CURRENT_FUNCTION,
693 OOMPH_EXCEPTION_LOCATION);
719 std::ostringstream error_stream;
720 error_stream <<
"new_right is " 723 <<
"it should be D, B, U, or F" << std::endl;
725 OOMPH_CURRENT_FUNCTION,
726 OOMPH_EXCEPTION_LOCATION);
751 std::ostringstream error_stream;
752 error_stream <<
"new_right is " 755 <<
"it should be D, B, U, or F" << std::endl;
757 OOMPH_CURRENT_FUNCTION,
758 OOMPH_EXCEPTION_LOCATION);
783 std::ostringstream error_stream;
784 error_stream <<
"new_right is " 787 <<
"it should be R, L, U, or D" << std::endl;
789 OOMPH_CURRENT_FUNCTION,
790 OOMPH_EXCEPTION_LOCATION);
814 std::ostringstream error_stream;
815 error_stream <<
"new_right is " 818 <<
"it should be R, L, U, or D" << std::endl;
820 OOMPH_CURRENT_FUNCTION,
821 OOMPH_EXCEPTION_LOCATION);
868 using namespace OcTreeNames;
874 std::ostringstream error_stream;
876 <<
"Inconsistent enumeration! \n Tree::OMEGA=" <<
Tree::OMEGA 880 OOMPH_CURRENT_FUNCTION,
881 OOMPH_EXCEPTION_LOCATION);
2041 for(
int i=-1;
i<2;
i++)
2043 for(
int j=-1; j<2; j++)
2045 for(
int k=-1; k<2; k++)
2047 vect[0]=
i; vect[1]=j; vect[2]=k;
2053 num_elem=(
i+1)*9+(j+1)*3+(k+1);
2058 case 6 :elem=
LUB;
break;
2059 case 24 :elem=
RUB;
break;
2060 case 26 :elem=
RUF;
break;
2061 case 8 :elem=
LUF;
break;
2062 case 0 :elem=
LDB;
break;
2063 case 18 :elem=
RDB;
break;
2064 case 20 :elem=
RDF;
break;
2065 case 2 :elem=
LDF;
break;
2066 case 25 :elem=
RU;
break;
2067 case 23 :elem=
RF;
break;
2068 case 19 :elem=
RD;
break;
2069 case 21 :elem=
RB;
break;
2070 case 7 :elem=
LU;
break;
2071 case 5 :elem=
LF;
break;
2072 case 1 :elem=
LD;
break;
2073 case 3 :elem=
LB;
break;
2074 case 17 :elem=
UF;
break;
2075 case 15 :elem=
UB;
break;
2076 case 11 :elem=
DF;
break;
2077 case 9 :elem=
DB;
break;
2078 case 16 :elem=
U;
break;
2079 case 10 :elem=
D;
break;
2080 case 22 :elem=
R;
break;
2081 case 4 :elem=
L;
break;
2082 case 14 :elem=
F;
break;
2083 case 12 :elem=
B;
break;
2084 case 13 :elem=
OMEGA;
break;
2088 <<
"there might be a problem with Vector_to_direction" 2107 for(
int j=0;j<3;j++)
2114 for (
unsigned j = 0; j < 3; j++)
2139 oomph_info <<
"Direction Error !!" << std::endl;
2151 int new_up,new_right;
2158 std::map<std::pair<int,int>, std::set<std::pair<int,int> > >
2162 for (
int vertex=
LDB;vertex<=
RUF;vertex++)
2168 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2169 std::make_pair(new_up,new_right));
2174 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2175 std::make_pair(new_up,new_right));
2180 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2181 std::make_pair(new_up,new_right));
2186 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2187 std::make_pair(new_up,new_right));
2197 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2198 std::make_pair(new_up,new_right));
2203 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2204 std::make_pair(new_up,new_right));
2209 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2210 std::make_pair(new_up,new_right));
2215 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2216 std::make_pair(new_up,new_right));
2224 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2225 std::make_pair(new_up,new_right));
2230 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2231 std::make_pair(new_up,new_right));
2236 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2237 std::make_pair(new_up,new_right));
2242 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2243 std::make_pair(new_up,new_right));
2252 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2253 std::make_pair(new_up,new_right));
2258 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2259 std::make_pair(new_up,new_right));
2264 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2265 std::make_pair(new_up,new_right));
2270 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2271 std::make_pair(new_up,new_right));
2278 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2279 std::make_pair(new_up,new_right));
2284 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2285 std::make_pair(new_up,new_right));
2290 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2291 std::make_pair(new_up,new_right));
2296 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2297 std::make_pair(new_up,new_right));
2307 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2308 std::make_pair(new_up,new_right));
2313 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2314 std::make_pair(new_up,new_right));
2319 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2320 std::make_pair(new_up,new_right));
2325 required_rotation[std::make_pair(vertex,new_vertex)].insert(
2326 std::make_pair(new_up,new_right));
2336 std::map<int,Vector<int> > vertex_in_edge_neighbour;
2341 std::map<int,Vector<int> > other_vertex_on_edge;
2346 std::map<int,Vector<int> > other_vertex_in_edge_neighbour;
2350 vertex_in_edge_neighbour[
LDB].resize(3);
2351 vertex_in_edge_neighbour[
LDB][0]=
LUF;
2352 vertex_in_edge_neighbour[
LDB][1]=
RDF;
2353 vertex_in_edge_neighbour[
LDB][2]=
RUB;
2355 other_vertex_on_edge[
LDB].resize(3);
2356 other_vertex_on_edge[
LDB][0]=
RDB;
2357 other_vertex_on_edge[
LDB][1]=
LUB;
2358 other_vertex_on_edge[
LDB][2]=
LDF;
2360 other_vertex_in_edge_neighbour[
LDB].resize(3);
2361 other_vertex_in_edge_neighbour[
LDB][0]=
RUF;
2362 other_vertex_in_edge_neighbour[
LDB][1]=
RUF;
2363 other_vertex_in_edge_neighbour[
LDB][2]=
RUF;
2368 vertex_in_edge_neighbour[
RDB].resize(3);
2369 vertex_in_edge_neighbour[
RDB][0]=
RUF;
2370 vertex_in_edge_neighbour[
RDB][1]=
LDF;
2371 vertex_in_edge_neighbour[
RDB][2]=
LUB;
2373 other_vertex_on_edge[
RDB].resize(3);
2374 other_vertex_on_edge[
RDB][0]=
LDB;
2375 other_vertex_on_edge[
RDB][1]=
RUB;
2376 other_vertex_on_edge[
RDB][2]=
RDF;
2378 other_vertex_in_edge_neighbour[
RDB].resize(3);
2379 other_vertex_in_edge_neighbour[
RDB][0]=
LUF;
2380 other_vertex_in_edge_neighbour[
RDB][1]=
LUF;
2381 other_vertex_in_edge_neighbour[
RDB][2]=
LUF;
2386 vertex_in_edge_neighbour[
LUB].resize(3);
2387 vertex_in_edge_neighbour[
LUB][0]=
LDF;
2388 vertex_in_edge_neighbour[
LUB][1]=
RUF;
2389 vertex_in_edge_neighbour[
LUB][2]=
RDB;
2391 other_vertex_on_edge[
LUB].resize(3);
2392 other_vertex_on_edge[
LUB][0]=
RUB;
2393 other_vertex_on_edge[
LUB][1]=
LDB;
2394 other_vertex_on_edge[
LUB][2]=
LUF;
2396 other_vertex_in_edge_neighbour[
LUB].resize(3);
2397 other_vertex_in_edge_neighbour[
LUB][0]=
RDF;
2398 other_vertex_in_edge_neighbour[
LUB][1]=
RDF;
2399 other_vertex_in_edge_neighbour[
LUB][2]=
RDF;
2404 vertex_in_edge_neighbour[
RUB].resize(3);
2405 vertex_in_edge_neighbour[
RUB][0]=
RDF;
2406 vertex_in_edge_neighbour[
RUB][1]=
LUF;
2407 vertex_in_edge_neighbour[
RUB][2]=
LDB;
2409 other_vertex_on_edge[
RUB].resize(3);
2410 other_vertex_on_edge[
RUB][0]=
LUB;
2411 other_vertex_on_edge[
RUB][1]=
RDB;
2412 other_vertex_on_edge[
RUB][2]=
RUF;
2414 other_vertex_in_edge_neighbour[
RUB].resize(3);
2415 other_vertex_in_edge_neighbour[
RUB][0]=
LDF;
2416 other_vertex_in_edge_neighbour[
RUB][1]=
LDF;
2417 other_vertex_in_edge_neighbour[
RUB][2]=
LDF;
2422 vertex_in_edge_neighbour[
LDF].resize(3);
2423 vertex_in_edge_neighbour[
LDF][0]=
LUB;
2424 vertex_in_edge_neighbour[
LDF][1]=
RDB;
2425 vertex_in_edge_neighbour[
LDF][2]=
RUF;
2427 other_vertex_on_edge[
LDF].resize(3);
2428 other_vertex_on_edge[
LDF][0]=
RDF;
2429 other_vertex_on_edge[
LDF][1]=
LUF;
2430 other_vertex_on_edge[
LDF][2]=
LDB;
2432 other_vertex_in_edge_neighbour[
LDF].resize(3);
2433 other_vertex_in_edge_neighbour[
LDF][0]=
RUB;
2434 other_vertex_in_edge_neighbour[
LDF][1]=
RUB;
2435 other_vertex_in_edge_neighbour[
LDF][2]=
RUB;
2440 vertex_in_edge_neighbour[
RDF].resize(3);
2441 vertex_in_edge_neighbour[
RDF][0]=
RUB;
2442 vertex_in_edge_neighbour[
RDF][1]=
LDB;
2443 vertex_in_edge_neighbour[
RDF][2]=
LUF;
2445 other_vertex_on_edge[
RDF].resize(3);
2446 other_vertex_on_edge[
RDF][0]=
LDF;
2447 other_vertex_on_edge[
RDF][1]=
RUF;
2448 other_vertex_on_edge[
RDF][2]=
RDB;
2450 other_vertex_in_edge_neighbour[
RDF].resize(3);
2451 other_vertex_in_edge_neighbour[
RDF][0]=
LUB;
2452 other_vertex_in_edge_neighbour[
RDF][1]=
LUB;
2453 other_vertex_in_edge_neighbour[
RDF][2]=
LUB;
2458 vertex_in_edge_neighbour[
LUF].resize(3);
2459 vertex_in_edge_neighbour[
LUF][0]=
LDB;
2460 vertex_in_edge_neighbour[
LUF][1]=
RUB;
2461 vertex_in_edge_neighbour[
LUF][2]=
RDF;
2463 other_vertex_on_edge[
LUF].resize(3);
2464 other_vertex_on_edge[
LUF][0]=
RUF;
2465 other_vertex_on_edge[
LUF][1]=
LDF;
2466 other_vertex_on_edge[
LUF][2]=
LUB;
2468 other_vertex_in_edge_neighbour[
LUF].resize(3);
2469 other_vertex_in_edge_neighbour[
LUF][0]=
RDB;
2470 other_vertex_in_edge_neighbour[
LUF][1]=
RDB;
2471 other_vertex_in_edge_neighbour[
LUF][2]=
RDB;
2476 vertex_in_edge_neighbour[
RUF].resize(3);
2477 vertex_in_edge_neighbour[
RUF][0]=
RDB;
2478 vertex_in_edge_neighbour[
RUF][1]=
LUB;
2479 vertex_in_edge_neighbour[
RUF][2]=
LDF;
2481 other_vertex_on_edge[
RUF].resize(3);
2482 other_vertex_on_edge[
RUF][0]=
LUF;
2483 other_vertex_on_edge[
RUF][1]=
RDF;
2484 other_vertex_on_edge[
RUF][2]=
RUB;
2486 other_vertex_in_edge_neighbour[
RUF].resize(3);
2487 other_vertex_in_edge_neighbour[
RUF][0]=
LDB;
2488 other_vertex_in_edge_neighbour[
RUF][1]=
LDB;
2489 other_vertex_in_edge_neighbour[
RUF][2]=
LDB;
2495 for (
int vertex=
LDB;vertex<=
RUF;vertex++)
2499 for (
unsigned i=0;
i<3;
i++)
2503 int other_vertex=other_vertex_on_edge[vertex][
i];
2508 int unrotated_neigh_vertex=vertex_in_edge_neighbour[vertex][
i];
2513 int unrotated_neigh_other_vertex=
2514 other_vertex_in_edge_neighbour[vertex][
i];
2517 for (
int neigh_vertex=
LDB;neigh_vertex<=
RUF;neigh_vertex++)
2522 std::set<std::pair<int,int> > vertex_rot=
2523 required_rotation[std::make_pair(neigh_vertex,
2524 unrotated_neigh_vertex)];
2529 for (
int neigh_other_vertex=
LDB;neigh_other_vertex<=
RUF;
2530 neigh_other_vertex++)
2535 std::set<std::pair<int,int> > other_vertex_rot=
2536 required_rotation[std::make_pair(neigh_other_vertex,
2537 unrotated_neigh_other_vertex)];
2540 std::set<std::pair<int,int> > common_rotations;
2543 std::set_intersection(vertex_rot.begin(),
2545 other_vertex_rot.begin(),
2546 other_vertex_rot.end(),
2547 inserter(common_rotations,
2548 common_rotations.begin()));
2551 if (common_rotations.size()>0)
2553 for (std::set<std::pair<int,int> >::iterator it=
2554 common_rotations.begin();
2555 it!=common_rotations.end();it++)
2561 std::make_pair(std::make_pair(vertex,neigh_vertex),
2562 std::make_pair(other_vertex,
2563 neigh_other_vertex))].
2568 std::make_pair(std::make_pair(vertex,neigh_vertex),
2569 std::make_pair(other_vertex,
2570 neigh_other_vertex))].
2592 OcTree* edge_neigh_pt)
const 2602 if (edge_neigh_pt==0)
2605 using namespace OcTreeNames;
2631 if (face_neigh_pt!=0)
2633 if(face_neigh_pt==edge_neigh_pt)
2648 if (face_neigh_pt!=0)
2650 if (face_neigh_pt==edge_neigh_pt)
2672 if (face_neigh_pt!=0)
2674 if (face_neigh_pt==edge_neigh_pt)
2689 if (face_neigh_pt!=0)
2691 if (face_neigh_pt==edge_neigh_pt)
2712 if (face_neigh_pt!=0)
2714 if (face_neigh_pt==edge_neigh_pt)
2729 if (face_neigh_pt!=0)
2731 if (face_neigh_pt==edge_neigh_pt)
2752 if (face_neigh_pt!=0)
2754 if (face_neigh_pt==edge_neigh_pt)
2769 if (face_neigh_pt!=0)
2771 if (face_neigh_pt==edge_neigh_pt)
2792 if (face_neigh_pt!=0)
2794 if (face_neigh_pt==edge_neigh_pt)
2809 if (face_neigh_pt!=0)
2811 if (face_neigh_pt==edge_neigh_pt)
2832 if (face_neigh_pt!=0)
2834 if (face_neigh_pt==edge_neigh_pt)
2849 if (face_neigh_pt!=0)
2851 if (face_neigh_pt==edge_neigh_pt)
2871 if (face_neigh_pt!=0)
2873 if (face_neigh_pt==edge_neigh_pt)
2888 if (face_neigh_pt!=0)
2890 if (face_neigh_pt==edge_neigh_pt)
2911 if (face_neigh_pt!=0)
2913 if (face_neigh_pt==edge_neigh_pt)
2929 if (face_neigh_pt!=0)
2931 if (face_neigh_pt==edge_neigh_pt)
2953 if (face_neigh_pt!=0)
2955 if (face_neigh_pt==edge_neigh_pt)
2970 if (face_neigh_pt!=0)
2972 if (face_neigh_pt==edge_neigh_pt)
2992 if (face_neigh_pt!=0)
2994 if (face_neigh_pt==edge_neigh_pt)
3009 if (face_neigh_pt!=0)
3011 if (face_neigh_pt==edge_neigh_pt)
3032 if (face_neigh_pt!=0)
3034 if (face_neigh_pt==edge_neigh_pt)
3050 if (face_neigh_pt!=0)
3052 if (face_neigh_pt==edge_neigh_pt)
3073 if (face_neigh_pt!=0)
3075 if (face_neigh_pt==edge_neigh_pt)
3091 if (face_neigh_pt!=0)
3093 if (face_neigh_pt==edge_neigh_pt)
3105 std::ostringstream error_stream;
3106 error_stream <<
"Never get here! Edge:" <<
Direct_string[edge]
3107 <<
" " << edge << std::endl;
3109 OOMPH_CURRENT_FUNCTION,
3110 OOMPH_EXCEPTION_LOCATION);
3172 int& diff_level)
const 3175 using namespace OcTreeNames;
3178 if ((direction!=
L)&&(direction!=
R)&&
3179 (direction!=
F)&&(direction!=
B)&&
3180 (direction!=
U)&&(direction!=
D))
3182 std::ostringstream error_stream;
3183 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
3186 OOMPH_CURRENT_FUNCTION,
3187 OOMPH_EXCEPTION_LOCATION);
3194 int max_level=
Level;
3208 diff_level,max_level,
3211 OcTree* neighb_pt=return_pt;
3214 for(
unsigned i=0;
i<3;
i++) {translate_s[
i] =
i;}
3227 s_sw[0]=
S_base(0,reflected_dir)+
3230 s_sw[1]=
S_base(1,reflected_dir)+
3233 s_sw[2]=
S_base(2,reflected_dir)+
3236 s_ne[0]=
S_base(0,reflected_dir)+
3237 S_steplo(0,reflected_dir)*pow(2.0,diff_level)+
3238 S_steplo(0,reflected_dir)*s_difflo+
3239 S_stephi(0,reflected_dir)*pow(2.0,diff_level)+
3240 S_stephi(0,reflected_dir)*s_diffhi;
3242 s_ne[1]=
S_base(1,reflected_dir)+
3243 S_steplo(1,reflected_dir)*pow(2.0,diff_level)
3244 +
S_steplo(1,reflected_dir)*s_difflo+
3245 S_stephi(1,reflected_dir)*pow(2.0,diff_level)
3246 +
S_stephi(1,reflected_dir)*s_diffhi;
3248 s_ne[2]=
S_base(2,reflected_dir)+
3249 S_steplo(2,reflected_dir)*pow(2.0,diff_level)
3250 +
S_steplo(2,reflected_dir)*s_difflo+
3251 S_stephi(2,reflected_dir)*pow(2.0,diff_level)
3252 +
S_stephi(2,reflected_dir)*s_diffhi;
3256 int new_dir = direction;
3292 tmp_dir=
rotate(orig_root_pt->
3293 up_equivalent(neighb_pt->
Root_pt),
3295 right_equivalent(neighb_pt->
Root_pt),
3300 tmp_dir=
rotate(orig_root_pt->
3301 up_equivalent(neighb_pt->
Root_pt),
3303 right_equivalent(neighb_pt->
Root_pt),
3308 tmp_dir=
rotate(orig_root_pt->
3309 up_equivalent(neighb_pt->
Root_pt),
3311 right_equivalent(neighb_pt->
Root_pt),
3317 for(
int i=0;
i<3;
i++)
3319 Mat_rot(
i,0)=vect1[
i];
3320 Mat_rot(
i,1)=vect2[
i];
3321 Mat_rot(
i,2)=vect3[
i];
3329 for(
unsigned i=0;
i<3;
i++)
3333 translate_s_new[
i] = 0;
3334 for(
unsigned k=0;k<3;k++)
3336 s_ne_new[
i] += Mat_rot(
i,k)*s_ne[k];
3337 s_sw_new[
i] += Mat_rot(
i,k)*s_sw[k];
3338 translate_s_new[
i] += Mat_rot(
i,k)*translate_s[k];
3346 for(
unsigned i=0;
i<3;
i++)
3349 translate_s[
i] = std::abs(translate_s_new[
i]);
3417 const unsigned& i_root_edge_neighbour,
3418 unsigned& nroot_edge_neighbour,
3423 int& diff_level)
const 3426 using namespace OcTreeNames;
3430 if ((direction!=
LB)&&(direction!=
RB)&&(direction!=
DB)&&(direction!=
UB)&&
3431 (direction!=
LD)&&(direction!=
RD)&&(direction!=
LU)&&(direction!=
RU)&&
3432 (direction!=
LF)&&(direction!=
RF)&&(direction!=
DF)&&(direction!=
UF))
3434 std::ostringstream error_stream;
3435 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
3438 OOMPH_CURRENT_FUNCTION,
3439 OOMPH_EXCEPTION_LOCATION);
3445 int max_level=
Level;
3458 i_root_edge_neighbour,
3459 nroot_edge_neighbour,
3461 diff_level,max_level,
3471 OcTree* neighb_pt=return_pt;
3474 for(
unsigned i=0;
i<3;
i++) {translate_s[
i] =
i;}
3510 int new_dir = direction;
3520 int new_up=orig_root_pt->
3521 up_equivalent(neighb_pt->
Root_pt);
3523 int new_right=orig_root_pt->
3524 right_equivalent(neighb_pt->
Root_pt);
3526 new_dir=
rotate(new_up,new_right,direction);
3574 for(
int i=0;
i<3;
i++)
3576 Mat_rot(
i,0)=vect1[
i];
3577 Mat_rot(
i,1)=vect2[
i];
3578 Mat_rot(
i,2)=vect3[
i];
3585 for(
unsigned i=0;
i<3;
i++)
3589 translate_s_new[
i] = 0;
3590 for(
unsigned k=0;k<3;k++)
3592 s_hi_new[
i] += Mat_rot(
i,k)*s_hi[k];
3593 s_lo_new[
i] += Mat_rot(
i,k)*s_lo[k];
3594 translate_s_new[
i] += Mat_rot(
i,k)*translate_s[k];
3602 for(
unsigned i=0;
i<3;
i++)
3605 translate_s[
i] = std::abs(translate_s_new[
i]);
3653 using namespace OcTreeNames;
3657 if ((direction!=
L)&&(direction!=
R)&&
3658 (direction!=
F)&&(direction!=
B)&&
3659 (direction!=
U)&&(direction!=
D))
3661 std::ostringstream error_stream;
3662 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
3665 OOMPH_CURRENT_FUNCTION,
3666 OOMPH_EXCEPTION_LOCATION);
3691 s_difflo, s_diffhi,diff_level,max_level,
3727 if ((next_el_pt->Son_pt.size()==0)||(next_el_pt->Level>max_level-1))
3729 return_el_pt=next_el_pt;
3744 if (orig_root_pt!=next_el_pt->
Root_pt)
3747 ->up_equivalent(next_el_pt->Root_pt);
3750 ->right_equivalent(next_el_pt->Root_pt);
3752 son_octant=
rotate(my_up,my_right,son_octant);
3755 return_el_pt=
dynamic_cast<OcTree*
>(next_el_pt->Son_pt[son_octant]);
3793 return return_el_pt;
3833 const unsigned& i_root_edge_neighbour,
3834 unsigned& nroot_edge_neighbour,
3841 using namespace OcTreeNames;
3845 if ((direction!=
LB)&&(direction!=
RB)&&(direction!=
DB)&&(direction!=
UB)&&
3846 (direction!=
LD)&&(direction!=
RD)&&(direction!=
LU)&&(direction!=
RU)&&
3847 (direction!=
LF)&&(direction!=
RF)&&(direction!=
DF)&&(direction!=
UF))
3849 std::ostringstream error_stream;
3850 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
3853 OOMPH_CURRENT_FUNCTION,
3854 OOMPH_EXCEPTION_LOCATION);
3860 nroot_edge_neighbour=0;
3884 i_root_edge_neighbour,
3885 nroot_edge_neighbour,
3886 s_diff,diff_level,max_level,
3898 double s_difflo=0.0;
3899 double s_diffhi=0.0;
3900 int diff_level_edge=0;
3905 diff_level_edge,max_level,
3937 if ((next_el_pt->
Son_pt.size()==0)||(next_el_pt->
Level>max_level-1))
3939 return_el_pt=next_el_pt;
3953 if (orig_root_pt!=next_el_pt->
Root_pt)
3956 ->up_equivalent(next_el_pt->
Root_pt);
3959 ->right_equivalent(next_el_pt->
Root_pt);
3961 son_octant=
rotate(my_up,my_right,son_octant);
3964 return_el_pt=
dynamic_cast<OcTree*
>(next_el_pt->
Son_pt[son_octant]);
3989 nroot_edge_neighbour=
3995 unsigned n_neigh=edge_neighbour_pt.size();
3998 return_el_pt=
dynamic_cast<OcTree*
>(
3999 edge_neighbour_pt[i_root_edge_neighbour]);
4007 return return_el_pt;
4031 unsigned long num_nodes=all_nodes_pt.size();
4033 for (
unsigned long i=0;
i<num_nodes;
i++)
4035 all_nodes_pt[
i]->object_pt()->set_number(++count);
4039 std::ofstream neighbours_file;
4040 std::ofstream no_true_edge_file;
4041 std::ofstream neighbours_txt_file;
4043 double max_error_face=0.0;
4045 neighbours_txt_file, max_error_face);
4047 double max_error_edge=0.0;
4050 neighbours_txt_file, max_error_edge);
4057 <<
"\n \n Failed self_test() for OcTree because of faces: Max. error " 4058 << max_error_face << std::endl<< std::endl;
4065 <<
"\n \n Failed self_test() for OcTree because of edges: Max. error " 4066 << max_error_edge << std::endl<< std::endl;
4070 double max_error=max_error_face;
4071 if (max_error_edge>max_error) max_error=max_error_edge;
4079 oomph_info <<
"Passed self_test() for OcTree: Max. error " 4080 << max_error << std::endl;
4100 std::ofstream& neighbours_file,
4101 std::ofstream& neighbours_txt_file,
4104 using namespace OcTreeNames;
4125 unsigned long num_nodes=forest_nodes_pt.size();
4127 for (
unsigned long i=0;
i<num_nodes;
i++)
4138 if (neighbours_file.is_open())
4140 neighbours_file <<
"#---------------------------------" << std::endl;
4141 neighbours_file <<
"#The element itself: " <<
i << std::endl;
4142 neighbours_file <<
"#---------------------------------" << std::endl;
4144 el_pt->
object_pt())->output_corners(neighbours_file,
"BLACK");
4149 for (
int direction=
L;direction<=
F;direction++)
4165 if (neighbours_txt_file.is_open())
4171 <<
" diff_level " << diff_level
4172 <<
". Inside the neighbour the face is " 4177 if (neighbours_file.is_open())
4179 neighbours_file <<
"#---------------------------------" << std::endl;
4180 neighbours_file <<
"#Neighbour element: " <<
Direct_string[direction]
4182 neighbours_file <<
"#---------------------------------" << std::endl;
4185 output_corners(neighbours_file,
Colour[direction]);
4191 if (neighbours_file.is_open())
4193 neighbours_file <<
"ZONE I=2 C=" <<
Colour[direction] << std::endl;
4207 s[0]=
S_base(0,direction);
4208 s[1]=
S_base(1,direction);
4209 s[2]=
S_base(2,direction);
4213 sqrt(pow(x_small[0]-x_large[0],2)+
4214 pow(x_small[1]-x_large[1],2)+
4215 pow(x_small[2]-x_large[2],2));
4217 if (neighbours_txt_file.is_open())
4219 neighbours_txt_file <<
"Error (1) " << error << std::endl;
4222 if (std::fabs(error)>max_error)
4224 max_error=std::fabs(error);
4230 std::ofstream mismatch_file;
4234 mismatch_file.open(
"mismatch.dat");
4235 mismatch_file <<
"ZONE" << std::endl;
4236 mismatch_file<< x_large[0]<<
" "<<x_large[1]<<
" "<<x_large[2]<<
" 2 \n";
4237 mismatch_file<< x_small[0]<<
" "<<x_small[1]<<
" "<<x_small[2]<<
" 3 \n";
4240 if (neighbours_file.is_open())
4242 neighbours_file <<
"#SOUTH WEST: " << std::endl;
4243 neighbours_file << x_large[0] <<
" " 4244 << x_large[1] <<
" " 4245 << x_large[2] <<
" 40 \n";
4265 if (neighbours_file.is_open())
4267 neighbours_file <<
"#NORTH EAST: " << std::endl;
4268 neighbours_file << x_large[0]
4269 <<
" " << x_large[1]
4270 <<
" " << x_large[2]
4276 sqrt(pow(x_small[0]-x_large[0],2)+
4277 pow(x_small[1]-x_large[1],2)+
4278 pow(x_small[2]-x_large[2],2));
4279 if (neighbours_txt_file.is_open())
4281 neighbours_txt_file <<
"Error (2) " << error << std::endl;
4284 if (std::fabs(error)>max_error)
4286 max_error=std::fabs(error);
4294 if (!mismatch_file.is_open())
4296 mismatch_file.open(
"mismatch.dat");
4298 mismatch_file <<
"ZONE" << std::endl;
4299 mismatch_file << x_large[0] <<
" " << x_large[1] <<
" " 4300 << x_large[2] <<
" 2 \n";
4301 mismatch_file << x_small[0] <<
" " << x_small[1] <<
" " 4302 << x_small[2] <<
" 3 \n";
4303 mismatch_file.close();
4305 <<
" with element "<<
i+1<< std::endl;
4314 if (neighbours_file.is_open())
4317 neighbours_file <<
"#---------------------------------" << std::endl;
4318 neighbours_file <<
"#no Neighbour in direct: " 4321 neighbours_file <<
"#---------------------------------" << std::endl;
4324 el_pt->
object_pt())->output_corners(neighbours_file,
"WHITE");
4325 neighbours_file <<
"ZONE I=2 \n";
4326 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4327 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4331 if (neighbours_file.is_open())
4333 neighbours_file << std::endl << std::endl << std::endl;
4357 std::ofstream& neighbours_file,
4358 std::ofstream& no_true_edge_file,
4359 std::ofstream& neighbours_txt_file,
4362 using namespace OcTreeNames;
4383 unsigned long num_nodes=forest_nodes_pt.size();
4385 for (
unsigned long i=0;
i<num_nodes;
i++)
4395 if (neighbours_file.is_open())
4397 neighbours_file <<
"#---------------------------------" << std::endl;
4398 neighbours_file <<
"#The element itself: " <<
i << std::endl;
4399 neighbours_file <<
"#---------------------------------" << std::endl;
4401 el_pt->
object_pt())->output_corners(neighbours_file,
"BLACK");
4406 for (
int direction=
LB;direction<=
UF;direction++)
4412 unsigned i_root_edge_neighbour=0;
4413 unsigned nroot_edge_neighbour=0;
4417 i_root_edge_neighbour,
4418 nroot_edge_neighbour,
4428 if (neighbours_txt_file.is_open())
4434 <<
" diff_level " << diff_level
4435 <<
". Inside the neighbour the edge is " 4440 if (neighbours_file.is_open())
4442 neighbours_file <<
"#---------------------------------" << std::endl;
4443 neighbours_file <<
"#Neighbour element: " <<
Direct_string[direction]
4445 neighbours_file <<
"#---------------------------------" << std::endl;
4448 output_corners(neighbours_file,
Colour[direction]);
4454 if (neighbours_file.is_open())
4456 neighbours_file <<
"ZONE I=2 C=" <<
Colour[direction] << std::endl;
4476 sqrt(pow(x_small[0]-x_large[0],2)+
4477 pow(x_small[1]-x_large[1],2)+
4478 pow(x_small[2]-x_large[2],2));
4480 if (neighbours_txt_file.is_open())
4482 neighbours_txt_file <<
"Error (1) " << error << std::endl;
4485 if (std::fabs(error)>max_error)
4487 max_error=std::fabs(error);
4493 std::ofstream mismatch_file;
4497 mismatch_file.open(
"mismatch.dat");
4498 mismatch_file <<
"ZONE" << std::endl;
4499 mismatch_file<< x_large[0]<<
" "<<x_large[1]<<
" "<<x_large[2]<<
" 2 \n";
4500 mismatch_file<< x_small[0]<<
" "<<x_small[1]<<
" "<<x_small[2]<<
" 3 \n";
4503 if (neighbours_file.is_open())
4505 neighbours_file <<
"#LOW VERTEX: " << std::endl;
4506 neighbours_file << x_large[0] <<
" " 4507 << x_large[1] <<
" " 4508 << x_large[2] <<
" 40 \n";
4528 if (neighbours_file.is_open())
4530 neighbours_file <<
"#HI VERTEX: " << std::endl;
4531 neighbours_file << x_large[0]
4532 <<
" " << x_large[1]
4533 <<
" " << x_large[2]
4539 sqrt(pow(x_small[0]-x_large[0],2)+
4540 pow(x_small[1]-x_large[1],2)+
4541 pow(x_small[2]-x_large[2],2));
4543 if (neighbours_txt_file.is_open())
4545 neighbours_txt_file <<
"Error (2) " << error << std::endl;
4548 if (std::fabs(error)>max_error)
4550 max_error=std::fabs(error);
4558 if (!mismatch_file.is_open())
4560 mismatch_file.open(
"mismatch.dat");
4562 mismatch_file <<
"ZONE" << std::endl;
4563 mismatch_file << x_large[0] <<
" " << x_large[1] <<
" " 4564 << x_large[2] <<
" 2 \n";
4565 mismatch_file << x_small[0] <<
" " << x_small[1] <<
" " 4566 << x_small[2] <<
" 3 \n";
4567 mismatch_file.close();
4569 <<
" with element "<<
i+1<< std::endl;
4578 if (neighbours_file.is_open())
4581 neighbours_file <<
"#---------------------------------" << std::endl;
4582 neighbours_file <<
"#no Neighbour in direct: " 4585 neighbours_file <<
"#---------------------------------" << std::endl;
4588 el_pt->
object_pt())->output_corners(neighbours_file,
"WHITE");
4589 neighbours_file <<
"ZONE I=2 \n";
4590 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4591 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4613 no_true_edge_file <<
"ZONE I=2" << std::endl;
4614 no_true_edge_file << x_start[0] <<
" " 4615 << x_start[1] <<
" " 4616 << x_start[2] <<
" " 4618 no_true_edge_file << x_end[0] <<
" " 4626 if (neighbours_file.is_open())
4628 neighbours_file << std::endl << std::endl << std::endl;
4662 if (trees_pt.size()==0)
4667 using namespace OcTreeNames;
4696 using namespace OcTreeNames ;
4697 unsigned numtrees=
ntree();
4701 n=
Trees_pt[0]->object_pt()->nnode_1d();
4706 "Trying to setup the neighbour scheme for an empty forest",
4707 OOMPH_CURRENT_FUNCTION,
4708 OOMPH_EXCEPTION_LOCATION);
4713 unsigned n_vertex_node=8;
4717 std::map<Node*,std::set<unsigned> > tree_assoc_with_vertex_node;
4720 for(
unsigned i=0;
i<numtrees;
i++)
4723 for (
unsigned j=0;j<n_vertex_node;j++)
4727 tree_assoc_with_vertex_node[nod_pt].insert(
i);
4737 for (std::map<
Node*,std::set<unsigned> >::iterator it=
4738 tree_assoc_with_vertex_node.begin();
4739 it!=tree_assoc_with_vertex_node.end();it++)
4742 for (std::set<unsigned>::iterator it_el1=it->second.begin();
4743 it_el1!=it->second.end();it_el1++)
4745 unsigned i=(*it_el1);
4746 for (std::set<unsigned>::iterator it_el2=it->second.begin();
4747 it_el2!=it->second.end();it_el2++)
4749 unsigned j=(*it_el2);
4753 potentially_neighb_tree[
i].insert(j);
4761 for(
unsigned i=0;
i<numtrees;
i++)
4768 for(std::set<unsigned>::iterator it=potentially_neighb_tree[
i].begin();
4769 it!=potentially_neighb_tree[
i].end();it++)
4775 bool is_face_neighbour=
false;
4778 bool is_Up_neighbour=
4779 ((
Trees_pt[j]->object_pt()->get_node_number(
4780 Trees_pt[
i]->object_pt()->node_pt(n*(n*n-1)))!=-1) &&
4781 (
Trees_pt[j]->object_pt()->get_node_number(
4782 Trees_pt[
i]->object_pt()->node_pt(n*n-1))!=-1));
4785 bool is_Down_neighbour=
4786 ((
Trees_pt[j]->object_pt()->get_node_number(
4787 Trees_pt[
i]->object_pt()->node_pt(n*n*(n-1)))!=-1) &&
4788 (
Trees_pt[j]->object_pt()->get_node_number(
4789 Trees_pt[
i]->object_pt()->node_pt(n-1))!=-1));
4792 bool is_Right_neighbour=
4793 ((
Trees_pt[j]->object_pt()->get_node_number(
4794 Trees_pt[
i]->object_pt()->node_pt(n*n*n-1))!=-1) &&
4795 (
Trees_pt[j]->object_pt()->get_node_number(
4796 Trees_pt[
i]->object_pt()->node_pt(n-1))!=-1));
4799 bool is_Left_neighbour=
4800 ((
Trees_pt[j]->object_pt()->get_node_number(
4801 Trees_pt[
i]->object_pt()->node_pt(n*(n*n-1)))!=-1) &&
4802 (
Trees_pt[j]->object_pt()->get_node_number(
4803 Trees_pt[
i]->object_pt()->node_pt(0))!=-1));
4806 bool is_Back_neighbour=
4807 ((
Trees_pt[j]->object_pt()->get_node_number(
4808 Trees_pt[
i]->object_pt()->node_pt(n*n-1))!=-1) &&
4809 (
Trees_pt[j]->object_pt()->get_node_number(
4810 Trees_pt[
i]->object_pt()->node_pt(0))!=-1));
4813 bool is_Front_neighbour=
4814 ((
Trees_pt[j]->object_pt()->get_node_number(
4815 Trees_pt[
i]->object_pt()->node_pt(n*n*n-1))!=-1) &&
4816 (
Trees_pt[j]->object_pt()->get_node_number(
4817 Trees_pt[
i]->object_pt()->node_pt(n*n*(n-1)))!=-1));
4820 if(is_Down_neighbour)
4822 is_face_neighbour=
true;
4827 is_face_neighbour=
true;
4830 if(is_Right_neighbour)
4832 is_face_neighbour=
true;
4835 if(is_Left_neighbour)
4837 is_face_neighbour=
true;
4840 if(is_Back_neighbour)
4842 is_face_neighbour=
true;
4845 if(is_Front_neighbour)
4847 is_face_neighbour=
true;
4857 if (!is_face_neighbour)
4861 bool is_left_back_neighbour=
4862 ((
Trees_pt[j]->object_pt()->get_node_number(
4863 Trees_pt[
i]->object_pt()->node_pt(0))!=-1) &&
4864 (
Trees_pt[j]->object_pt()->get_node_number(
4865 Trees_pt[
i]->object_pt()->node_pt(n*(n-1)))!=-1));
4868 bool is_right_back_neighbour=
4869 ((
Trees_pt[j]->object_pt()->get_node_number(
4870 Trees_pt[
i]->object_pt()->node_pt(n-1))!=-1) &&
4871 (
Trees_pt[j]->object_pt()->get_node_number(
4872 Trees_pt[
i]->object_pt()->node_pt(n*n-1))!=-1));
4876 bool is_down_back_neighbour=
4877 ((
Trees_pt[j]->object_pt()->get_node_number(
4878 Trees_pt[
i]->object_pt()->node_pt(n-1))!=-1) &&
4879 (
Trees_pt[j]->object_pt()->get_node_number(
4880 Trees_pt[
i]->object_pt()->node_pt(0))!=-1));
4883 bool is_up_back_neighbour=
4884 ((
Trees_pt[j]->object_pt()->get_node_number(
4885 Trees_pt[
i]->object_pt()->node_pt(n*(n-1)))!=-1) &&
4886 (
Trees_pt[j]->object_pt()->get_node_number(
4887 Trees_pt[
i]->object_pt()->node_pt(n*n-1))!=-1));
4891 bool is_left_down_neighbour=
4892 ((
Trees_pt[j]->object_pt()->get_node_number(
4893 Trees_pt[
i]->object_pt()->node_pt(n*n*(n-1)))!=-1) &&
4894 (
Trees_pt[j]->object_pt()->get_node_number(
4895 Trees_pt[
i]->object_pt()->node_pt(0))!=-1));
4899 bool is_right_down_neighbour=
4900 ((
Trees_pt[j]->object_pt()->get_node_number(
4901 Trees_pt[
i]->object_pt()->node_pt((n*n+1)*(n-1)))!=-1) &&
4902 (
Trees_pt[j]->object_pt()->get_node_number(
4903 Trees_pt[
i]->object_pt()->node_pt(n-1))!=-1));
4907 bool is_left_up_neighbour=
4908 ((
Trees_pt[j]->object_pt()->get_node_number(
4909 Trees_pt[
i]->object_pt()->node_pt((n*n*n-n)))!=-1) &&
4910 (
Trees_pt[j]->object_pt()->get_node_number(
4911 Trees_pt[
i]->object_pt()->node_pt(n*(n-1)))!=-1));
4915 bool is_right_up_neighbour=
4916 ((
Trees_pt[j]->object_pt()->get_node_number(
4917 Trees_pt[
i]->object_pt()->node_pt((n*n*n-1)))!=-1) &&
4918 (
Trees_pt[j]->object_pt()->get_node_number(
4919 Trees_pt[
i]->object_pt()->node_pt(n*n-1))!=-1));
4923 bool is_left_front_neighbour=
4924 ((
Trees_pt[j]->object_pt()->get_node_number(
4925 Trees_pt[
i]->object_pt()->node_pt((n*n*n-n)))!=-1) &&
4926 (
Trees_pt[j]->object_pt()->get_node_number(
4927 Trees_pt[
i]->object_pt()->node_pt(n*n*(n-1)))!=-1));
4931 bool is_right_front_neighbour=
4932 ((
Trees_pt[j]->object_pt()->get_node_number(
4933 Trees_pt[
i]->object_pt()->node_pt((n*n*n-1)))!=-1) &&
4934 (
Trees_pt[j]->object_pt()->get_node_number(
4935 Trees_pt[
i]->object_pt()->node_pt((n*n+1)*(n-1)))!=-1));
4939 bool is_down_front_neighbour=
4940 ((
Trees_pt[j]->object_pt()->get_node_number(
4941 Trees_pt[
i]->object_pt()->node_pt(n*n*(n-1)))!=-1) &&
4942 (
Trees_pt[j]->object_pt()->get_node_number(
4943 Trees_pt[
i]->object_pt()->node_pt((n*n+1)*(n-1)))!=-1));
4947 bool is_up_front_neighbour=
4948 ((
Trees_pt[j]->object_pt()->get_node_number(
4949 Trees_pt[
i]->object_pt()->node_pt((n*n*n-n)))!=-1) &&
4950 (
Trees_pt[j]->object_pt()->get_node_number(
4951 Trees_pt[
i]->object_pt()->node_pt((n*n*n-1)))!=-1));
4957 if(is_left_back_neighbour)
4962 if(is_right_back_neighbour)
4967 if(is_down_back_neighbour)
4972 if(is_up_back_neighbour)
4979 if(is_left_down_neighbour)
4984 if(is_right_down_neighbour)
4989 if(is_left_up_neighbour)
4994 if(is_right_up_neighbour)
5001 if(is_left_front_neighbour)
5006 if(is_right_front_neighbour)
5011 if(is_down_front_neighbour)
5016 if(is_up_front_neighbour)
5037 using namespace OcTreeNames;
5040 unsigned numtrees =
ntree();
5044 if(numtrees>0) nnode1d=
Trees_pt[0]->object_pt()->nnode_1d();
5052 for(
unsigned i=0;
i<numtrees;
i++)
5072 OcTree::Reflect_face[direction]);
5083 ->node_pt(nnode1d*nnode1d*nnode1d-1));
5086 ->node_pt(nnode1d*nnode1d-1));
5097 std::ostringstream error_stream;
5100 <<
"'s Up neighbour has no neighbour pointer to Tree " <<
i 5104 OOMPH_CURRENT_FUNCTION,
5105 OOMPH_EXCEPTION_LOCATION);
5118 int direction = neigh_pt->direction_of_neighbour(
octree_pt(
i));
5128 OcTree::Reflect_face[direction]);
5136 int nod1=neigh_pt->object_pt()->
5138 ->node_pt(nnode1d*nnode1d*nnode1d-1));
5139 int nod2=neigh_pt->object_pt()->
5141 ->node_pt(nnode1d*nnode1d-1));
5153 std::ostringstream error_stream;
5156 <<
"'s Right neighbour has no neighbour pointer to Tree " <<
i 5160 OOMPH_CURRENT_FUNCTION,
5161 OOMPH_EXCEPTION_LOCATION);
5175 int direction = neigh_pt->direction_of_neighbour(
octree_pt(
i));
5191 int nod1=neigh_pt->object_pt()
5193 ->node_pt(nnode1d-1));
5194 int nod2=neigh_pt->object_pt()->
5196 ->node_pt((nnode1d*nnode1d+1)*(nnode1d-1)));
5207 std::ostringstream error_stream;
5210 <<
"'s Down neighbour has no neighbour pointer to Tree " <<
i 5214 OOMPH_CURRENT_FUNCTION,
5215 OOMPH_EXCEPTION_LOCATION);
5230 int direction = neigh_pt->direction_of_neighbour(
octree_pt(
i));
5246 int nod1=neigh_pt->object_pt()->
5248 ->node_pt((nnode1d-1)*nnode1d));
5249 int nod2=neigh_pt->object_pt()->
5251 ->node_pt((nnode1d*nnode1d-1)*nnode1d));
5263 std::ostringstream error_stream;
5266 <<
"'s Left neighbour has no neighbour pointer to Tree " <<
i 5270 OOMPH_CURRENT_FUNCTION,
5271 OOMPH_EXCEPTION_LOCATION);
5285 int direction = neigh_pt->direction_of_neighbour(
octree_pt(
i));
5295 int nod1=neigh_pt->object_pt()->
5297 ->node_pt(nnode1d*nnode1d*nnode1d-1));
5298 int nod2=neigh_pt->object_pt()->
5300 ->node_pt((nnode1d*nnode1d-1)*nnode1d));
5313 nod1=neigh_pt->object_pt()->
5315 ->node_pt(nnode1d*nnode1d*nnode1d-1));
5316 nod2=neigh_pt->object_pt()->
5318 ->node_pt((nnode1d*nnode1d+1)*(nnode1d-1)));
5329 std::ostringstream error_stream;
5332 <<
"'s Front neighbour has no neighbour pointer to Tree " <<
i 5336 OOMPH_CURRENT_FUNCTION,
5337 OOMPH_EXCEPTION_LOCATION);
5350 int direction = neigh_pt->direction_of_neighbour(
octree_pt(
i));
5360 int nod1=neigh_pt->object_pt()->
5362 ->node_pt((nnode1d-1)*nnode1d));
5363 int nod2=neigh_pt->object_pt()->
5365 ->node_pt(nnode1d*nnode1d-1));
5379 nod1=neigh_pt->object_pt()->
5381 ->node_pt(nnode1d*nnode1d-1));
5382 nod2=neigh_pt->object_pt()->
5384 ->node_pt(nnode1d-1));
5395 std::ostringstream error_stream;
5398 <<
"'s Back neighbour has no neighbour pointer to Tree " <<
i 5402 OOMPH_CURRENT_FUNCTION,
5403 OOMPH_EXCEPTION_LOCATION);
5412 for (
int edge=
LB;edge<=
UF;edge++)
5418 unsigned n_neigh=edge_neigh_pt.size();
5419 for (
unsigned e=0;
e<n_neigh;
e++)
5422 if(edge_neigh_pt[
e]!=0)
5426 int vertex =OcTree::Vertex_at_end_of_edge[edge][0];
5427 int other_vertex=OcTree::Vertex_at_end_of_edge[edge][1];
5436 unsigned neighb_nod1=edge_neigh_pt[
e]->object_pt()->
5440 unsigned neighb_nod2=edge_neigh_pt[
e]->object_pt()->
5447 int neighb_other_vertex=
5454 OcTree::Up_and_right_equivalent_for_pairs_of_vertices[
5455 std::make_pair(std::make_pair(neighb_vertex,vertex),
5456 std::make_pair(neighb_other_vertex,other_vertex))].
5462 OcTree::Up_and_right_equivalent_for_pairs_of_vertices[
5463 std::make_pair(std::make_pair(neighb_vertex,vertex),
5464 std::make_pair(neighb_other_vertex,other_vertex))].
5486 unsigned long num_nodes=all_nodes_pt.size();
5487 for (
unsigned long i=0;
i<num_nodes;
i++)
5489 all_nodes_pt[
i]->object_pt()->set_number(++count);
5493 std::ofstream neighbours_file;
5494 std::ofstream no_true_edge_file;
5495 std::ofstream neighbours_txt_file;
5497 double max_error_face=0.0;
5499 neighbours_txt_file, max_error_face);
5501 double max_error_edge=0.0;
5504 neighbours_txt_file, max_error_edge);
5510 <<
"\n\n Failed self_test() for OcTreeForest because of faces: Max. error " 5511 << max_error_face << std::endl<< std::endl;
5518 <<
"\n\n Failed self_test() for OcTreeForest because of edges: Max. error " 5519 << max_error_edge << std::endl<< std::endl;
5523 double max_error=max_error_face;
5524 if (max_error_edge>max_error) max_error=max_error_edge;
5532 oomph_info <<
"\nPassed self_test() for OcTreeForest: Max. error " 5533 << max_error << std::endl;
5559 std::ofstream neigh_file;
5560 std::ofstream neigh_txt_file;
5564 std::ostringstream fullname;
5565 fullname << doc_info.
directory() <<
"/neighbours" 5566 << doc_info.
number() <<
".dat";
5567 oomph_info <<
"opened " << fullname.str() <<
" to doc neighbours" 5569 neigh_file.open(fullname.str().c_str());
5571 fullname << doc_info.
directory() <<
"/neighbours" 5572 << doc_info.
number() <<
".txt";
5573 oomph_info <<
"opened " << fullname.str() <<
" to doc neighbours" 5575 neigh_txt_file.open(fullname.str().c_str());
5579 double max_error=0.0;
5581 neigh_file,neigh_txt_file,max_error);
5584 std::ostringstream error_stream;
5585 error_stream <<
"\nMax. error in octree neighbour finding: " 5586 << max_error <<
" is too big" << std::endl;
5588 <<
"i.e. bigger than Tree::max_neighbour_finding_tolerance()=" 5595 neigh_txt_file.close();
5599 OOMPH_CURRENT_FUNCTION,
5600 OOMPH_EXCEPTION_LOCATION);
5604 oomph_info <<
"\nMax. error in octree neighbour finding: " 5605 << max_error <<
" is OK" << std::endl;
5606 oomph_info <<
"i.e. less than OcTree::max_neighbour_finding_tolerance()=" 5614 neigh_txt_file.close();
5622 std::ofstream neigh_file;
5623 std::ofstream no_true_edge_file;
5624 std::ofstream neigh_txt_file;
5628 std::ostringstream fullname;
5629 fullname << doc_info.
directory() <<
"/edge_neighbours" 5630 << doc_info.
number() <<
".dat";
5631 neigh_file.open(fullname.str().c_str());
5633 fullname << doc_info.
directory() <<
"/no_true_edge" 5634 << doc_info.
number() <<
".dat";
5635 no_true_edge_file.open(fullname.str().c_str());
5637 fullname << doc_info.
directory() <<
"/edge_neighbours" 5638 << doc_info.
number() <<
".txt";
5639 neigh_txt_file.open(fullname.str().c_str());
5643 double max_error=0.0;
5645 neigh_file,no_true_edge_file,
5646 neigh_txt_file,max_error);
5649 std::ostringstream error_stream;
5650 error_stream <<
"Max. error in octree edge neighbour finding: " 5651 << max_error <<
" is too big" << std::endl;
5653 <<
"i.e. bigger than Tree::max_neighbour_finding_tolerance()=" 5660 no_true_edge_file.close();
5661 neigh_txt_file.close();
5665 OOMPH_CURRENT_FUNCTION,
5666 OOMPH_EXCEPTION_LOCATION);
5670 oomph_info <<
"Max. error in octree edge neighbour finding: " 5671 << max_error <<
" is OK" << std::endl;
5672 oomph_info <<
"i.e. less than OcTree::max_neighbour_finding_tolerance()=" 5680 no_true_edge_file.close();
5681 neigh_txt_file.close();
5699 for(
unsigned i=0;
i<6;
i++)
5700 {output_stream.push_back(
new std::ofstream);}
5705 std::ostringstream fullname;
5706 fullname << doc_info.
directory() <<
"/hang_nodes_u" 5707 << doc_info.
number() <<
".dat";
5708 output_stream[0]->open(fullname.str().c_str());
5710 fullname << doc_info.
directory() <<
"/hang_nodes_d" 5711 << doc_info.
number() <<
".dat";
5712 output_stream[1]->open(fullname.str().c_str());
5714 fullname << doc_info.
directory() <<
"/hang_nodes_l" 5715 << doc_info.
number() <<
".dat";
5716 output_stream[2]->open(fullname.str().c_str());
5718 fullname << doc_info.
directory() <<
"/hang_nodes_r" 5719 << doc_info.
number() <<
".dat";
5720 output_stream[3]->open(fullname.str().c_str());
5722 fullname << doc_info.
directory() <<
"/hang_nodes_b" 5723 << doc_info.
number() <<
".dat";
5724 output_stream[4]->open(fullname.str().c_str());
5726 fullname << doc_info.
directory() <<
"/hang_nodes_f" 5727 << doc_info.
number() <<
".dat";
5728 output_stream[5]->open(fullname.str().c_str());
static std::map< std::pair< std::pair< int, int >, std::pair< int, int > >, std::pair< int, int > > Up_and_right_equivalent_for_pairs_of_vertices
Storage for the up/right-equivalents corresponding to two pairs of vertices along an element edge: ...
Vector< Tree * > Son_pt
Vector of pointers to the sons of the Tree.
Vector< TreeRoot * > Trees_pt
Vector containing the pointers to the trees.
static Vector< int > Reflect_face
Get opposite face, e.g. Reflect_face[L]=R.
static double & max_neighbour_finding_tolerance()
Max. allowed discrepancy in neighbour finding routine (distance between points when identified from t...
unsigned ntree()
Number of trees in forest.
void get_x(const Vector< double > &s, Vector< double > &x) const
Global coordinates as function of local coordinates. Either via FE representation or via macro-elemen...
void set_right_equivalent(TreeRoot *tree_root_pt, const int &dir)
The same thing as up_equivalent, but for the right direction: When viewed from the current octree nei...
static void setup_static_data()
Setup the static data, rotation and reflection schemes, etc.
static unsigned vertex_to_node_number(const int &vertex, const unsigned &nnode1d)
Return the local node number of given vertex [LDB,RDB,...] in an element with nnode1d nodes in each c...
TreeRoot *& neighbour_pt(const int &direction)
Return the pointer to the neighbouring TreeRoots in specified direction. Returns NULL if there's no n...
OcTree * gteq_face_neighbour(const int &direction, Vector< unsigned > &translate_s, Vector< double > &s_sw, Vector< double > &s_ne, int &face, int &diff_level) const
Find (pointer to) `greater-or-equal-sized face neighbour' in given direction (L/R/U/D/F/B). Another way of interpreting this is that we're looking for the neighbour across the present element's face 'direction'. The various arguments return additional information about the size and relative orientation of the neighbouring octree. To interpret these we use the following General convention:
static std::map< Vector< int >, int > Vector_to_direction
Each vector representing a direction can be translated into a direction, either a son type (vertex)...
bool is_doc_enabled() const
Are we documenting?
static Vector< int > vertex_node_to_vector(const unsigned &n, const unsigned &nnode1d)
Returns the vector of the coordinate directions of vertex node number n in an element with nnode1d el...
static DenseMatrix< double > S_base_edge
S_base_edge(i,edge): Initial value for coordinate s[i] on the specified edge (LF/RF/...).
static Vector< std::string > Colour
Colours for neighbours in various directions.
void find_neighbours()
Construct the neighbour scheme.
Information for documentation of results: Directory and file number to enable output in the form RESL...
std::string directory() const
Output directory.
int up_equivalent(TreeRoot *tree_root_pt)
Return up equivalent of the neighbours specified by pointer: When viewed from the current octree's ne...
Base class for all brick elements.
void stick_all_tree_nodes_into_vector(Vector< Tree * > &all_forest_nodes)
Traverse forest and stick pointers to all "nodes" into Vector.
static double Max_neighbour_finding_tolerance
Max. allowed discrepancy in neighbour finding routine (distance between points when identified from t...
static DenseMatrix< double > S_steplo
Each face of the RefineableQElement<3> that is represented by the octree is parametrised by two (of t...
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
TreeRoot * Root_pt
Pointer to the root of the tree.
static Vector< Vector< int > > Vertex_at_end_of_edge
Vector of vectors containing the two vertices for each edge, e.g. Vertex_at_end_of_edge[LU][0]=LUB an...
unsigned & number()
Number used (e.g.) for labeling output files.
void construct_up_right_equivalents()
Construct the rotation schemes.
OcTreeRoot * octree_pt(const unsigned &i) const
Return pointer to i-th OcTree in forest (Performs a dynamic cast from the TreeRoot to a OcTreeRoot)...
void check_all_neighbours(DocInfo &doc_info)
Document and check all the neighbours of all the nodes in the forest. DocInfo object specifies the ou...
long number() const
Element number (for debugging/plotting)
static DenseMatrix< double > S_base
s_base(i,direction): Initial value for coordinate s[i] on the face indicated by direction (L/R/U/D/F/...
unsigned self_test()
Self-test: Check all neighbours. Return success (0) if the max. distance between corresponding points...
static Vector< int > rotate(const int &new_up, const int &new_right, const Vector< int > &dir)
If U[p] becomes new_up and R[ight] becomes new_right then the direction vector dir becomes rotate(new...
static Vector< int > Cosi
Entry in rotation matrix: cos(i*90)
static Vector< int > Reflect_vertex
Get opposite vertex, e.g. Reflect_vertex[LDB]=RUF.
double angle(const Vector< double > &a, const Vector< double > &b)
Get the angle between two vector.
static bool Static_data_has_been_setup
Bool indicating that static member data has been setup.
static DenseMatrix< double > S_stephi
If we're located on face face [L/R/F/B/U/D], then an increase in s_hi from -1 to +1 corresponds to a ...
static Vector< int > Reflect_edge
Get opposite edge, e.g. Reflect_edge[DB]=UF.
int Level
Level of the Tree (level 0 = root)
static DenseMatrix< int > Reflect
Reflection scheme: Reflect(direction,octant): Get mirror of octant/edge in specified direction...
static void doc_face_neighbours(Vector< Tree *> forest_nodes_pt, std::ofstream &neighbours_file, std::ofstream &neighbours_txt_file, double &max_error)
Doc/check all face neighbours of octree (nodes) contained in the Vector forest_node_pt. Output into neighbours_file which can be viewed from tecplot with OcTreeNeighbours.mcr Neighbour info and errors are displayed on neighbours_txt_file. Finally, compute the max. error between vertices when viewed from neighhbouring element. If the two filestreams are closed, output is suppressed.
static Vector< Vector< int > > Direction_to_vector
For each direction, i.e. a son_type (vertex), a face or an edge, this defines a vector that indicates...
static int get_the_other_face(const unsigned &n1, const unsigned &n2, const unsigned &nnode1d, const int &face)
If an edge is bordered by the nodes whose local numbers are n1 and n2 in an element with nnode1d node...
OcTree * gteq_true_edge_neighbour(const int &direction, const unsigned &i_root_edge_neighbour, unsigned &nroot_edge_neighbour, Vector< unsigned > &translate_s, Vector< double > &s_lo, Vector< double > &s_hi, int &edge, int &diff_level) const
Find (pointer to) `greater-or-equal-sized true edge neighbour' in the given direction (LB...
static DenseMatrix< double > S_directlo
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
static DenseMatrix< double > S_step_edge
Each edge of the RefineableQElement<3> that is represented by the octree is parametrised by one (of t...
static void mult_mat_vect(const DenseMatrix< int > &mat, const Vector< int > &vect1, Vector< int > &vect2)
Helper function: Performs the operation : vect2 = mat*vect1.
static Vector< std::string > Direct_string
Translate (enumerated) directions into strings.
OcTreeRoot * oc_face_neigh_pt(const unsigned &i, const int &direction)
Given the number i of the root octree in this forest, return pointer to its face neighbour in the spe...
Tree * Father_pt
Pointer to the Father of the Tree.
virtual bool nodes_built()
Return true if all the nodes have been built, false if not.
static const int OMEGA
Default value for an unassigned neighbour.
void set_up_equivalent(TreeRoot *tree_root_pt, const int &dir)
Set up equivalent of the neighbours specified by pointer: When viewed from the current octree's neigh...
void stick_all_tree_nodes_into_vector(Vector< Tree * > &)
Traverse and stick pointers to all "nodes" into Vector.
static int num_elem(char *strv, unsigned elem_len, int term_char, int num_term) static int num_elem(strv
static DenseMatrix< bool > Is_adjacent
Array of direction/octant adjacency scheme: Is_adjacent(direction,octant): Is face/edge direction adj...
Vector< TreeRoot * > oc_edge_neigh_pt(const unsigned &i, const int &direction)
Given the number i of the root octree in this forest, return the vector of pointers to the true edge ...
static int node_number_to_vertex(const unsigned &n, const unsigned &nnode1d)
Return the vertex [LDB,RDB,...] of local (vertex) node n.
unsigned self_test()
Self-test: Check all neighbours. Return success (0) if the max. distance between corresponding points...
static void doc_true_edge_neighbours(Vector< Tree *> forest_nodes_pt, std::ofstream &neighbours_file, std::ofstream &no_true_edge_file, std::ofstream &neighbours_txt_file, double &max_error)
Doc/check all true edge neighbours of octree (nodes) contained in the Vector forest_node_pt. Output into neighbours_file which can be viewed from tecplot with OcTreeNeighbours.mcr Neighbour info and errors are displayed on neighbours_txt_file. Finally, compute the max. error between vertices when viewed from neighhbouring element. If the two filestreams are closed, output is suppressed.
void pause(std::string message)
Pause and display message.
void add_edge_neighbour_pt(TreeRoot *oc_tree_root_pt, const unsigned &edge_direction)
Add pointer to the edge-neighbouring [Oc]TreeRoot in the (enumerated) (edge) direction – maintains u...
OcTreeForest()
Default constructor (empty and broken)
OcTree * gteq_edge_neighbour(const int &direction, const unsigned &i_root_edge_neighbour, unsigned &nroot_edge_neighbour, double &s_diff, int &diff_level, int max_level, OcTreeRoot *orig_root_pt) const
Find `greater-or-equal-sized edge neighbour' in given direction (LB,RB,DB,UB [the back edges]...
int direction_of_neighbour(TreeRoot *octree_root_pt)
If octree_root_pt is a neighbour, return the direction [faces L/R/F/B/U/D or edges DB/UP/...
RefineableElement * object_pt() const
Return the pointer to the object (RefineableElement) represented by the tree.
static DenseMatrix< double > S_directhi
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
static void mult_mat_mat(const DenseMatrix< int > &mat1, const DenseMatrix< int > &mat2, DenseMatrix< int > &mat3)
Helper function: Performs the operation : mat3=mat1*mat2.
static DenseMatrix< int > Common_face
Determine common face of edges or octants. Slightly bizarre lookup scheme from Samet's book...
bool is_leaf()
Return true if the tree is a leaf node.
void open_hanging_node_files(DocInfo &doc_info, Vector< std::ofstream *> &output_stream)
Open output files that will store any hanging nodes in.
static DenseMatrix< double > S_direct_edge
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
bool edge_neighbour_is_face_neighbour(const int &edge, OcTree *edge_neighb_pt) const
Is the edge neighbour (for edge "edge") specified via the pointer also a face neighbour for one of th...
static Vector< int > Sini
Entry in rotation matrix sin(i*90)
int Son_type
Son type (e.g. SW/SE/NW/NE in a quadtree)
static void construct_rotation_matrix(int &axis, int &angle, DenseMatrix< int > &mat)
This constructs the rotation matrix of the rotation around the axis axis with an angle of angle*90...
int right_equivalent(TreeRoot *tree_root_pt)
The same thing as up_equivalent, but for the right direction: When viewed from the current octree nei...
void resize(const unsigned long &n)