30 #ifndef OOMPH_OCTREE_HEADER 31 #define OOMPH_OCTREE_HEADER 35 #include <oomph-lib-config.h> 125 Tree*
const &father_pt,
const int &son_type)
127 OcTree* temp_oc_pt =
new OcTree(object_pt,father_pt,son_type);
173 OcTree* gteq_face_neighbour(
const int& direction,
178 int& diff_level)
const;
237 OcTree* gteq_true_edge_neighbour(
const int& direction,
238 const unsigned& i_root_edge_neighbour,
239 unsigned& nroot_edge_neighbour,
244 int& diff_level)
const;
254 static void setup_static_data();
264 static void doc_face_neighbours(
Vector<Tree*> forest_nodes_pt,
265 std::ofstream& neighbours_file,
266 std::ofstream& neighbours_txt_file,
277 static void doc_true_edge_neighbours(
Vector<Tree*> forest_nodes_pt,
278 std::ofstream& neighbours_file,
279 std::ofstream& no_true_edge_file,
280 std::ofstream& neighbours_txt_file,
288 static int get_the_other_face(
const unsigned& n1,
const unsigned& n2,
289 const unsigned& nnode1d,
const int& face);
294 static unsigned vertex_to_node_number(
const int& vertex,
295 const unsigned& nnode1d);
300 static int node_number_to_vertex(
const unsigned& n,
301 const unsigned& nnode1d);
306 static Vector<int> rotate(
const int& new_up,
const int& new_right,
312 static int rotate(
const int& new_up,
const int& new_right,
364 static std::map<std::pair<std::pair<int,int>,std::pair<int,int> >,
374 "Don't call empty constructor for OcTree!",
375 OOMPH_CURRENT_FUNCTION,
376 OOMPH_EXCEPTION_LOCATION);
395 Tree*
const &father_pt,
const int& son_type) :
396 Tree(object_pt,father_pt,son_type) {}
426 OcTree* gteq_face_neighbour(
const int& direction,
468 OcTree* gteq_edge_neighbour(
const int& direction,
469 const unsigned& i_root_edge_neighbour,
470 unsigned& nroot_edge_neighbour,
479 bool edge_neighbour_is_face_neighbour(
const int& edge,
480 OcTree* edge_neighb_pt)
const;
487 static void construct_rotation_matrix(
int& axis,
int&
angle,
504 static Vector<int> vertex_node_to_vector(
const unsigned& n,
505 const unsigned& nnode1d);
642 if (!Static_data_has_been_setup)
645 "Static member data hasn't been setup yet.\n";
647 "Call OcTree::setup_static_data() before creating\n";
648 error_message +=
"any OcTreeRoots\n";
651 OOMPH_CURRENT_FUNCTION,
652 OOMPH_EXCEPTION_LOCATION);
678 using namespace OcTreeNames;
679 if ((edge_direction!=
LB)&&(edge_direction!=
RB)&&(edge_direction!=
DB)&&
680 (edge_direction!=
UB)&&
681 (edge_direction!=
LD)&&(edge_direction!=
RD)&&(edge_direction!=
LU)&&
682 (edge_direction!=
RU)&&
683 (edge_direction!=
LF)&&(edge_direction!=
RF)&&(edge_direction!=
DF)&&
684 (edge_direction!=
UF))
686 std::ostringstream error_stream;
687 error_stream <<
"Wrong edge_direction: " << Direct_string[edge_direction]
690 OOMPH_CURRENT_FUNCTION,
691 OOMPH_EXCEPTION_LOCATION);
695 return Edge_neighbour_pt[edge_direction];
705 using namespace OcTreeNames;
706 if ((edge_direction!=
LB)&&(edge_direction!=
RB)&&(edge_direction!=
DB)&&
707 (edge_direction!=
UB)&&
708 (edge_direction!=
LD)&&(edge_direction!=
RD)&&(edge_direction!=
LU)&&
709 (edge_direction!=
RU)&&
710 (edge_direction!=
LF)&&(edge_direction!=
RF)&&(edge_direction!=
DF)&&
711 (edge_direction!=
UF))
713 std::ostringstream error_stream;
714 error_stream <<
"Wrong edge_direction: " << Direct_string[edge_direction]
717 OOMPH_CURRENT_FUNCTION,
718 OOMPH_EXCEPTION_LOCATION);
721 return Edge_neighbour_pt[edge_direction].size();
727 const unsigned& edge_direction)
731 using namespace OcTreeNames;
732 if ((edge_direction!=
LB)&&(edge_direction!=
RB)&&(edge_direction!=
DB)&&
733 (edge_direction!=
UB)&&
734 (edge_direction!=
LD)&&(edge_direction!=
RD)&&(edge_direction!=
LU)&&
735 (edge_direction!=
RU)&&
736 (edge_direction!=
LF)&&(edge_direction!=
RF)&&(edge_direction!=
DF)&&
737 (edge_direction!=
UF))
739 std::ostringstream error_stream;
740 error_stream <<
"Wrong edge_direction: " << Direct_string[edge_direction]
743 OOMPH_CURRENT_FUNCTION,
744 OOMPH_EXCEPTION_LOCATION);
749 find(Edge_neighbour_pt[edge_direction].begin(),
750 Edge_neighbour_pt[edge_direction].end(),
752 if (it==Edge_neighbour_pt[edge_direction].end())
754 Edge_neighbour_pt[edge_direction].push_back(oc_tree_root_pt);
771 if (direction_of_neighbour(tree_root_pt)==
OMEGA)
777 return Up_equivalent[tree_root_pt];
793 Up_equivalent[tree_root_pt]=dir;
804 if (direction_of_neighbour(tree_root_pt)==
OMEGA)
810 return Right_equivalent[tree_root_pt];
820 Right_equivalent[tree_root_pt]=dir;
828 using namespace OcTreeNames;
830 if(Neighbour_pt[
U]==octree_root_pt) {
return U;}
831 if(Neighbour_pt[
D]==octree_root_pt) {
return D;}
832 if(Neighbour_pt[
L]==octree_root_pt) {
return L;}
833 if(Neighbour_pt[
R]==octree_root_pt) {
return R;}
834 if(Neighbour_pt[
F]==octree_root_pt) {
return F;}
835 if(Neighbour_pt[
B]==octree_root_pt) {
return B;}
837 if(Neighbour_pt[
LB]==octree_root_pt) {
return LB;}
838 if(Neighbour_pt[
RB]==octree_root_pt) {
return RB;}
839 if(Neighbour_pt[
DB]==octree_root_pt) {
return DB;}
840 if(Neighbour_pt[
UB]==octree_root_pt) {
return UB;}
842 if(Neighbour_pt[
LD]==octree_root_pt) {
return LD;}
843 if(Neighbour_pt[
RD]==octree_root_pt) {
return RD;}
844 if(Neighbour_pt[
LU]==octree_root_pt) {
return LU;}
845 if(Neighbour_pt[
RU]==octree_root_pt) {
return RU;}
847 if(Neighbour_pt[
LF]==octree_root_pt) {
return LF;}
848 if(Neighbour_pt[
RF]==octree_root_pt) {
return RF;}
849 if(Neighbour_pt[
DF]==octree_root_pt) {
return DF;}
850 if(Neighbour_pt[
UF]==octree_root_pt) {
return UF;}
854 for (
int dir=
LB;dir<=
UF;dir++)
857 unsigned n_neigh=edge_neigh_pt.size();
858 for (
unsigned e=0;
e<n_neigh;
e++)
860 if (edge_neigh_pt[
e]==octree_root_pt)
899 throw OomphLibError(
"Don't call empty constructor for OcTreeForest!",
900 OOMPH_CURRENT_FUNCTION,
901 OOMPH_EXCEPTION_LOCATION);
926 void check_all_neighbours(
DocInfo &doc_info);
930 void open_hanging_node_files(
DocInfo &doc_info,
952 using namespace OcTreeNames;
953 if ((direction!=
U)&&(direction!=
D)&&
954 (direction!=
F)&&(direction!=
B)&&
955 (direction!=
L)&&(direction!=
R))
957 std::ostringstream error_stream;
958 error_stream <<
"Wrong edge_direction: " 962 OOMPH_CURRENT_FUNCTION,
963 OOMPH_EXCEPTION_LOCATION);
966 return dynamic_cast<OcTreeRoot*
>(Trees_pt[
i]->neighbour_pt(direction));
976 Trees_pt[
i])->edge_neighbour_pt(direction);
984 void construct_up_right_equivalents();
987 void find_neighbours();
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 Vector< int > Reflect_face
Get opposite face, e.g. Reflect_face[L]=R.
void operator=(const OcTreeRoot &)
Broken assignment operator.
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...
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
virtual ~OcTree()
Destructor. Note: Deleting a octree also deletes the objects associated with all non-leaf nodes! ...
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)...
Tree * construct_son(RefineableElement *const &object_pt, Tree *const &father_pt, const int &son_type)
Overload the function construct_son to ensure that the son is a specific OcTree and not a general Tre...
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.
Information for documentation of results: Directory and file number to enable output in the form RESL...
int up_equivalent(TreeRoot *tree_root_pt)
Return up equivalent of the neighbours specified by pointer: When viewed from the current octree's ne...
static DenseMatrix< double > S_steplo
Each face of the RefineableQElement<3> that is represented by the octree is parametrised by two (of t...
std::map< int, Vector< TreeRoot * > > Edge_neighbour_pt
Map of pointers to the edge-neighbouring [Oc]TreeRoots: Edge_neighbour_pt[direction] is Vector to the...
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...
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 nedge_neighbour(const unsigned &edge_direction)
Return number of edge-neighbouring OcTreeRoot in the (enumerated) (edge) direction.
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 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.
unsigned self_test()
Self-test: Return 0 for OK.
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.
static DenseMatrix< int > Reflect
Reflection scheme: Reflect(direction,octant): Get mirror of octant/edge in specified direction...
OcTreeRoot(const OcTreeRoot &dummy)
Broken copy constructor.
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...
OcTree()
Default constructor (empty and broken)
static DenseMatrix< double > S_directlo
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
OcTreeRoot(RefineableElement *const &object_pt)
Constructor for the root octree: Pass pointer to the RefineableQElement<3> that is represented by the...
static DenseMatrix< double > S_step_edge
Each edge of the RefineableQElement<3> that is represented by the octree is parametrised by one (of t...
OcTree(RefineableElement *const &object_pt)
Constructor for empty (root) tree: no father, no sons; just pass a pointer to its object (a Refineabl...
OcTree(const OcTree &dummy)
Broken copy constructor.
std::map< TreeRoot *, int > Right_equivalent
Map giving the Right equivalent of the neighbour specified by pointer: When viewed from the current o...
static Vector< std::string > Direct_string
Translate (enumerated) directions into strings.
OcTree(RefineableElement *const &object_pt, Tree *const &father_pt, const int &son_type)
Constructor for tree that has a father: Pass it the pointer to its object, the pointer to its father ...
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...
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 broken_assign(const std::string &class_name)
Issue error message and terminate execution.
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 ...
OcTreeForest(const OcTreeForest &dummy)
Broken copy constructor.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
std::map< TreeRoot *, int > Up_equivalent
Map giving the Up equivalent of the neighbour specified by pointer: When viewed from the current octr...
void operator=(const OcTree &)
Broken assignment operator.
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)
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/...
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< int > Common_face
Determine common face of edges or octants. Slightly bizarre lookup scheme from Samet's book...
static DenseMatrix< double > S_direct_edge
Relative to the left/down/back vertex in any (father) octree, the corresponding vertex in the son spe...
virtual ~OcTreeForest()
Destructor: Delete the constituent octrees (and thus the associated objects!)
static Vector< int > Sini
Entry in rotation matrix sin(i*90)
Vector< TreeRoot * > edge_neighbour_pt(const unsigned &edge_direction)
Return vector of pointers to the edge-neighbouring TreeRoots in the (enumerated) (edge) direction...
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 operator=(const OcTreeForest &)
Broken assignment operator.