100 std::map<std::pair<std::pair<int, int>, std::pair<int, int>>,
233 const unsigned& nnode1d)
236 if ((n != 0) && (n != nnode1d - 1) && (n != (nnode1d - 1) * nnode1d) &&
237 (n != nnode1d * nnode1d - 1) &&
238 (n != (nnode1d * nnode1d) * (nnode1d - 1) + 0) &&
239 (n != (nnode1d * nnode1d) * (nnode1d - 1) + nnode1d - 1) &&
240 (n != (nnode1d * nnode1d) * (nnode1d - 1) + (nnode1d - 1) * nnode1d) &&
241 (n != (nnode1d * nnode1d) * (nnode1d - 1) + nnode1d * nnode1d - 1))
243 std::ostringstream error_stream;
244 error_stream <<
"Node " << n
245 <<
" is not a vertex node in a brick element with "
246 << nnode1d <<
" nodes along each edge!";
249 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
254 a = n / (nnode1d * nnode1d);
255 b = (n - a * nnode1d * nnode1d) / nnode1d;
256 c = n - a * nnode1d * nnode1d - b * nnode1d;
258 result_vect[0] = 2 * c / (nnode1d - 1) - 1;
259 result_vect[1] = 2 * b / (nnode1d - 1) - 1;
260 result_vect[2] = 2 * a / (nnode1d - 1) - 1;
270 using namespace OcTreeNames;
273 if ((edge !=
LB) && (edge !=
RB) && (edge !=
DB) && (edge !=
UB) &&
274 (edge !=
LD) && (edge !=
RD) && (edge !=
LU) && (edge !=
RU) &&
275 (edge !=
LF) && (edge !=
RF) && (edge !=
DF) && (edge !=
UF))
277 std::ostringstream error_stream;
278 error_stream <<
"Edge " <<
Direct_string[edge] <<
"is not valid!";
280 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
401 OOMPH_CURRENT_FUNCTION,
402 OOMPH_EXCEPTION_LOCATION);
415 const unsigned& nnode1d)
417 using namespace OcTreeNames;
420 if ((vertex !=
LDB) && (vertex !=
RDB) && (vertex !=
LUB) &&
421 (vertex !=
RUB) && (vertex !=
LDF) && (vertex !=
RDF) &&
422 (vertex !=
LUF) && (vertex !=
RUF))
424 std::ostringstream error_stream;
425 error_stream <<
"Wrong vertex: " <<
Direct_string[vertex] << std::endl;
427 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
443 return nnode1d * (nnode1d - 1);
447 return nnode1d * nnode1d - 1;
452 return nnode1d * nnode1d * (nnode1d - 1);
457 return (nnode1d * nnode1d + 1) * (nnode1d - 1);
461 return nnode1d * nnode1d * nnode1d - nnode1d;
465 return nnode1d * nnode1d * nnode1d - 1;
470 std::ostringstream error_stream;
471 error_stream <<
"Never get here. vertex: " <<
Direct_string[vertex]
474 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
479 std::ostringstream error_stream;
480 error_stream <<
"Never get here. vertex: " <<
Direct_string[vertex]
483 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
493 using namespace OcTreeNames;
496 if ((n != 0) && (n != nnode1d - 1) && (n != (nnode1d - 1) * nnode1d) &&
497 (n != nnode1d * nnode1d - 1) &&
498 (n != (nnode1d * nnode1d) * (nnode1d - 1) + 0) &&
499 (n != (nnode1d * nnode1d) * (nnode1d - 1) + nnode1d - 1) &&
500 (n != (nnode1d * nnode1d) * (nnode1d - 1) + (nnode1d - 1) * nnode1d) &&
501 (n != (nnode1d * nnode1d) * (nnode1d - 1) + nnode1d * nnode1d - 1))
503 std::ostringstream error_stream;
504 error_stream <<
"Node " << n
505 <<
" is not a vertex node in a brick element with "
506 << nnode1d <<
" nodes along each edge!";
509 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
517 else if (n == nnode1d - 1)
521 else if (n == nnode1d * (nnode1d - 1))
525 else if (n == nnode1d * nnode1d - 1)
529 else if (n == nnode1d * nnode1d * (nnode1d - 1))
533 else if (n == (nnode1d * nnode1d + 1) * (nnode1d - 1))
537 else if (n == nnode1d * nnode1d * nnode1d - nnode1d)
541 else if (n == nnode1d * nnode1d * nnode1d - 1)
547 std::ostringstream error_stream;
548 error_stream <<
"Never get here. local node number: " << n
549 <<
" is not a vertex node in a brick element with "
550 << nnode1d <<
" nodes along each edge!" << std::endl;
552 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
567 const unsigned& nnode1d,
584 for (
unsigned i = 0;
i < 3;
i++)
587 vect_other_face[
i] = (vect_node1[
i] + vect_node2[
i]) / 2 - vect_face[
i];
590 if ((vect_other_face[
i] != 1) && (vect_other_face[
i] != -1) &&
591 (vect_other_face[
i] != 0))
594 OOMPH_CURRENT_FUNCTION,
595 OOMPH_EXCEPTION_LOCATION);
613 using namespace OcTreeNames;
614 int a = 0, b = 0, c = 0,
i, j;
635 std::ostringstream error_message_stream;
638 error_message_stream <<
"Bad axis (" << axis <<
"). Expected "
644 OOMPH_CURRENT_FUNCTION,
645 OOMPH_EXCEPTION_LOCATION);
647 for (
i = 0;
i < 3;
i++)
649 for (j = 0; j < 3; j++)
669 for (
i = 0;
i < 3;
i++)
671 for (j = 0; j < 3; j++)
674 for (k = 0; k < 3; k++)
676 Sum += mat1(
i, k) * mat2(k, j);
692 for (
i = 0;
i < 3;
i++)
695 for (k = 0; k < 3; k++)
697 sum += mat(
i, k) * vect1[k];
711 using namespace OcTreeNames;
714 if ((new_up !=
L) && (new_up !=
R) && (new_up !=
F) && (new_up !=
B) &&
715 (new_up !=
U) && (new_up !=
D))
717 std::ostringstream error_stream;
718 error_stream <<
"Wrong new_up: " <<
Direct_string[new_up] << std::endl;
720 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
722 if ((new_right !=
L) && (new_right !=
R) && (new_right !=
F) &&
723 (new_right !=
B) && (new_right !=
U) && (new_right !=
D))
725 std::ostringstream error_stream;
726 error_stream <<
"Wrong new_right: " <<
Direct_string[new_right]
729 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
739 vect_new_dir =
rotate(new_up, new_right, vect_dir);
751 const int& new_right,
754 using namespace OcTreeNames;
757 if ((new_up !=
L) && (new_up !=
R) && (new_up !=
F) && (new_up !=
B) &&
758 (new_up !=
U) && (new_up !=
D))
760 std::ostringstream error_stream;
761 error_stream <<
"Wrong new_up: " <<
Direct_string[new_up] << std::endl;
763 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
765 if ((new_right !=
L) && (new_right !=
R) && (new_right !=
F) &&
766 (new_right !=
B) && (new_right !=
U) && (new_right !=
D))
768 std::ostringstream error_stream;
769 error_stream <<
"Wrong new_right: " <<
Direct_string[new_right]
772 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
782 int axis1, axis2, angle1, angle2, nrot;
803 std::ostringstream error_stream;
804 error_stream <<
"New_right is " << new_right <<
" ("
806 <<
"It should be R, B, L, or F" << std::endl;
808 OOMPH_CURRENT_FUNCTION,
809 OOMPH_EXCEPTION_LOCATION);
840 std::ostringstream error_stream;
841 error_stream <<
"New_right is " << new_right <<
" ("
843 <<
"It should be R, B, L, or F" << std::endl;
845 OOMPH_CURRENT_FUNCTION,
846 OOMPH_EXCEPTION_LOCATION);
878 std::ostringstream error_stream;
879 error_stream <<
"New_right is " << new_right <<
" ("
881 <<
"It should be D, B, U, or F" << std::endl;
883 OOMPH_CURRENT_FUNCTION,
884 OOMPH_EXCEPTION_LOCATION);
916 std::ostringstream error_stream;
917 error_stream <<
"New_right is " << new_right <<
" ("
919 <<
"It should be D, B, U, or F" << std::endl;
921 OOMPH_CURRENT_FUNCTION,
922 OOMPH_EXCEPTION_LOCATION);
954 std::ostringstream error_stream;
955 error_stream <<
"New_right is " << new_right <<
" ("
957 <<
"It should be R, L, U, or D" << std::endl;
959 OOMPH_CURRENT_FUNCTION,
960 OOMPH_EXCEPTION_LOCATION);
991 std::ostringstream error_stream;
992 error_stream <<
"New_right is " << new_right <<
" ("
994 <<
"It should be R, L, U, or D" << std::endl;
996 OOMPH_CURRENT_FUNCTION,
997 OOMPH_EXCEPTION_LOCATION);
1020 for (
int i = 0;
i < 3;
i++)
1022 for (
int j = 0; j < 3; j++)
1024 mat3(
i, j) = mat1(
i, j);
1033 return vect_new_dir;
1042 using namespace OcTreeNames;
1048 std::ostringstream error_stream;
1049 error_stream <<
"Inconsistent enumeration! \n Tree::OMEGA="
1053 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2192 for (
int i = -1;
i < 2;
i++)
2194 for (
int j = -1; j < 2; j++)
2196 for (
int k = -1; k < 2; k++)
2206 num_elem = (
i + 1) * 9 + (j + 1) * 3 + (k + 1);
2294 oomph_info <<
"there might be a problem with Vector_to_direction"
2308 for (
int i =
LDB;
i <=
F;
i++)
2312 for (
int j = 0; j < 3; j++)
2319 for (
unsigned j = 0; j < 3; j++)
2344 oomph_info <<
"Direction Error !!" << std::endl;
2356 int new_up, new_right;
2364 std::map<std::pair<int, int>, std::set<std::pair<int, int>>>
2368 for (
int vertex =
LDB; vertex <=
RUF; vertex++)
2373 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2374 std::make_pair(new_up, new_right));
2379 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2380 std::make_pair(new_up, new_right));
2385 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2386 std::make_pair(new_up, new_right));
2391 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2392 std::make_pair(new_up, new_right));
2398 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2399 std::make_pair(new_up, new_right));
2404 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2405 std::make_pair(new_up, new_right));
2410 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2411 std::make_pair(new_up, new_right));
2416 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2417 std::make_pair(new_up, new_right));
2423 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2424 std::make_pair(new_up, new_right));
2429 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2430 std::make_pair(new_up, new_right));
2435 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2436 std::make_pair(new_up, new_right));
2441 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2442 std::make_pair(new_up, new_right));
2448 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2449 std::make_pair(new_up, new_right));
2454 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2455 std::make_pair(new_up, new_right));
2460 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2461 std::make_pair(new_up, new_right));
2466 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2467 std::make_pair(new_up, new_right));
2473 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2474 std::make_pair(new_up, new_right));
2479 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2480 std::make_pair(new_up, new_right));
2485 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2486 std::make_pair(new_up, new_right));
2491 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2492 std::make_pair(new_up, new_right));
2498 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2499 std::make_pair(new_up, new_right));
2504 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2505 std::make_pair(new_up, new_right));
2510 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2511 std::make_pair(new_up, new_right));
2516 required_rotation[std::make_pair(vertex, new_vertex)].insert(
2517 std::make_pair(new_up, new_right));
2525 std::map<int, Vector<int>> vertex_in_edge_neighbour;
2530 std::map<int, Vector<int>> other_vertex_on_edge;
2535 std::map<int, Vector<int>> other_vertex_in_edge_neighbour;
2538 vertex_in_edge_neighbour[
LDB].resize(3);
2539 vertex_in_edge_neighbour[
LDB][0] =
2541 vertex_in_edge_neighbour[
LDB][1] =
RDF;
2542 vertex_in_edge_neighbour[
LDB][2] =
RUB;
2544 other_vertex_on_edge[
LDB].resize(3);
2545 other_vertex_on_edge[
LDB][0] =
2547 other_vertex_on_edge[
LDB][1] =
LUB;
2548 other_vertex_on_edge[
LDB][2] =
LDF;
2550 other_vertex_in_edge_neighbour[
LDB].resize(3);
2551 other_vertex_in_edge_neighbour[
LDB][0] =
RUF;
2552 other_vertex_in_edge_neighbour[
LDB][1] =
RUF;
2553 other_vertex_in_edge_neighbour[
LDB][2] =
RUF;
2556 vertex_in_edge_neighbour[
RDB].resize(3);
2557 vertex_in_edge_neighbour[
RDB][0] =
2559 vertex_in_edge_neighbour[
RDB][1] =
LDF;
2560 vertex_in_edge_neighbour[
RDB][2] =
LUB;
2562 other_vertex_on_edge[
RDB].resize(3);
2563 other_vertex_on_edge[
RDB][0] =
2565 other_vertex_on_edge[
RDB][1] =
RUB;
2566 other_vertex_on_edge[
RDB][2] =
RDF;
2568 other_vertex_in_edge_neighbour[
RDB].resize(3);
2569 other_vertex_in_edge_neighbour[
RDB][0] =
LUF;
2570 other_vertex_in_edge_neighbour[
RDB][1] =
LUF;
2571 other_vertex_in_edge_neighbour[
RDB][2] =
LUF;
2574 vertex_in_edge_neighbour[
LUB].resize(3);
2575 vertex_in_edge_neighbour[
LUB][0] =
2577 vertex_in_edge_neighbour[
LUB][1] =
RUF;
2578 vertex_in_edge_neighbour[
LUB][2] =
RDB;
2580 other_vertex_on_edge[
LUB].resize(3);
2581 other_vertex_on_edge[
LUB][0] =
2583 other_vertex_on_edge[
LUB][1] =
LDB;
2584 other_vertex_on_edge[
LUB][2] =
LUF;
2586 other_vertex_in_edge_neighbour[
LUB].resize(3);
2587 other_vertex_in_edge_neighbour[
LUB][0] =
RDF;
2588 other_vertex_in_edge_neighbour[
LUB][1] =
RDF;
2589 other_vertex_in_edge_neighbour[
LUB][2] =
RDF;
2592 vertex_in_edge_neighbour[
RUB].resize(3);
2593 vertex_in_edge_neighbour[
RUB][0] =
2595 vertex_in_edge_neighbour[
RUB][1] =
LUF;
2596 vertex_in_edge_neighbour[
RUB][2] =
LDB;
2598 other_vertex_on_edge[
RUB].resize(3);
2599 other_vertex_on_edge[
RUB][0] =
2601 other_vertex_on_edge[
RUB][1] =
RDB;
2602 other_vertex_on_edge[
RUB][2] =
RUF;
2604 other_vertex_in_edge_neighbour[
RUB].resize(3);
2605 other_vertex_in_edge_neighbour[
RUB][0] =
LDF;
2606 other_vertex_in_edge_neighbour[
RUB][1] =
LDF;
2607 other_vertex_in_edge_neighbour[
RUB][2] =
LDF;
2610 vertex_in_edge_neighbour[
LDF].resize(3);
2611 vertex_in_edge_neighbour[
LDF][0] =
2613 vertex_in_edge_neighbour[
LDF][1] =
RDB;
2614 vertex_in_edge_neighbour[
LDF][2] =
RUF;
2616 other_vertex_on_edge[
LDF].resize(3);
2617 other_vertex_on_edge[
LDF][0] =
2619 other_vertex_on_edge[
LDF][1] =
LUF;
2620 other_vertex_on_edge[
LDF][2] =
LDB;
2622 other_vertex_in_edge_neighbour[
LDF].resize(3);
2623 other_vertex_in_edge_neighbour[
LDF][0] =
RUB;
2624 other_vertex_in_edge_neighbour[
LDF][1] =
RUB;
2625 other_vertex_in_edge_neighbour[
LDF][2] =
RUB;
2628 vertex_in_edge_neighbour[
RDF].resize(3);
2629 vertex_in_edge_neighbour[
RDF][0] =
2631 vertex_in_edge_neighbour[
RDF][1] =
LDB;
2632 vertex_in_edge_neighbour[
RDF][2] =
LUF;
2634 other_vertex_on_edge[
RDF].resize(3);
2635 other_vertex_on_edge[
RDF][0] =
2637 other_vertex_on_edge[
RDF][1] =
RUF;
2638 other_vertex_on_edge[
RDF][2] =
RDB;
2640 other_vertex_in_edge_neighbour[
RDF].resize(3);
2641 other_vertex_in_edge_neighbour[
RDF][0] =
LUB;
2642 other_vertex_in_edge_neighbour[
RDF][1] =
LUB;
2643 other_vertex_in_edge_neighbour[
RDF][2] =
LUB;
2646 vertex_in_edge_neighbour[
LUF].resize(3);
2647 vertex_in_edge_neighbour[
LUF][0] =
2649 vertex_in_edge_neighbour[
LUF][1] =
RUB;
2650 vertex_in_edge_neighbour[
LUF][2] =
RDF;
2652 other_vertex_on_edge[
LUF].resize(3);
2653 other_vertex_on_edge[
LUF][0] =
2655 other_vertex_on_edge[
LUF][1] =
LDF;
2656 other_vertex_on_edge[
LUF][2] =
LUB;
2658 other_vertex_in_edge_neighbour[
LUF].resize(3);
2659 other_vertex_in_edge_neighbour[
LUF][0] =
RDB;
2660 other_vertex_in_edge_neighbour[
LUF][1] =
RDB;
2661 other_vertex_in_edge_neighbour[
LUF][2] =
RDB;
2664 vertex_in_edge_neighbour[
RUF].resize(3);
2665 vertex_in_edge_neighbour[
RUF][0] =
2667 vertex_in_edge_neighbour[
RUF][1] =
LUB;
2668 vertex_in_edge_neighbour[
RUF][2] =
LDF;
2670 other_vertex_on_edge[
RUF].resize(3);
2671 other_vertex_on_edge[
RUF][0] =
2673 other_vertex_on_edge[
RUF][1] =
RDF;
2674 other_vertex_on_edge[
RUF][2] =
RUB;
2676 other_vertex_in_edge_neighbour[
RUF].resize(3);
2677 other_vertex_in_edge_neighbour[
RUF][0] =
LDB;
2678 other_vertex_in_edge_neighbour[
RUF][1] =
LDB;
2679 other_vertex_in_edge_neighbour[
RUF][2] =
LDB;
2683 for (
int vertex =
LDB; vertex <=
RUF; vertex++)
2686 for (
unsigned i = 0;
i < 3;
i++)
2689 int other_vertex = other_vertex_on_edge[vertex][
i];
2694 int unrotated_neigh_vertex = vertex_in_edge_neighbour[vertex][
i];
2699 int unrotated_neigh_other_vertex =
2700 other_vertex_in_edge_neighbour[vertex][
i];
2703 for (
int neigh_vertex =
LDB; neigh_vertex <=
RUF; neigh_vertex++)
2707 std::set<std::pair<int, int>> vertex_rot =
2708 required_rotation[std::make_pair(neigh_vertex,
2709 unrotated_neigh_vertex)];
2713 for (
int neigh_other_vertex =
LDB; neigh_other_vertex <=
RUF;
2714 neigh_other_vertex++)
2718 std::set<std::pair<int, int>> other_vertex_rot =
2719 required_rotation[std::make_pair(neigh_other_vertex,
2720 unrotated_neigh_other_vertex)];
2723 std::set<std::pair<int, int>> common_rotations;
2726 std::set_intersection(
2729 other_vertex_rot.begin(),
2730 other_vertex_rot.end(),
2731 inserter(common_rotations, common_rotations.begin()));
2734 if (common_rotations.size() > 0)
2736 for (std::set<std::pair<int, int>>::iterator it =
2737 common_rotations.begin();
2738 it != common_rotations.end();
2746 std::make_pair(vertex, neigh_vertex),
2747 std::make_pair(other_vertex, neigh_other_vertex))]
2753 std::make_pair(vertex, neigh_vertex),
2754 std::make_pair(other_vertex, neigh_other_vertex))]
2755 .second = it->second;
2770 OcTree* edge_neigh_pt)
const
2779 if (edge_neigh_pt == 0)
2784 using namespace OcTreeNames;
2793 bool in_neighbouring_tree =
false;
2795 OcTree* face_neigh_pt = 0;
2809 in_neighbouring_tree);
2812 if (face_neigh_pt != 0)
2814 if (face_neigh_pt == edge_neigh_pt)
2828 in_neighbouring_tree);
2831 if (face_neigh_pt != 0)
2833 if (face_neigh_pt == edge_neigh_pt)
2853 in_neighbouring_tree);
2856 if (face_neigh_pt != 0)
2858 if (face_neigh_pt == edge_neigh_pt)
2872 in_neighbouring_tree);
2874 if (face_neigh_pt != 0)
2876 if (face_neigh_pt == edge_neigh_pt)
2895 in_neighbouring_tree);
2898 if (face_neigh_pt != 0)
2900 if (face_neigh_pt == edge_neigh_pt)
2914 in_neighbouring_tree);
2916 if (face_neigh_pt != 0)
2918 if (face_neigh_pt == edge_neigh_pt)
2937 in_neighbouring_tree);
2940 if (face_neigh_pt != 0)
2942 if (face_neigh_pt == edge_neigh_pt)
2956 in_neighbouring_tree);
2959 if (face_neigh_pt != 0)
2961 if (face_neigh_pt == edge_neigh_pt)
2980 in_neighbouring_tree);
2983 if (face_neigh_pt != 0)
2985 if (face_neigh_pt == edge_neigh_pt)
2999 in_neighbouring_tree);
3001 if (face_neigh_pt != 0)
3003 if (face_neigh_pt == edge_neigh_pt)
3022 in_neighbouring_tree);
3025 if (face_neigh_pt != 0)
3027 if (face_neigh_pt == edge_neigh_pt)
3041 in_neighbouring_tree);
3043 if (face_neigh_pt != 0)
3045 if (face_neigh_pt == edge_neigh_pt)
3063 in_neighbouring_tree);
3066 if (face_neigh_pt != 0)
3068 if (face_neigh_pt == edge_neigh_pt)
3082 in_neighbouring_tree);
3085 if (face_neigh_pt != 0)
3087 if (face_neigh_pt == edge_neigh_pt)
3106 in_neighbouring_tree);
3109 if (face_neigh_pt != 0)
3111 if (face_neigh_pt == edge_neigh_pt)
3125 in_neighbouring_tree);
3128 if (face_neigh_pt != 0)
3130 if (face_neigh_pt == edge_neigh_pt)
3150 in_neighbouring_tree);
3153 if (face_neigh_pt != 0)
3155 if (face_neigh_pt == edge_neigh_pt)
3169 in_neighbouring_tree);
3172 if (face_neigh_pt != 0)
3174 if (face_neigh_pt == edge_neigh_pt)
3192 in_neighbouring_tree);
3195 if (face_neigh_pt != 0)
3197 if (face_neigh_pt == edge_neigh_pt)
3211 in_neighbouring_tree);
3214 if (face_neigh_pt != 0)
3216 if (face_neigh_pt == edge_neigh_pt)
3235 in_neighbouring_tree);
3238 if (face_neigh_pt != 0)
3240 if (face_neigh_pt == edge_neigh_pt)
3255 in_neighbouring_tree);
3258 if (face_neigh_pt != 0)
3260 if (face_neigh_pt == edge_neigh_pt)
3279 in_neighbouring_tree);
3282 if (face_neigh_pt != 0)
3284 if (face_neigh_pt == edge_neigh_pt)
3299 in_neighbouring_tree);
3302 if (face_neigh_pt != 0)
3304 if (face_neigh_pt == edge_neigh_pt)
3316 std::ostringstream error_stream;
3317 error_stream <<
"Never get here! Edge:" <<
Direct_string[edge] <<
" "
3318 << edge << std::endl;
3320 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3379 bool& in_neighbouring_tree)
const
3381 using namespace OcTreeNames;
3384 if ((direction !=
L) && (direction !=
R) && (direction !=
F) &&
3385 (direction !=
B) && (direction !=
U) && (direction !=
D))
3387 std::ostringstream error_stream;
3388 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
3391 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3397 in_neighbouring_tree =
false;
3401 int max_level =
Level;
3407 double s_difflo = 0;
3408 double s_diffhi = 0;
3418 in_neighbouring_tree,
3422 OcTree* neighb_pt = return_pt;
3425 for (
unsigned i = 0;
i < 3;
i++)
3441 s_sw[0] =
S_base(0, reflected_dir) +
3442 S_steplo(0, reflected_dir) * s_difflo +
3443 S_stephi(0, reflected_dir) * s_diffhi;
3445 s_sw[1] =
S_base(1, reflected_dir) +
3446 S_steplo(1, reflected_dir) * s_difflo +
3447 S_stephi(1, reflected_dir) * s_diffhi;
3449 s_sw[2] =
S_base(2, reflected_dir) +
3450 S_steplo(2, reflected_dir) * s_difflo +
3451 S_stephi(2, reflected_dir) * s_diffhi;
3453 s_ne[0] =
S_base(0, reflected_dir) +
3454 S_steplo(0, reflected_dir) * pow(2.0, diff_level) +
3455 S_steplo(0, reflected_dir) * s_difflo +
3456 S_stephi(0, reflected_dir) * pow(2.0, diff_level) +
3457 S_stephi(0, reflected_dir) * s_diffhi;
3459 s_ne[1] =
S_base(1, reflected_dir) +
3460 S_steplo(1, reflected_dir) * pow(2.0, diff_level) +
3461 S_steplo(1, reflected_dir) * s_difflo +
3462 S_stephi(1, reflected_dir) * pow(2.0, diff_level) +
3463 S_stephi(1, reflected_dir) * s_diffhi;
3465 s_ne[2] =
S_base(2, reflected_dir) +
3466 S_steplo(2, reflected_dir) * pow(2.0, diff_level) +
3467 S_steplo(2, reflected_dir) * s_difflo +
3468 S_stephi(2, reflected_dir) * pow(2.0, diff_level) +
3469 S_stephi(2, reflected_dir) * s_diffhi;
3473 int new_dir = direction;
3523 for (
int i = 0;
i < 3;
i++)
3525 Mat_rot(
i, 0) = vect1[
i];
3526 Mat_rot(
i, 1) = vect2[
i];
3527 Mat_rot(
i, 2) = vect3[
i];
3534 for (
unsigned i = 0;
i < 3;
i++)
3538 translate_s_new[
i] = 0;
3539 for (
unsigned k = 0; k < 3; k++)
3541 s_ne_new[
i] += Mat_rot(
i, k) * s_ne[k];
3542 s_sw_new[
i] += Mat_rot(
i, k) * s_sw[k];
3543 translate_s_new[
i] += Mat_rot(
i, k) * translate_s[k];
3551 for (
unsigned i = 0;
i < 3;
i++)
3554 translate_s[
i] = std::abs(translate_s_new[
i]);
3619 const int& direction,
3620 const unsigned& i_root_edge_neighbour,
3621 unsigned& nroot_edge_neighbour,
3626 int& diff_level)
const
3628 using namespace OcTreeNames;
3631 if ((direction !=
LB) && (direction !=
RB) && (direction !=
DB) &&
3632 (direction !=
UB) && (direction !=
LD) && (direction !=
RD) &&
3633 (direction !=
LU) && (direction !=
RU) && (direction !=
LF) &&
3634 (direction !=
RF) && (direction !=
DF) && (direction !=
UF))
3636 std::ostringstream error_stream;
3637 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
3640 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3646 int max_level =
Level;
3659 i_root_edge_neighbour,
3660 nroot_edge_neighbour,
3673 OcTree* neighb_pt = return_pt;
3676 for (
unsigned i = 0;
i < 3;
i++)
3702 S_step_edge(0, reflected_dir) * pow(2.0, diff_level) +
3706 S_step_edge(1, reflected_dir) * pow(2.0, diff_level) +
3710 S_step_edge(2, reflected_dir) * pow(2.0, diff_level) +
3715 int new_dir = direction;
3729 new_dir =
rotate(new_up, new_right, direction);
3770 for (
int i = 0;
i < 3;
i++)
3772 Mat_rot(
i, 0) = vect1[
i];
3773 Mat_rot(
i, 1) = vect2[
i];
3774 Mat_rot(
i, 2) = vect3[
i];
3781 for (
unsigned i = 0;
i < 3;
i++)
3785 translate_s_new[
i] = 0;
3786 for (
unsigned k = 0; k < 3; k++)
3788 s_hi_new[
i] += Mat_rot(
i, k) * s_hi[k];
3789 s_lo_new[
i] += Mat_rot(
i, k) * s_lo[k];
3790 translate_s_new[
i] += Mat_rot(
i, k) * translate_s[k];
3798 for (
unsigned i = 0;
i < 3;
i++)
3801 translate_s[
i] = std::abs(translate_s_new[
i]);
3843 bool& in_neighbouring_tree,
3847 using namespace OcTreeNames;
3850 if ((direction !=
L) && (direction !=
R) && (direction !=
F) &&
3851 (direction !=
B) && (direction !=
U) && (direction !=
D))
3853 std::ostringstream error_stream;
3855 <<
" is not L, R, B, F, D or U." << std::endl;
3857 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3866 in_neighbouring_tree =
false;
3885 in_neighbouring_tree,
3910 if (next_el_pt != 0)
3916 if ((next_el_pt->
Son_pt.size() == 0) ||
3917 (next_el_pt->
Level > max_level - 1))
3919 return_el_pt = next_el_pt;
3931 if (orig_root_pt != next_el_pt->
Root_pt)
3937 son_octant =
rotate(my_up, my_right, son_octant);
3940 return_el_pt =
dynamic_cast<OcTree*
>(next_el_pt->
Son_pt[son_octant]);
3966 in_neighbouring_tree =
true;
3979 return return_el_pt;
4016 const unsigned& i_root_edge_neighbour,
4017 unsigned& nroot_edge_neighbour,
4023 using namespace OcTreeNames;
4027 if ((direction !=
LB) && (direction !=
RB) && (direction !=
DB) &&
4028 (direction !=
UB) && (direction !=
LD) && (direction !=
RD) &&
4029 (direction !=
LU) && (direction !=
RU) && (direction !=
LF) &&
4030 (direction !=
RF) && (direction !=
DF) && (direction !=
UF))
4032 std::ostringstream error_stream;
4033 error_stream <<
"Wrong direction: " <<
Direct_string[direction]
4036 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
4042 nroot_edge_neighbour = 0;
4045 OcTree* return_el_pt = 0;
4061 i_root_edge_neighbour,
4062 nroot_edge_neighbour,
4077 bool in_neighbouring_tree =
false;
4080 double s_difflo = 0.0;
4081 double s_diffhi = 0.0;
4082 int diff_level_edge = 0;
4089 in_neighbouring_tree,
4112 if (next_el_pt != 0)
4118 if ((next_el_pt->
Son_pt.size() == 0) ||
4119 (next_el_pt->
Level > max_level - 1))
4121 return_el_pt = next_el_pt;
4133 if (orig_root_pt != next_el_pt->
Root_pt)
4139 son_octant =
rotate(my_up, my_right, son_octant);
4142 return_el_pt =
dynamic_cast<OcTree*
>(next_el_pt->
Son_pt[son_octant]);
4165 nroot_edge_neighbour =
4173 unsigned n_neigh = edge_neighbour_pt.size();
4180 dynamic_cast<OcTree*
>(edge_neighbour_pt[i_root_edge_neighbour]);
4188 return return_el_pt;
4208 unsigned long num_nodes = all_nodes_pt.size();
4210 for (
unsigned long i = 0;
i < num_nodes;
i++)
4212 all_nodes_pt[
i]->object_pt()->set_number(++count);
4216 std::ofstream neighbours_file;
4217 std::ofstream no_true_edge_file;
4218 std::ofstream neighbours_txt_file;
4220 double max_error_face = 0.0;
4222 all_nodes_pt, neighbours_file, neighbours_txt_file, max_error_face);
4224 double max_error_edge = 0.0;
4228 neighbours_txt_file,
4230 bool failed =
false;
4234 <<
"\n \n Failed self_test() for OcTree because of faces: Max. error "
4235 << max_error_face << std::endl
4243 <<
"\n \n Failed self_test() for OcTree because of edges: Max. error "
4244 << max_error_edge << std::endl
4249 double max_error = max_error_face;
4250 if (max_error_edge > max_error) max_error = max_error_edge;
4258 oomph_info <<
"Passed self_test() for OcTree: Max. error " << max_error
4276 std::ofstream& neighbours_file,
4277 std::ofstream& neighbours_txt_file,
4280 using namespace OcTreeNames;
4284 bool in_neighbouring_tree;
4302 unsigned long num_nodes = forest_nodes_pt.size();
4304 for (
unsigned long i = 0;
i < num_nodes;
i++)
4313 if (neighbours_file.is_open())
4315 neighbours_file <<
"#---------------------------------" << std::endl;
4316 neighbours_file <<
"#The element itself: " <<
i << std::endl;
4317 neighbours_file <<
"#---------------------------------" << std::endl;
4319 ->output_corners(neighbours_file,
"BLACK");
4324 for (
int direction =
L; direction <=
F; direction++)
4336 in_neighbouring_tree);
4342 if (neighbours_txt_file.is_open())
4348 << diff_level <<
". Inside the neighbour the face is "
4353 if (neighbours_file.is_open())
4355 neighbours_file <<
"#---------------------------------"
4359 <<
"\n#---------------------------------" << std::endl;
4361 ->output_corners(neighbours_file,
Colour[direction]);
4367 if (neighbours_file.is_open())
4369 neighbours_file <<
"ZONE I=2 C=" <<
Colour[direction]
4392 bool is_periodic =
false;
4393 if (in_neighbouring_tree)
4401 if (is_periodic ==
false)
4403 error = sqrt(pow(x_small[0] - x_large[0], 2) +
4404 pow(x_small[1] - x_large[1], 2) +
4405 pow(x_small[2] - x_large[2], 2));
4408 if (neighbours_txt_file.is_open())
4410 neighbours_txt_file <<
"Error (1) " << error << std::endl;
4413 if (std::fabs(error) > max_error)
4415 max_error = std::fabs(error);
4420 std::ofstream mismatch_file;
4424 mismatch_file.open(
"mismatch.dat");
4425 mismatch_file <<
"ZONE" << std::endl;
4426 mismatch_file << x_large[0] <<
" " << x_large[1] <<
" "
4427 << x_large[2] <<
" 2 \n";
4428 mismatch_file << x_small[0] <<
" " << x_small[1] <<
" "
4429 << x_small[2] <<
" 3 \n";
4432 if (neighbours_file.is_open())
4434 neighbours_file <<
"#SOUTH WEST: " << std::endl;
4435 neighbours_file << x_large[0] <<
" " << x_large[1] <<
" "
4436 << x_large[2] <<
" 40 \n";
4460 if (is_periodic ==
false)
4462 error = sqrt(pow(x_small[0] - x_large[0], 2) +
4463 pow(x_small[1] - x_large[1], 2) +
4464 pow(x_small[2] - x_large[2], 2));
4468 if (neighbours_file.is_open())
4470 neighbours_file <<
"#NORTH EAST: " << std::endl;
4471 neighbours_file << x_large[0] <<
" " << x_large[1] <<
" "
4472 << x_large[2] <<
" 80 \n";
4475 if (neighbours_txt_file.is_open())
4477 neighbours_txt_file <<
"Error (2) " << error << std::endl;
4480 if (std::fabs(error) > max_error)
4482 max_error = std::fabs(error);
4492 if (!mismatch_file.is_open())
4494 mismatch_file.open(
"mismatch.dat");
4496 mismatch_file <<
"ZONE" << std::endl;
4497 mismatch_file << x_large[0] <<
" " << x_large[1] <<
" "
4498 << x_large[2] <<
" 2 " << std::fabs(error)
4500 mismatch_file << x_small[0] <<
" " << x_small[1] <<
" "
4501 << x_small[2] <<
" 3 " << std::fabs(error)
4503 mismatch_file.close();
4512 if (neighbours_file.is_open())
4515 <<
"#---------------------------------\n"
4516 <<
"# No neighbour in direction: " <<
Direct_string[direction]
4518 <<
"#---------------------------------" << std::endl;
4521 ->output_corners(neighbours_file,
"WHITE");
4522 neighbours_file <<
"ZONE I=2 \n";
4523 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4524 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4528 if (neighbours_file.is_open())
4530 neighbours_file << std::endl << std::endl << std::endl;
4553 std::ofstream& neighbours_file,
4554 std::ofstream& no_true_edge_file,
4555 std::ofstream& neighbours_txt_file,
4558 using namespace OcTreeNames;
4579 unsigned long num_nodes = forest_nodes_pt.size();
4581 for (
unsigned long i = 0;
i < num_nodes;
i++)
4590 if (neighbours_file.is_open())
4592 neighbours_file <<
"#---------------------------------" << std::endl;
4593 neighbours_file <<
"# The element itself: " <<
i << std::endl;
4594 neighbours_file <<
"#---------------------------------" << std::endl;
4596 ->output_corners(neighbours_file,
"BLACK");
4601 for (
int direction =
LB; direction <=
UF; direction++)
4607 unsigned i_root_edge_neighbour = 0;
4608 unsigned nroot_edge_neighbour = 0;
4613 i_root_edge_neighbour,
4614 nroot_edge_neighbour,
4625 if (neighbours_txt_file.is_open())
4631 << diff_level <<
". Inside the neighbour the edge is "
4636 if (neighbours_file.is_open())
4639 <<
"#---------------------------------"
4641 <<
"\n#---------------------------------" << std::endl;
4643 ->output_corners(neighbours_file,
Colour[direction]);
4649 if (neighbours_file.is_open())
4651 neighbours_file <<
"ZONE I=2 C=" <<
Colour[direction]
4673 bool is_periodic =
false;
4680 unsigned n_faces_attached_to_edge = faces_attached_to_edge.size();
4683 for (
unsigned i_face = 0; i_face < n_faces_attached_to_edge;
4688 faces_attached_to_edge[i_face]);
4701 if (is_periodic ==
false)
4703 error = sqrt(pow(x_small[0] - x_large[0], 2) +
4704 pow(x_small[1] - x_large[1], 2) +
4705 pow(x_small[2] - x_large[2], 2));
4708 if (std::fabs(error) > max_error)
4710 max_error = std::fabs(error);
4713 if (neighbours_txt_file.is_open())
4715 neighbours_txt_file <<
"Error (1) " << error << std::endl;
4720 std::ofstream mismatch_file;
4724 mismatch_file.open(
"mismatch.dat");
4725 mismatch_file <<
"ZONE" << std::endl;
4726 mismatch_file << x_large[0] <<
" " << x_large[1] <<
" "
4727 << x_large[2] <<
" 2 \n";
4728 mismatch_file << x_small[0] <<
" " << x_small[1] <<
" "
4729 << x_small[2] <<
" 3 \n";
4732 if (neighbours_file.is_open())
4734 neighbours_file <<
"# LOW VERTEX: " << std::endl;
4735 neighbours_file << x_large[0] <<
" " << x_large[1] <<
" "
4736 << x_large[2] <<
" 40 \n";
4755 if (neighbours_file.is_open())
4757 neighbours_file <<
"# HI VERTEX: " << std::endl;
4758 neighbours_file << x_large[0] <<
" " << x_large[1] <<
" "
4759 << x_large[2] <<
" 80 \n";
4766 if (is_periodic ==
false)
4768 error = sqrt(pow(x_small[0] - x_large[0], 2) +
4769 pow(x_small[1] - x_large[1], 2) +
4770 pow(x_small[2] - x_large[2], 2));
4773 if (neighbours_txt_file.is_open())
4775 neighbours_txt_file <<
"Error (2) " << error << std::endl;
4778 if (std::fabs(error) > max_error)
4780 max_error = std::fabs(error);
4790 if (!mismatch_file.is_open())
4792 mismatch_file.open(
"mismatch.dat");
4794 mismatch_file <<
"ZONE" << std::endl;
4795 mismatch_file << x_large[0] <<
" " << x_large[1] <<
" "
4796 << x_large[2] <<
" 2 \n";
4797 mismatch_file << x_small[0] <<
" " << x_small[1] <<
" "
4798 << x_small[2] <<
" 3 \n";
4799 mismatch_file.close();
4808 if (neighbours_file.is_open())
4810 neighbours_file <<
"#---------------------------------"
4813 <<
"# No neighbour in direction: " <<
Direct_string[direction]
4815 neighbours_file <<
"#---------------------------------"
4819 ->output_corners(neighbours_file,
"WHITE");
4820 neighbours_file <<
"ZONE I=2 \n";
4821 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4822 neighbours_file <<
"-0.05 -0.05 -0.05 0 \n";
4843 no_true_edge_file <<
"ZONE I=2" << std::endl;
4844 no_true_edge_file << x_start[0] <<
" " << x_start[1] <<
" "
4845 << x_start[2] <<
" " << std::endl;
4846 no_true_edge_file << x_end[0] <<
" " << x_end[1] <<
" "
4847 << x_end[2] <<
" " << std::endl;
4851 if (neighbours_file.is_open())
4853 neighbours_file << std::endl << std::endl << std::endl;
4882 if (trees_pt.size() == 0)
4887 using namespace OcTreeNames;
4915 using namespace OcTreeNames;
4916 unsigned numtrees =
ntree();
4920 n =
Trees_pt[0]->object_pt()->nnode_1d();
4925 "Trying to setup the neighbour scheme for an empty forest",
4926 OOMPH_CURRENT_FUNCTION,
4927 OOMPH_EXCEPTION_LOCATION);
4932 unsigned n_vertex_node = 8;
4936 std::map<Node*, std::set<unsigned>> tree_assoc_with_vertex_node;
4939 for (
unsigned i = 0;
i < numtrees;
i++)
4942 for (
unsigned j = 0; j < n_vertex_node; j++)
4945 ->vertex_node_pt(j);
4946 tree_assoc_with_vertex_node[nod_pt].insert(
i);
4956 for (std::map<
Node*, std::set<unsigned>>::iterator it =
4957 tree_assoc_with_vertex_node.begin();
4958 it != tree_assoc_with_vertex_node.end();
4962 for (std::set<unsigned>::iterator it_el1 = it->second.begin();
4963 it_el1 != it->second.end();
4966 unsigned i = (*it_el1);
4967 for (std::set<unsigned>::iterator it_el2 = it->second.begin();
4968 it_el2 != it->second.end();
4971 unsigned j = (*it_el2);
4975 potentially_neighb_tree[
i].insert(j);
4983 for (
unsigned i = 0;
i < numtrees;
i++)
4989 for (std::set<unsigned>::iterator it = potentially_neighb_tree[
i].begin();
4990 it != potentially_neighb_tree[
i].end();
4997 bool is_face_neighbour =
false;
5000 bool is_Up_neighbour =
5001 ((
Trees_pt[j]->object_pt()->get_node_number(
5002 Trees_pt[
i]->object_pt()->node_pt(n * (n * n - 1))) != -1) &&
5003 (
Trees_pt[j]->object_pt()->get_node_number(
5004 Trees_pt[
i]->object_pt()->node_pt(n * n - 1)) != -1));
5007 bool is_Down_neighbour =
5008 ((
Trees_pt[j]->object_pt()->get_node_number(
5009 Trees_pt[
i]->object_pt()->node_pt(n * n * (n - 1))) != -1) &&
5010 (
Trees_pt[j]->object_pt()->get_node_number(
5011 Trees_pt[
i]->object_pt()->node_pt(n - 1)) != -1));
5014 bool is_Right_neighbour =
5015 ((
Trees_pt[j]->object_pt()->get_node_number(
5016 Trees_pt[
i]->object_pt()->node_pt(n * n * n - 1)) != -1) &&
5017 (
Trees_pt[j]->object_pt()->get_node_number(
5018 Trees_pt[
i]->object_pt()->node_pt(n - 1)) != -1));
5021 bool is_Left_neighbour =
5022 ((
Trees_pt[j]->object_pt()->get_node_number(
5023 Trees_pt[
i]->object_pt()->node_pt(n * (n * n - 1))) != -1) &&
5024 (
Trees_pt[j]->object_pt()->get_node_number(
5025 Trees_pt[
i]->object_pt()->node_pt(0)) != -1));
5028 bool is_Back_neighbour =
5029 ((
Trees_pt[j]->object_pt()->get_node_number(
5030 Trees_pt[
i]->object_pt()->node_pt(n * n - 1)) != -1) &&
5031 (
Trees_pt[j]->object_pt()->get_node_number(
5032 Trees_pt[
i]->object_pt()->node_pt(0)) != -1));
5035 bool is_Front_neighbour =
5036 ((
Trees_pt[j]->object_pt()->get_node_number(
5037 Trees_pt[
i]->object_pt()->node_pt(n * n * n - 1)) != -1) &&
5038 (
Trees_pt[j]->object_pt()->get_node_number(
5039 Trees_pt[
i]->object_pt()->node_pt(n * n * (n - 1))) != -1));
5042 if (is_Down_neighbour)
5044 is_face_neighbour =
true;
5047 if (is_Up_neighbour)
5049 is_face_neighbour =
true;
5052 if (is_Right_neighbour)
5054 is_face_neighbour =
true;
5057 if (is_Left_neighbour)
5059 is_face_neighbour =
true;
5062 if (is_Back_neighbour)
5064 is_face_neighbour =
true;
5067 if (is_Front_neighbour)
5069 is_face_neighbour =
true;
5079 if (!is_face_neighbour)
5082 bool is_left_back_neighbour =
5083 ((
Trees_pt[j]->object_pt()->get_node_number(
5084 Trees_pt[
i]->object_pt()->node_pt(0)) != -1) &&
5085 (
Trees_pt[j]->object_pt()->get_node_number(
5086 Trees_pt[
i]->object_pt()->node_pt(n * (n - 1))) != -1));
5089 bool is_right_back_neighbour =
5090 ((
Trees_pt[j]->object_pt()->get_node_number(
5091 Trees_pt[
i]->object_pt()->node_pt(n - 1)) != -1) &&
5092 (
Trees_pt[j]->object_pt()->get_node_number(
5093 Trees_pt[
i]->object_pt()->node_pt(n * n - 1)) != -1));
5097 bool is_down_back_neighbour =
5098 ((
Trees_pt[j]->object_pt()->get_node_number(
5099 Trees_pt[
i]->object_pt()->node_pt(n - 1)) != -1) &&
5100 (
Trees_pt[j]->object_pt()->get_node_number(
5101 Trees_pt[
i]->object_pt()->node_pt(0)) != -1));
5104 bool is_up_back_neighbour =
5105 ((
Trees_pt[j]->object_pt()->get_node_number(
5106 Trees_pt[
i]->object_pt()->node_pt(n * (n - 1))) != -1) &&
5107 (
Trees_pt[j]->object_pt()->get_node_number(
5108 Trees_pt[
i]->object_pt()->node_pt(n * n - 1)) != -1));
5112 bool is_left_down_neighbour =
5113 ((
Trees_pt[j]->object_pt()->get_node_number(
5114 Trees_pt[
i]->object_pt()->node_pt(n * n * (n - 1))) != -1) &&
5115 (
Trees_pt[j]->object_pt()->get_node_number(
5116 Trees_pt[
i]->object_pt()->node_pt(0)) != -1));
5120 bool is_right_down_neighbour =
5121 ((
Trees_pt[j]->object_pt()->get_node_number(
5122 Trees_pt[
i]->object_pt()->node_pt((n * n + 1) * (n - 1))) !=
5124 (
Trees_pt[j]->object_pt()->get_node_number(
5125 Trees_pt[
i]->object_pt()->node_pt(n - 1)) != -1));
5129 bool is_left_up_neighbour =
5130 ((
Trees_pt[j]->object_pt()->get_node_number(
5131 Trees_pt[
i]->object_pt()->node_pt((n * n * n - n))) != -1) &&
5132 (
Trees_pt[j]->object_pt()->get_node_number(
5133 Trees_pt[
i]->object_pt()->node_pt(n * (n - 1))) != -1));
5137 bool is_right_up_neighbour =
5138 ((
Trees_pt[j]->object_pt()->get_node_number(
5139 Trees_pt[
i]->object_pt()->node_pt((n * n * n - 1))) != -1) &&
5140 (
Trees_pt[j]->object_pt()->get_node_number(
5141 Trees_pt[
i]->object_pt()->node_pt(n * n - 1)) != -1));
5145 bool is_left_front_neighbour =
5146 ((
Trees_pt[j]->object_pt()->get_node_number(
5147 Trees_pt[
i]->object_pt()->node_pt((n * n * n - n))) != -1) &&
5148 (
Trees_pt[j]->object_pt()->get_node_number(
5149 Trees_pt[
i]->object_pt()->node_pt(n * n * (n - 1))) != -1));
5153 bool is_right_front_neighbour =
5154 ((
Trees_pt[j]->object_pt()->get_node_number(
5155 Trees_pt[
i]->object_pt()->node_pt((n * n * n - 1))) != -1) &&
5156 (
Trees_pt[j]->object_pt()->get_node_number(
5157 Trees_pt[
i]->object_pt()->node_pt((n * n + 1) * (n - 1))) !=
5162 bool is_down_front_neighbour =
5163 ((
Trees_pt[j]->object_pt()->get_node_number(
5164 Trees_pt[
i]->object_pt()->node_pt(n * n * (n - 1))) != -1) &&
5165 (
Trees_pt[j]->object_pt()->get_node_number(
5166 Trees_pt[
i]->object_pt()->node_pt((n * n + 1) * (n - 1))) !=
5171 bool is_up_front_neighbour =
5172 ((
Trees_pt[j]->object_pt()->get_node_number(
5173 Trees_pt[
i]->object_pt()->node_pt((n * n * n - n))) != -1) &&
5174 (
Trees_pt[j]->object_pt()->get_node_number(
5175 Trees_pt[
i]->object_pt()->node_pt((n * n * n - 1))) != -1));
5180 if (is_left_back_neighbour)
5185 if (is_right_back_neighbour)
5190 if (is_down_back_neighbour)
5195 if (is_up_back_neighbour)
5202 if (is_left_down_neighbour)
5207 if (is_right_down_neighbour)
5212 if (is_left_up_neighbour)
5217 if (is_right_up_neighbour)
5224 if (is_left_front_neighbour)
5229 if (is_right_front_neighbour)
5234 if (is_down_front_neighbour)
5239 if (is_up_front_neighbour)
5257 using namespace OcTreeNames;
5260 unsigned numtrees =
ntree();
5266 nnode1d =
Trees_pt[0]->object_pt()->nnode_1d();
5273 for (
unsigned i = 0;
i < numtrees;
i++)
5302 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d * nnode1d -
5305 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d - 1));
5316 std::ostringstream error_stream;
5317 error_stream <<
"Tree " <<
i
5318 <<
"'s Up neighbour has no neighbour pointer to Tree "
5322 OOMPH_CURRENT_FUNCTION,
5323 OOMPH_EXCEPTION_LOCATION);
5354 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d * nnode1d -
5357 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d - 1));
5368 std::ostringstream error_stream;
5369 error_stream <<
"Tree " <<
i
5370 <<
"'s Right neighbour has no neighbour pointer to Tree "
5374 OOMPH_CURRENT_FUNCTION,
5375 OOMPH_EXCEPTION_LOCATION);
5405 octree_pt(
i)->object_pt()->node_pt(nnode1d - 1));
5407 octree_pt(
i)->object_pt()->node_pt((nnode1d * nnode1d + 1) *
5419 std::ostringstream error_stream;
5420 error_stream <<
"Tree " <<
i
5421 <<
"'s Down neighbour has no neighbour pointer to Tree "
5425 OOMPH_CURRENT_FUNCTION,
5426 OOMPH_EXCEPTION_LOCATION);
5456 octree_pt(
i)->object_pt()->node_pt((nnode1d - 1) * nnode1d));
5458 octree_pt(
i)->object_pt()->node_pt((nnode1d * nnode1d - 1) *
5470 std::ostringstream error_stream;
5471 error_stream <<
"Tree " <<
i
5472 <<
"'s Left neighbour has no neighbour pointer to Tree "
5476 OOMPH_CURRENT_FUNCTION,
5477 OOMPH_EXCEPTION_LOCATION);
5501 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d * nnode1d -
5504 octree_pt(
i)->object_pt()->node_pt((nnode1d * nnode1d - 1) *
5519 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d * nnode1d -
5522 octree_pt(
i)->object_pt()->node_pt((nnode1d * nnode1d + 1) *
5534 std::ostringstream error_stream;
5535 error_stream <<
"Tree " <<
i
5536 <<
"'s Front neighbour has no neighbour pointer to Tree "
5540 OOMPH_CURRENT_FUNCTION,
5541 OOMPH_EXCEPTION_LOCATION);
5565 octree_pt(
i)->object_pt()->node_pt((nnode1d - 1) * nnode1d));
5567 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d - 1));
5581 octree_pt(
i)->object_pt()->node_pt(nnode1d * nnode1d - 1));
5583 octree_pt(
i)->object_pt()->node_pt(nnode1d - 1));
5594 std::ostringstream error_stream;
5595 error_stream <<
"Tree " <<
i
5596 <<
"'s Back neighbour has no neighbour pointer to Tree "
5600 OOMPH_CURRENT_FUNCTION,
5601 OOMPH_EXCEPTION_LOCATION);
5610 for (
int edge =
LB; edge <=
UF; edge++)
5616 unsigned n_neigh = edge_neigh_pt.size();
5617 for (
unsigned e = 0;
e < n_neigh;
e++)
5620 if (edge_neigh_pt[
e] != 0)
5635 unsigned neighb_nod1 =
5636 edge_neigh_pt[
e]->object_pt()->get_node_number(
5639 unsigned neighb_nod2 =
5640 edge_neigh_pt[
e]->object_pt()->get_node_number(
5646 int neighb_other_vertex =
5655 std::make_pair(neighb_vertex, vertex),
5656 std::make_pair(neighb_other_vertex, other_vertex))]
5665 std::make_pair(neighb_vertex, vertex),
5666 std::make_pair(neighb_other_vertex, other_vertex))]
5685 unsigned long num_nodes = all_nodes_pt.size();
5686 for (
unsigned long i = 0;
i < num_nodes;
i++)
5688 all_nodes_pt[
i]->object_pt()->set_number(++count);
5692 std::ofstream neighbours_file;
5693 std::ofstream no_true_edge_file;
5694 std::ofstream neighbours_txt_file;
5696 double max_error_face = 0.0;
5698 all_nodes_pt, neighbours_file, neighbours_txt_file, max_error_face);
5700 double max_error_edge = 0.0;
5704 neighbours_txt_file,
5707 bool failed =
false;
5710 oomph_info <<
"\n\n Failed self_test() for OcTreeForest because of "
5711 "faces: Max. error "
5712 << max_error_face << std::endl
5719 oomph_info <<
"\n\n Failed self_test() for OcTreeForest because of "
5720 "edges: Max. error "
5721 << max_error_edge << std::endl
5726 double max_error = max_error_face;
5727 if (max_error_edge > max_error) max_error = max_error_edge;
5735 oomph_info <<
"\nPassed self_test() for OcTreeForest: Max. error "
5736 << max_error << std::endl;
5759 std::ofstream neigh_file;
5760 std::ofstream neigh_txt_file;
5764 std::ostringstream fullname;
5765 fullname << doc_info.
directory() <<
"/neighbours" << doc_info.
number()
5767 oomph_info <<
"opened " << fullname.str() <<
" to doc neighbours"
5769 neigh_file.open(fullname.str().c_str());
5771 fullname << doc_info.
directory() <<
"/neighbours" << doc_info.
number()
5773 oomph_info <<
"opened " << fullname.str() <<
" to doc neighbours"
5775 neigh_txt_file.open(fullname.str().c_str());
5779 double max_error = 0.0;
5781 all_tree_nodes_pt, neigh_file, neigh_txt_file, max_error);
5784 std::ostringstream error_stream;
5785 error_stream <<
"\nMax. error in octree neighbour finding: "
5786 << max_error <<
" is too big" << std::endl;
5788 <<
"i.e. bigger than Tree::max_neighbour_finding_tolerance()="
5795 neigh_txt_file.close();
5799 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5803 oomph_info <<
"\nMax. error in octree neighbour finding: " << max_error
5804 <<
" is OK" << std::endl;
5806 <<
"i.e. less than OcTree::max_neighbour_finding_tolerance()="
5814 neigh_txt_file.close();
5822 std::ofstream neigh_file;
5823 std::ofstream no_true_edge_file;
5824 std::ofstream neigh_txt_file;
5828 std::ostringstream fullname;
5829 fullname << doc_info.
directory() <<
"/edge_neighbours"
5830 << doc_info.
number() <<
".dat";
5831 neigh_file.open(fullname.str().c_str());
5833 fullname << doc_info.
directory() <<
"/no_true_edge" << doc_info.
number()
5835 no_true_edge_file.open(fullname.str().c_str());
5837 fullname << doc_info.
directory() <<
"/edge_neighbours"
5838 << doc_info.
number() <<
".txt";
5839 neigh_txt_file.open(fullname.str().c_str());
5843 double max_error = 0.0;
5852 std::ostringstream error_stream;
5853 error_stream <<
"Max. error in octree edge neighbour finding: "
5854 << max_error <<
" is too big" << std::endl;
5856 <<
"i.e. bigger than Tree::max_neighbour_finding_tolerance()="
5863 no_true_edge_file.close();
5864 neigh_txt_file.close();
5868 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
5872 oomph_info <<
"Max. error in octree edge neighbour finding: "
5873 << max_error <<
" is OK" << std::endl;
5875 <<
"i.e. less than OcTree::max_neighbour_finding_tolerance()="
5883 no_true_edge_file.close();
5884 neigh_txt_file.close();
5898 for (
unsigned i = 0;
i < 6;
i++)
5900 output_stream.push_back(
new std::ofstream);
5906 std::ostringstream fullname;
5907 fullname << doc_info.
directory() <<
"/hang_nodes_u" << doc_info.
number()
5909 output_stream[0]->open(fullname.str().c_str());
5911 fullname << doc_info.
directory() <<
"/hang_nodes_d" << doc_info.
number()
5913 output_stream[1]->open(fullname.str().c_str());
5915 fullname << doc_info.
directory() <<
"/hang_nodes_l" << doc_info.
number()
5917 output_stream[2]->open(fullname.str().c_str());
5919 fullname << doc_info.
directory() <<
"/hang_nodes_r" << doc_info.
number()
5921 output_stream[3]->open(fullname.str().c_str());
5923 fullname << doc_info.
directory() <<
"/hang_nodes_b" << doc_info.
number()
5925 output_stream[4]->open(fullname.str().c_str());
5927 fullname << doc_info.
directory() <<
"/hang_nodes_f" << doc_info.
number()
5929 output_stream[5]->open(fullname.str().c_str());
static int num_elem(char *strv, unsigned elem_len, int term_char, int num_term) static int num_elem(strv
Base class for all brick elements.
void resize(const unsigned long &n)
Resize to a square nxn matrix; any values already present will be transfered.
Information for documentation of results: Directory and file number to enable output in the form RESL...
bool is_doc_enabled() const
Are we documenting?
std::string directory() const
Output directory.
unsigned & number()
Number used (e.g.) for labeling output files.
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...
int get_node_number(Node *const &node_pt) const
Return the number of the node *node_pt if this node is in the element, else return -1;.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
OcTreeForest()
Default constructor (empty and broken)
void find_neighbours()
Construct the neighbour scheme.
void open_hanging_node_files(DocInfo &doc_info, Vector< std::ofstream * > &output_stream)
Open output files that will store any hanging nodes in the forest and return a vector of the streams.
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 ...
void construct_up_right_equivalents()
Construct the rotation schemes.
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...
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...
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).
unsigned self_test()
Self-test: Check all neighbours. Return success (0) if the max. distance between corresponding points...
OcTreeRoot is a OcTree that forms the root of a (recursive) octree. The "root node" is special as it ...
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...
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/....
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 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 un...
int up_equivalent(TreeRoot *tree_root_pt)
Return up equivalent of the neighbours specified by pointer: When viewed from the current octree's ne...
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...
OcTree class: Recursively defined, generalised octree.
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 Vector< std::string > Colour
Colours for neighbours in various directions.
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/...
static DenseMatrix< double > S_directhi
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
static DenseMatrix< bool > Is_adjacent
Array of direction/octant adjacency scheme: Is_adjacent(direction,octant): Is face/edge direction adj...
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 > faces_of_common_edge(const int &edge)
Function that, given an edge, returns the two faces on which it.
static Vector< std::string > Direct_string
Translate (enumerated) directions into strings.
static DenseMatrix< double > S_directlo
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
static int node_number_to_vertex(const unsigned &n, const unsigned &nnode1d)
Return the vertex [LDB,RDB,...] of local (vertex) node n in an element with nnode1d nodes in each coo...
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 DenseMatrix< int > Common_face
Determine common face of edges or octants. Slightly bizarre lookup scheme from Samet's book.
static Vector< int > Reflect_face
Get opposite face, e.g. Reflect_face[L]=R.
static Vector< int > Sini
Entry in rotation matrix sin(i*90)
static void setup_static_data()
Setup the static data, rotation and reflection schemes, etc.
unsigned self_test()
Self-test: Check all neighbours. Return success (0) if the max. distance between corresponding points...
OcTree * gteq_face_neighbour(const int &direction, Vector< unsigned > &translate_s, Vector< double > &s_sw, Vector< double > &s_ne, int &face, int &diff_level, bool &in_neighbouring_tree) const
Find (pointer to) ‘greater-or-equal-sized face neighbour’ in given direction (L/R/U/D/F/B)....
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 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....
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:
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< int > Cosi
Entry in rotation matrix: cos(i*90)
static DenseMatrix< int > Reflect
Reflection scheme: Reflect(direction,octant): Get mirror of octant/edge in specified direction....
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,...
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...
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],...
static DenseMatrix< double > S_direct_edge
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
static Vector< int > Reflect_vertex
Get opposite vertex, e.g. Reflect_vertex[LDB]=RUF.
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...
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.
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 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< 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 Vector< int > Reflect_edge
Get opposite edge, e.g. Reflect_edge[DB]=UF.
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),...
static DenseMatrix< double > S_steplo
Each face of the RefineableQElement<3> that is represented by the octree is parametrised by two (of t...
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...
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....
An OomphLibError object which should be thrown when an run-time error is encountered....
long number() const
Element number (for debugging/plotting)
virtual bool nodes_built()
Return true if all the nodes have been built, false if not.
Refineable version of QElement<3,NNODE_1D>.
A TreeForest consists of a collection of TreeRoots. Each member tree can have neighbours in various e...
void stick_all_tree_nodes_into_vector(Vector< Tree * > &all_forest_nodes)
Traverse forest and stick pointers to all "nodes" into Vector.
unsigned ntree()
Number of trees in forest.
Vector< TreeRoot * > Trees_pt
Vector containing the pointers to the trees.
bool is_neighbour_periodic(const int &direction)
Return whether the neighbour in the particular direction is periodic.
TreeRoot *& neighbour_pt(const int &direction)
Return the pointer to the neighbouring TreeRoots in specified direction. Returns NULL if there's no n...
Tree * Father_pt
Pointer to the Father of the Tree.
void stick_all_tree_nodes_into_vector(Vector< Tree * > &)
Traverse and stick pointers to all "nodes" into Vector.
RefineableElement * object_pt() const
Return the pointer to the object (RefineableElement) represented by the tree.
TreeRoot * Root_pt
Pointer to the root of the tree.
bool is_leaf()
Return true if the tree is a leaf node.
int Son_type
Son type (e.g. SW/SE/NW/NE in a quadtree)
int Level
Level of the Tree (level 0 = root)
static const int OMEGA
Default value for an unassigned neighbour.
Vector< Tree * > Son_pt
Vector of pointers to the sons of the Tree.
TreeRoot *& root_pt()
Return pointer to root of the tree.
static double Max_neighbour_finding_tolerance
Max. allowed discrepancy in neighbour finding routine (distance between points when identified from t...
static double & max_neighbour_finding_tolerance()
Max. allowed discrepancy in neighbour finding routine (distance between points when identified from t...
double angle(const Vector< double > &a, const Vector< double > &b)
Get the angle between two vector.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
void pause(std::string message)
Pause and display message.
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...