oomph::QuadTreeForest Class Reference

#include <quadtree.h>

+ Inheritance diagram for oomph::QuadTreeForest:

Public Member Functions

 QuadTreeForest ()
 Default constructor (empty and broken) More...
 
 QuadTreeForest (Vector< TreeRoot * > &trees_pt)
 
 QuadTreeForest (const QuadTreeForest &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const QuadTreeForest &)=delete
 Broken assignment operator. More...
 
virtual ~QuadTreeForest ()
 
void check_all_neighbours (DocInfo &doc_info)
 
void open_hanging_node_files (DocInfo &doc_info, Vector< std::ofstream * > &output_stream)
 
unsigned self_test ()
 
- Public Member Functions inherited from oomph::TreeForest
 TreeForest (Vector< TreeRoot * > &trees_pt)
 
 TreeForest ()
 Default constructor (empty and broken) More...
 
 TreeForest (const TreeForest &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const TreeForest &)=delete
 Broken assignment operator. More...
 
virtual ~TreeForest ()
 Kill tree forest: Delete the constituent trees. More...
 
void stick_leaves_into_vector (Vector< Tree * > &forest_nodes)
 Traverse forst and stick pointers to leaf "nodes" into Vector. More...
 
void stick_all_tree_nodes_into_vector (Vector< Tree * > &all_forest_nodes)
 Traverse forest and stick pointers to all "nodes" into Vector. More...
 
void close_hanging_node_files (DocInfo &doc_info, Vector< std::ofstream * > &output_stream)
 
unsigned ntree ()
 Number of trees in forest. More...
 
TreeRoottree_pt (const unsigned &i) const
 Return pointer to i-th tree in forest. More...
 
void flush_trees ()
 Flush trees from forest. More...
 

Private Member Functions

void construct_north_equivalents ()
 Construct the rotation schemes. More...
 
void find_neighbours ()
 Construct the neighbour lookup scheme. More...
 
QuadTreeRootquadtree_pt (const unsigned &i)
 
QuadTreeRootquad_neigh_pt (const unsigned &i, const int &direction)
 

Additional Inherited Members

- Protected Attributes inherited from oomph::TreeForest
Vector< TreeRoot * > Trees_pt
 Vector containing the pointers to the trees. More...
 

Detailed Description

A QuadTreeForest consists of a collection of QuadTreeRoots. Each member tree can have neighbours to its S/W/N/E and the orientation of their compasses can differ, allowing for complex, unstructured meshes.

Constructor & Destructor Documentation

◆ QuadTreeForest() [1/3]

oomph::QuadTreeForest::QuadTreeForest ( )
inline

Default constructor (empty and broken)

413  {
414  // Throw an error
415  throw OomphLibError(
416  "Don't call an empty constructor for a QuadTreeForest object",
419  }
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ QuadTreeForest() [2/3]

oomph::QuadTreeForest::QuadTreeForest ( Vector< TreeRoot * > &  trees_pt)

Constructor: Pass vector of pointers to the roots of the constituent QuadTrees

Constructor for QuadTreeForest:

Pass:

  • trees_pt[], the Vector of pointers to the constituent trees (QuadTreeRoot objects)

Note that the pointers to the neighbour's of each tree must have been allocated before the constructor is called, otherwise the relative rotation scheme will not be constructed correctly.

864  : TreeForest(trees_pt)
865  {
866 #ifdef LEAK_CHECK
867  LeakCheckNames::QuadTreeForest_build += 1;
868 #endif
869 
870  // Don't setup neighbours etc. if forest is empty
871  if (trees_pt.size() == 0)
872  {
873  return;
874  }
875 
876  using namespace QuadTreeNames;
877 
878  // Setup the neighbours
879  find_neighbours();
880 
881  // Construct the rotation scheme, note that all neighbour pointers must
882  // be set before the constructor is called
884  }
void find_neighbours()
Construct the neighbour lookup scheme.
Definition: quadtree.cc:891
void construct_north_equivalents()
Construct the rotation schemes.
Definition: quadtree.cc:1067
TreeForest()
Default constructor (empty and broken)
Definition: tree.h:416

References construct_north_equivalents(), and find_neighbours().

◆ QuadTreeForest() [3/3]

oomph::QuadTreeForest::QuadTreeForest ( const QuadTreeForest dummy)
delete

Broken copy constructor.

◆ ~QuadTreeForest()

virtual oomph::QuadTreeForest::~QuadTreeForest ( )
inlinevirtual

Destructor: Delete the constituent quadtrees (and thus the objects associated with its non-leaf nodes!)

433 {}

Member Function Documentation

◆ check_all_neighbours()

void oomph::QuadTreeForest::check_all_neighbours ( DocInfo doc_info)
virtual

Document and check all the neighbours of all the nodes in the forest. DocInfo object specifies the output directory and file numbers for the various files. If doc_info.disable_doc() has been called no output is created.

Document and check all the neighbours in all the nodes in the forest

Implements oomph::TreeForest.

1246  {
1247  // Create Vector of elements
1248  Vector<Tree*> all_tree_nodes_pt;
1249  this->stick_all_tree_nodes_into_vector(all_tree_nodes_pt);
1250 
1251  // Create storage for information files
1252  std::ofstream neigh_file;
1253  std::ofstream neigh_txt_file;
1254 
1255  // If we are documenting the results, then open the files
1256  if (doc_info.is_doc_enabled())
1257  {
1258  std::ostringstream fullname;
1259  fullname << doc_info.directory() << "/neighbours" << doc_info.number()
1260  << ".dat";
1261  oomph_info << "opened " << fullname.str() << " to doc neighbours"
1262  << std::endl;
1263  neigh_file.open(fullname.str().c_str());
1264  fullname.str("");
1265  fullname << doc_info.directory() << "/neighbours" << doc_info.number()
1266  << ".txt";
1267  oomph_info << "opened " << fullname.str() << " to doc neighbours"
1268  << std::endl;
1269  neigh_txt_file.open(fullname.str().c_str());
1270  }
1271 
1272  // Call the standard documentation function
1273  double max_error = 0.0;
1275  all_tree_nodes_pt, neigh_file, neigh_txt_file, max_error);
1276 
1277  // If the error is too large complain
1279  {
1280  std::ostringstream error_stream;
1281  error_stream << "Max. error in quadtree neighbour finding: " << max_error
1282  << " is too big" << std::endl;
1283  error_stream
1284  << "i.e. bigger than Tree::max_neighbour_finding_tolerance()="
1285  << Tree::max_neighbour_finding_tolerance() << std::endl;
1286 
1287  // Close the files if they were opened
1288  if (doc_info.is_doc_enabled())
1289  {
1290  neigh_file.close();
1291  neigh_txt_file.close();
1292  }
1293 
1294  throw OomphLibError(
1295  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1296  }
1297  else
1298  {
1299  oomph_info << "Max. error in quadtree neighbour finding: " << max_error
1300  << " is OK" << std::endl;
1301  oomph_info
1302  << "i.e. less than QuadTree::max_neighbour_finding_tolerance()="
1304  }
1305 
1306  // Close the files if they were opened
1307  if (doc_info.is_doc_enabled())
1308  {
1309  neigh_file.close();
1310  neigh_txt_file.close();
1311  }
1312  }
static void doc_neighbours(Vector< Tree * > forest_nodes_pt, std::ofstream &neighbours_file, std::ofstream &neighbours_txt_file, double &max_error)
Definition: quadtree.cc:1402
void stick_all_tree_nodes_into_vector(Vector< Tree * > &all_forest_nodes)
Traverse forest and stick pointers to all "nodes" into Vector.
Definition: tree.cc:405
static double & max_neighbour_finding_tolerance()
Definition: tree.h:255
double max_error
Definition: MortaringCantileverCompareToNonMortaring.cpp:188
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References oomph::DocInfo::directory(), oomph::QuadTree::doc_neighbours(), oomph::DocInfo::is_doc_enabled(), MeshRefinement::max_error, oomph::Tree::max_neighbour_finding_tolerance(), oomph::DocInfo::number(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, and oomph::TreeForest::stick_all_tree_nodes_into_vector().

◆ construct_north_equivalents()

void oomph::QuadTreeForest::construct_north_equivalents ( )
private

Construct the rotation schemes.

Construct the rotation scheme for the quadtree forest. Note that all pointers to neighbours must have been allocated for this to work.

1068  {
1069  using namespace QuadTreeNames;
1070 
1071  unsigned numtrees = ntree();
1072  // Loop over all the trees
1073  for (unsigned i = 0; i < numtrees; i++)
1074  {
1075  // Find the pointer to the northern neighbour
1076  QuadTreeRoot* neigh_pt = quad_neigh_pt(i, N);
1077  // If there is a neighbour
1078  if (neigh_pt != 0)
1079  {
1080  // Find the direction of the present tree, as viewed from the neighbour
1081  int direction = neigh_pt->direction_of_neighbour(quadtree_pt(i));
1082 
1083  // Set up the rotation scheme
1084  switch (direction)
1085  {
1086  // If N neighbour has this tree on S, north equivalent is N
1087  case S:
1089  break;
1090  // If N neighbour has this tree on W, north equivalent is E
1091  case W:
1093  break;
1094  // If N neighbour has this tree on N, north equivalent is S
1095  case N:
1097  break;
1098  // If N neighbour has this tree on E, north equivalent is W
1099  case E:
1101  break;
1102  // If N neighbour does not have pointer to this tree, die
1103  default:
1104  std::ostringstream error_stream;
1105  error_stream
1106  << "Tree " << i
1107  << "'s Northern neighbour has no neighbour pointer to Tree " << i
1108  << std::endl;
1109 
1110  throw OomphLibError(error_stream.str(),
1113  }
1114  }
1115 
1116  // Find the pointer to the eastern neighbour
1117  neigh_pt = quad_neigh_pt(i, E);
1118  // If there is a neighbour
1119  if (neigh_pt != 0)
1120  {
1121  // Find the direction of the present tree, as viewed from the neighbour
1122  int direction = neigh_pt->direction_of_neighbour(quadtree_pt(i));
1123 
1124  // Set up the rotation scheme
1125  switch (direction)
1126  {
1127  // If E neighbour has this tree on W, north equivalent is N
1128  case W:
1130  break;
1131  // If E neighbour has this tree on N, north equivalent is E
1132  case N:
1134  break;
1135  // If E neighbour has this tree on E, north equivalent is S
1136  case E:
1138  break;
1139  // If E neighbour has this tree on S, north equivalent is W
1140  case S:
1142  break;
1143  // If E neighbour does not have pointer to this tree, die
1144  default:
1145  std::ostringstream error_stream;
1146  error_stream
1147  << "Tree " << i
1148  << "'s Eastern neighbour has no neighbour pointer to Tree " << i
1149  << std::endl;
1150 
1151  throw OomphLibError(error_stream.str(),
1154  }
1155  }
1156 
1157  // Find the pointer to the southern neighbour
1158  neigh_pt = quad_neigh_pt(i, S);
1159  // If there is a neighbour
1160  if (neigh_pt != 0)
1161  {
1162  // Find the direction of the present tree, as viewed from the neighbour
1163  int direction = neigh_pt->direction_of_neighbour(quadtree_pt(i));
1164 
1165  // Set up the rotation scheme
1166  switch (direction)
1167  {
1168  // If S neighbour has this tree on N, north equivalent is N
1169  case N:
1171  break;
1172  // If S neighbour has this tree on E, north equivalent is E
1173  case E:
1175  break;
1176  // If S neighbour has this tree on S, north equivalent is S
1177  case S:
1179  break;
1180  // If S neighbour has this tree on W, north equivalent is W
1181  case W:
1183  break;
1184  // If S neighbour does not have pointer to this tree, die
1185  default:
1186  std::ostringstream error_stream;
1187  error_stream
1188  << "Tree " << i
1189  << "'s Southern neighbour has no neighbour pointer to Tree " << i
1190  << std::endl;
1191 
1192  throw OomphLibError(error_stream.str(),
1195  }
1196  }
1197 
1198  // Find the pointer to the western neighbour
1199  neigh_pt = quad_neigh_pt(i, W);
1200  // If there is a neighbour
1201  if (neigh_pt != 0)
1202  {
1203  // Find the direction of the present tree, as viewed from the neighbour
1204  int direction = neigh_pt->direction_of_neighbour(quadtree_pt(i));
1205 
1206  // Set up the rotation scheme
1207  switch (direction)
1208  {
1209  // If W neighbour has this tree on E, north equivalent is N
1210  case E:
1212  break;
1213  // If W neighbour has this tree on S, north equivalent is E
1214  case S:
1216  break;
1217  // If W neighbour has this tree on W, north equivalent is S
1218  case W:
1220  break;
1221  // If W neighbour has this tree on N, north equivalent is W
1222  case N:
1224  break;
1225  // If W neighbour does not have pointer to this tree, die
1226  default:
1227  std::ostringstream error_stream;
1228  error_stream
1229  << "Tree " << i
1230  << "'s Western neighbour has no neighbour pointer to Tree " << i
1231  << std::endl;
1232 
1233  throw OomphLibError(error_stream.str(),
1236  }
1237  }
1238  }
1239  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
QuadTreeRoot * quadtree_pt(const unsigned &i)
Definition: quadtree.h:462
QuadTreeRoot * quad_neigh_pt(const unsigned &i, const int &direction)
Definition: quadtree.h:471
int & north_equivalent(const int &neighbour)
Definition: quadtree.h:354
unsigned ntree()
Number of trees in forest.
Definition: tree.h:460
@ N
Definition: constructor.cpp:22
double E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:68
@ S
Definition: quadtree.h:62
@ W
Definition: quadtree.h:63

References oomph::QuadTreeRoot::direction_of_neighbour(), Global_Physical_Variables::E, i, N, oomph::QuadTreeRoot::north_equivalent(), oomph::TreeForest::ntree(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, quad_neigh_pt(), quadtree_pt(), oomph::QuadTreeNames::S, and oomph::QuadTreeNames::W.

Referenced by QuadTreeForest().

◆ find_neighbours()

void oomph::QuadTreeForest::find_neighbours ( )
private

Construct the neighbour lookup scheme.

Setup the neighbour lookup schemes for all constituent quadtrees.

892  {
893  using namespace QuadTreeNames;
894 
895  unsigned numtrees = ntree();
896  unsigned n = 0; // to store nnode1d
897  if (numtrees > 0)
898  {
899  n = Trees_pt[0]->object_pt()->nnode_1d();
900  }
901  else
902  {
903  throw OomphLibError(
904  "Trying to setup the neighbour scheme for an empty forest\n",
907  }
908 
909  // Number of vertex nodes: 4
910  unsigned n_vertex_node = 4;
911 
912  // Find potentially connected trees by identifying
913  // those whose associated elements share a common vertex node
914  std::map<Node*, std::set<unsigned>> tree_assoc_with_vertex_node;
915 
916  // Loop over all trees
917  for (unsigned i = 0; i < numtrees; i++)
918  {
919  // Loop over the vertex nodes of the associated element
920  for (unsigned j = 0; j < n_vertex_node; j++)
921  {
922  Node* nod_pt = dynamic_cast<QuadElementBase*>(Trees_pt[i]->object_pt())
923  ->vertex_node_pt(j);
924  tree_assoc_with_vertex_node[nod_pt].insert(i);
925  }
926  }
927 
928 
929  // For each tree we store a set of potentially neighbouring trees
930  // i.e. trees that share at least one node
931  Vector<std::set<unsigned>> potentially_neighb_tree(numtrees);
932 
933  // Loop over vertex nodes
934  for (std::map<Node*, std::set<unsigned>>::iterator it =
935  tree_assoc_with_vertex_node.begin();
936  it != tree_assoc_with_vertex_node.end();
937  it++)
938  {
939  // Loop over connected elements twice
940  for (std::set<unsigned>::iterator it_el1 = it->second.begin();
941  it_el1 != it->second.end();
942  it_el1++)
943  {
944  unsigned i = (*it_el1);
945  for (std::set<unsigned>::iterator it_el2 = it->second.begin();
946  it_el2 != it->second.end();
947  it_el2++)
948  {
949  unsigned j = (*it_el2);
950  // These two elements are potentially connected
951  if (i != j)
952  {
953  potentially_neighb_tree[i].insert(j);
954  }
955  }
956  }
957  }
958 
959 
960  // Loop over all trees
961  for (unsigned i = 0; i < numtrees; i++)
962  {
963  // Loop over their potential neighbours
964  for (std::set<unsigned>::iterator it = potentially_neighb_tree[i].begin();
965  it != potentially_neighb_tree[i].end();
966  it++)
967  {
968  unsigned j = (*it);
969 
970  // is it the Northern neighbour ?
971  bool is_N_neighbour =
972  ((Trees_pt[j]->object_pt()->get_node_number(
973  Trees_pt[i]->object_pt()->node_pt(n * (n - 1))) != -1) &&
974  (Trees_pt[j]->object_pt()->get_node_number(
975  Trees_pt[i]->object_pt()->node_pt(n * n - 1)) != -1));
976 
977 
978  // is it the Southern neighbour ?
979  bool is_S_neighbour =
980  ((Trees_pt[j]->object_pt()->get_node_number(
981  Trees_pt[i]->object_pt()->node_pt(0)) != -1) &&
982  (Trees_pt[j]->object_pt()->get_node_number(
983  Trees_pt[i]->object_pt()->node_pt(n - 1)) != -1));
984 
985 
986  // is it the Eastern neighbour ?
987  bool is_E_neighbour =
988  ((Trees_pt[j]->object_pt()->get_node_number(
989  Trees_pt[i]->object_pt()->node_pt(n - 1)) != -1) &&
990  (Trees_pt[j]->object_pt()->get_node_number(
991  Trees_pt[i]->object_pt()->node_pt(n * n - 1)) != -1));
992 
993  // is it the Western neighbour ?
994  bool is_W_neighbour =
995  ((Trees_pt[j]->object_pt()->get_node_number(
996  Trees_pt[i]->object_pt()->node_pt(0)) != -1) &&
997  (Trees_pt[j]->object_pt()->get_node_number(
998  Trees_pt[i]->object_pt()->node_pt(n * (n - 1))) != -1));
999 
1000 
1001  if (is_N_neighbour) Trees_pt[i]->neighbour_pt(N) = Trees_pt[j];
1002  if (is_S_neighbour) Trees_pt[i]->neighbour_pt(S) = Trees_pt[j];
1003  if (is_E_neighbour) Trees_pt[i]->neighbour_pt(E) = Trees_pt[j];
1004  if (is_W_neighbour) Trees_pt[i]->neighbour_pt(W) = Trees_pt[j];
1005  }
1006  }
1007 
1008 
1009  // Old hacky version with horrendous scaling
1010  if (false)
1011  {
1012  // Loop over all trees
1013  for (unsigned i = 0; i < numtrees; i++)
1014  {
1015  // Loop over all the other elements
1016  for (unsigned j = 0; j < numtrees; j++)
1017  {
1018  if (j != i) // make sure we are not looking at the element itself
1019  {
1020  // is it the Northern neighbour ?
1021  bool is_N_neighbour =
1022  ((Trees_pt[j]->object_pt()->get_node_number(
1023  Trees_pt[i]->object_pt()->node_pt(n * (n - 1))) != -1) &&
1024  (Trees_pt[j]->object_pt()->get_node_number(
1025  Trees_pt[i]->object_pt()->node_pt(n * n - 1)) != -1));
1026 
1027 
1028  // is it the Southern neighbour ?
1029  bool is_S_neighbour =
1030  ((Trees_pt[j]->object_pt()->get_node_number(
1031  Trees_pt[i]->object_pt()->node_pt(0)) != -1) &&
1032  (Trees_pt[j]->object_pt()->get_node_number(
1033  Trees_pt[i]->object_pt()->node_pt(n - 1)) != -1));
1034 
1035 
1036  // is it the Eastern neighbour ?
1037  bool is_E_neighbour =
1038  ((Trees_pt[j]->object_pt()->get_node_number(
1039  Trees_pt[i]->object_pt()->node_pt(n - 1)) != -1) &&
1040  (Trees_pt[j]->object_pt()->get_node_number(
1041  Trees_pt[i]->object_pt()->node_pt(n * n - 1)) != -1));
1042 
1043  // is it the Western neighbour ?
1044  bool is_W_neighbour =
1045  ((Trees_pt[j]->object_pt()->get_node_number(
1046  Trees_pt[i]->object_pt()->node_pt(0)) != -1) &&
1047  (Trees_pt[j]->object_pt()->get_node_number(
1048  Trees_pt[i]->object_pt()->node_pt(n * (n - 1))) != -1));
1049 
1050 
1051  if (is_N_neighbour) Trees_pt[i]->neighbour_pt(N) = Trees_pt[j];
1052  if (is_S_neighbour) Trees_pt[i]->neighbour_pt(S) = Trees_pt[j];
1053  if (is_E_neighbour) Trees_pt[i]->neighbour_pt(E) = Trees_pt[j];
1054  if (is_W_neighbour) Trees_pt[i]->neighbour_pt(W) = Trees_pt[j];
1055  }
1056  }
1057  }
1058  }
1059  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Vector< TreeRoot * > Trees_pt
Vector containing the pointers to the trees.
Definition: tree.h:480
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References Global_Physical_Variables::E, i, j, n, N, oomph::TreeForest::ntree(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::QuadTreeNames::S, oomph::TreeForest::Trees_pt, and oomph::QuadTreeNames::W.

Referenced by QuadTreeForest().

◆ open_hanging_node_files()

void oomph::QuadTreeForest::open_hanging_node_files ( DocInfo doc_info,
Vector< std::ofstream * > &  output_stream 
)
virtual

Open output files that will store any hanging nodes in the forest and return a vector of the streams.

Open output files that will stored any hanging nodes that are

created in the mesh refinement process.

Implements oomph::TreeForest.

1320  {
1321  // In 2D, there will be four output files
1322  for (unsigned i = 0; i < 4; i++)
1323  {
1324  output_stream.push_back(new std::ofstream);
1325  }
1326 
1327  // If we are documenting the output, open the files
1328  if (doc_info.is_doc_enabled())
1329  {
1330  std::ostringstream fullname;
1331  fullname << doc_info.directory() << "/hang_nodes_s" << doc_info.number()
1332  << ".dat";
1333  output_stream[0]->open(fullname.str().c_str());
1334  fullname.str("");
1335  fullname << doc_info.directory() << "/hang_nodes_n" << doc_info.number()
1336  << ".dat";
1337  output_stream[1]->open(fullname.str().c_str());
1338  fullname.str("");
1339  fullname << doc_info.directory() << "/hang_nodes_w" << doc_info.number()
1340  << ".dat";
1341  output_stream[2]->open(fullname.str().c_str());
1342  fullname.str("");
1343  fullname << doc_info.directory() << "/hang_nodes_e" << doc_info.number()
1344  << ".dat";
1345  output_stream[3]->open(fullname.str().c_str());
1346  }
1347  }

References oomph::DocInfo::directory(), i, oomph::DocInfo::is_doc_enabled(), and oomph::DocInfo::number().

◆ operator=()

void oomph::QuadTreeForest::operator= ( const QuadTreeForest )
delete

Broken assignment operator.

◆ quad_neigh_pt()

QuadTreeRoot* oomph::QuadTreeForest::quad_neigh_pt ( const unsigned i,
const int direction 
)
inlineprivate

Given the number i of the root quadtree in this forest, return pointer to its neighbour in the specified direction. NULL if neighbour doesn't exist. (This does the dynamic cast from a TreeRoot to a QuadTreeRoot internally).

472  {
473  return dynamic_cast<QuadTreeRoot*>(Trees_pt[i]->neighbour_pt(direction));
474  }

References i.

Referenced by construct_north_equivalents().

◆ quadtree_pt()

QuadTreeRoot* oomph::QuadTreeForest::quadtree_pt ( const unsigned i)
inlineprivate

Return pointer to i-th root quadtree in this forest. (Performs a dynamic cast from the TreeRoot to a QuadTreeRoot).

463  {
464  return dynamic_cast<QuadTreeRoot*>(Trees_pt[i]);
465  }

References i.

Referenced by construct_north_equivalents().

◆ self_test()

unsigned oomph::QuadTreeForest::self_test ( )

Self-test: Check all neighbours. Return success (0) if the max. distance between corresponding points in the neighbours is less than the tolerance specified in the static value QuadTree::Max_neighbour_finding_tolerance.

Self test: Check neighbour finding routine. For each element in the tree and for each vertex, determine the distance between the vertex and its position in the neigbour. If the difference is less than Tree::Max_neighbour_finding_tolerance. return success (0), otherwise failure (1)

1358  {
1359  // Stick pointers to all nodes into Vector and number elements
1360  // in the process
1361  Vector<Tree*> all_forest_nodes_pt;
1362  stick_all_tree_nodes_into_vector(all_forest_nodes_pt);
1363  long int count = 0;
1364  unsigned long num_nodes = all_forest_nodes_pt.size();
1365  for (unsigned long i = 0; i < num_nodes; i++)
1366  {
1367  all_forest_nodes_pt[i]->object_pt()->set_number(++count);
1368  }
1369 
1370  // Check neighbours (distance between hanging nodes) -- don't print
1371  // (keep output streams closed)
1372  double max_error = 0.0;
1373  std::ofstream neighbours_file;
1374  std::ofstream neighbours_txt_file;
1376  all_forest_nodes_pt, neighbours_file, neighbours_txt_file, max_error);
1378  {
1379  oomph_info << "\n \n Failed self_test() for QuadTree: Max. error "
1380  << max_error << std::endl
1381  << std::endl;
1382  return 1;
1383  }
1384  else
1385  {
1386  oomph_info << "\n \n Passed self_test() for QuadTree: Max. error "
1387  << max_error << std::endl
1388  << std::endl;
1389  return 0;
1390  }
1391  }

References oomph::QuadTree::doc_neighbours(), i, MeshRefinement::max_error, oomph::Tree::max_neighbour_finding_tolerance(), oomph::oomph_info, and oomph::TreeForest::stick_all_tree_nodes_into_vector().


The documentation for this class was generated from the following files: