58 unsigned max_level = 0;
59 unsigned nnodes = all_tree_nodes_pt.size();
60 for (
unsigned e = 0;
e < nnodes;
e++)
62 unsigned level = all_tree_nodes_pt[
e]->level();
63 if (level > max_level) max_level = level;
67 to_be_refined.clear();
68 to_be_refined.resize(max_level);
73 for (
unsigned l = 0; l < max_level; l++)
80 for (
unsigned l = 0; l < max_level; l++)
83 for (
unsigned e = 0;
e < nnodes;
e++)
86 unsigned level = all_tree_nodes_pt[
e]->level();
91 if ((level == l) || ((level < l) && (all_tree_nodes_pt[
e]->is_leaf())))
95 if ((level == l) && (!all_tree_nodes_pt[
e]->is_leaf()))
99 to_be_refined[l].push_back(el_count[l]);
121 unsigned nnodes = all_tree_nodes_pt.size();
122 for (
unsigned e = 0;
e < nnodes;
e++)
124 unsigned level = all_tree_nodes_pt[
e]->level();
125 if (level == refinement_level)
127 level_elements.push_back(
141 unsigned my_max, my_min;
145 unsigned my_max_level = to_be_refined.size();
147 unsigned global_max = 0;
148 unsigned global_max_level = 0;
151 data[1] = my_max_level;
156 MPI_Allreduce(&data[0],
162 global_max = global_data[0];
163 global_max_level = global_data[1];
169 global_max_level = my_max_level;
173 for (
unsigned i = 0;
i < global_max;
i++)
179 for (
unsigned l = 0; l < global_max_level; l++)
182 unsigned n_to_be_refined = 0;
183 if (l < my_max_level) n_to_be_refined = to_be_refined[l].size();
186 for (
unsigned i = 0;
i < n_to_be_refined;
i++)
189 ->select_for_refinement();
227 unsigned max_level = to_be_refined.size();
228 outfile << max_level <<
" # max. refinement level " << std::endl;
231 for (
unsigned l = 0; l < max_level; l++)
234 unsigned n_to_be_refined = to_be_refined[l].size();
235 outfile << n_to_be_refined <<
" # number of elements to be refined. "
236 <<
"What follows are the numbers of the elements. " << std::endl;
239 for (
unsigned i = 0;
i < n_to_be_refined;
i++)
241 outfile << to_be_refined[l][
i] << std::endl;
259 getline(restart_file, input_string,
'#');
262 restart_file.ignore(80,
'\n');
265 unsigned max_level = std::atoi(input_string.c_str());
268 to_be_refined.resize(max_level);
272 for (
unsigned l = 0; l < max_level; l++)
275 getline(restart_file, input_string,
'#');
278 restart_file.ignore(80,
'\n');
281 unsigned n_to_be_refined = atoi(input_string.c_str());
285 to_be_refined[l].resize(n_to_be_refined);
288 for (
unsigned i = 0;
i < n_to_be_refined;
i++)
290 restart_file >> to_be_refined[l][
i];
328 if (refine_tol <= unrefine_tol)
330 std::ostringstream error_stream;
331 error_stream <<
"Refinement tolerance <= Unrefinement tolerance"
332 << refine_tol <<
" " << unrefine_tol << std::endl
333 <<
"doesn't make sense and will almost certainly crash"
335 <<
"this beautiful code!" << std::endl;
338 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
350 std::map<RefineableElement*, bool> wants_to_be_unrefined;
353 unsigned n_refine = 0;
356 unsigned long Nelement = this->
nelement();
357 for (
unsigned long e = 0;
e < Nelement;
e++)
367 if (elemental_error[
e] > refine_tol)
387 if ((elemental_error[
e] < unrefine_tol) &&
391 bool unrefine =
true;
395 for (
unsigned ison = 0; ison < n_sons; ison++)
415 wants_to_be_unrefined[el_pt] =
true;
419 wants_to_be_unrefined[el_pt] =
false;
424 oomph_info <<
" \n Number of elements to be refined: " << n_refine
426 oomph_info <<
" \n Number of elements whose refinement was overruled: "
433 unsigned n_unrefine = 0;
434 for (
unsigned long e = 0;
e < Nelement;
e++)
450 bool unrefine =
true;
452 for (
unsigned ison = 0; ison < n_sons; ison++)
469 n_unrefine += n_sons;
481 oomph_info <<
" \n Number of elements to be merged : " << n_unrefine
501 unsigned total_n_refine = 0;
506 MPI_Allreduce(&n_refine,
515 total_n_refine = n_refine;
518 total_n_refine = n_refine;
529 unsigned total_n_unrefine = 0;
534 MPI_Allreduce(&n_unrefine,
543 total_n_unrefine = n_unrefine;
546 total_n_unrefine = n_unrefine;
549 oomph_info <<
"---> " << total_n_refine <<
" elements to be refined, and "
550 << total_n_unrefine <<
" to be unrefined, in total.\n"
567 int my_rank =
Comm_pt->my_rank();
573 for (
int d = 0; d < n_proc; d++)
584 unsigned nhalo = halo_elem_pt.size();
586 for (
unsigned e = 0;
e < nhalo;
e++)
589 ->sons_to_be_unrefined())
591 halo_to_be_unrefined[
e] = 1;
600 MPI_Send(&halo_to_be_unrefined[0],
613 for (
int dd = 0; dd < n_proc; dd++)
625 unsigned nhaloed = haloed_elem_pt.size();
631 MPI_Recv(&halo_to_be_unrefined[0],
641 for (
unsigned e = 0;
e < nhaloed;
e++)
643 if (((halo_to_be_unrefined[
e] == 0) &&
645 ->sons_to_be_unrefined())) ||
646 ((halo_to_be_unrefined[
e] == 1) &&
648 ->sons_to_be_unrefined())))
650 std::ostringstream error_message;
652 <<
"Error in unrefinement: \n"
653 <<
"Haloed element: " <<
e <<
" on proc " << my_rank
655 <<
"wants to be unrefined whereas its halo counterpart "
657 <<
"proc " << dd <<
" doesn't (or vice versa)...\n"
658 <<
"This is most likely because the error estimator\n"
659 <<
"has not assigned the same errors to halo and haloed\n"
660 <<
"elements -- it ought to!\n";
662 OOMPH_CURRENT_FUNCTION,
663 OOMPH_EXCEPTION_LOCATION);
676 for (
int d = 0; d < n_proc; d++)
687 unsigned nhalo = halo_elem_pt.size();
689 for (
unsigned e = 0;
e < nhalo;
e++)
694 halo_to_be_refined[
e] = 1;
703 MPI_Send(&halo_to_be_refined[0],
716 for (
int dd = 0; dd < n_proc; dd++)
728 unsigned nhaloed = haloed_elem_pt.size();
734 MPI_Recv(&halo_to_be_refined[0],
744 for (
unsigned e = 0;
e < nhaloed;
e++)
746 if (((halo_to_be_refined[
e] == 0) &&
748 ->to_be_refined())) ||
749 ((halo_to_be_refined[
e] == 1) &&
753 std::ostringstream error_message;
755 <<
"Error in refinement: \n"
756 <<
"Haloed element: " <<
e <<
" on proc " << my_rank
758 <<
"wants to be refined whereas its halo counterpart on\n"
759 <<
"proc " << dd <<
" doesn't (or vice versa)...\n"
760 <<
"This is most likely because the error estimator\n"
761 <<
"has not assigned the same errors to halo and haloed\n"
762 <<
"elements -- it ought to!\n";
764 OOMPH_CURRENT_FUNCTION,
765 OOMPH_EXCEPTION_LOCATION);
819 oomph_info <<
" Not enough benefit in adapting mesh." << std::endl
831 unsigned& min_refinement_level,
unsigned& max_refinement_level)
838 unsigned long n_element = this->
nelement();
846 for (
unsigned long e = 0;
e < n_element;
e++)
850 ->refinement_level();
940 Mesh* mesh_pt =
this;
942 double t_start = 0.0;
956 oomph_info <<
"Time for split_elements_if_required: " << t_end - t_start
971 oomph_info <<
"Time for stick_leaves_into_vector: " << t_end - t_start
977 std::ostringstream fullname;
978 std::ofstream new_nodes_file;
983 new_nodes_file.open(fullname.str().c_str());
991 bool was_already_built;
992 unsigned long num_tree_nodes = leaf_nodes_pt.size();
993 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
996 leaf_nodes_pt[
e]->object_pt()->pre_build(mesh_pt, new_node_pt);
998 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
1001 leaf_nodes_pt[
e]->object_pt()->build(
1002 mesh_pt, new_node_pt, was_already_built, new_nodes_file);
1010 oomph_info <<
"Time for building " << num_tree_nodes
1011 <<
" new elements: " << t_end - t_start << std::endl;
1018 new_nodes_file.close();
1043 const unsigned n_boundary = this->
nboundary();
1047 unsigned long n_node = this->
nnode();
1048 for (
unsigned long n = 0; n < n_node; n++)
1054 unsigned n_value = nod_pt->
nvalue();
1059 for (
unsigned n = 0; n < n_value; n++)
1075 unsigned n_dim = nod_pt->
ndim();
1078 for (
unsigned t = 0;
t < nt;
t++)
1080 nod_pt->
value(
t, values);
1081 for (
unsigned i = 0;
i < n_value;
i++)
1086 for (
unsigned i = 0;
i < n_dim;
i++)
1088 nod_pt->
x(
t,
i) = position[
i];
1094 if (alg_node_pt != 0)
1096 bool update_all_time_levels =
true;
1104 if (solid_node_pt != 0)
1106 unsigned n_lagrangian = solid_node_pt->
nlagrangian();
1107 for (
unsigned i = 0;
i < n_lagrangian;
i++)
1116 if ((mesh_dim > 2) && (nod_pt->
is_hanging()))
1123 std::set<unsigned>* boundaries_pt;
1125 if (boundaries_pt != 0)
1129 for (std::set<unsigned>::iterator it = boundaries_pt->begin();
1130 it != boundaries_pt->end();
1133 hanging_nodes_on_boundary_pt[*it].insert(nod_pt);
1149 oomph_info <<
"Time for sorting out initial hanging status: "
1150 << t_end - t_start << std::endl;
1169 oomph_info <<
"Time for unrefinement: " << t_end - t_start << std::endl;
1182 num_tree_nodes = tree_nodes_pt.size();
1184 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
1199 unsigned n_node = this_el_pt->
nnode();
1200 for (
unsigned n = 0; n < n_node; n++)
1210 oomph_info <<
"Time for adding elements to mesh: " << t_end - t_start
1229 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
1232 tree_nodes_pt[
e]->object_pt()->setup_hanging_nodes(
1233 hanging_output_files);
1235 tree_nodes_pt[
e]->object_pt()->further_setup_hanging_nodes();
1246 oomph_info <<
"Time for setup_hanging_nodes() and "
1247 "further_setup_hanging_nodes() for "
1248 << num_tree_nodes <<
" elements: " << t_end - t_start
1255 unsigned ncont_interpolated_values =
1256 tree_nodes_pt[0]->object_pt()->ncont_interpolated_values();
1265 oomph_info <<
"Time for complete_hanging_nodes: " << t_end - t_start
1282 oomph_info <<
"Time for boundary element info: " << t_end - t_start
1302 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
1304 double max_el_error;
1305 tree_nodes_pt[
e]->object_pt()->check_integrity(max_el_error);
1316 std::ostringstream error_stream;
1317 error_stream <<
"Mesh refined: Max. error in integrity check: "
1320 <<
"i.e. bigger than RefineableElement::max_integrity_tolerance()="
1324 std::ofstream some_file;
1325 some_file.open(
"ProblemMesh.dat");
1326 for (
unsigned long n = 0; n < n_node; n++)
1331 unsigned n_dim = nod_pt->
ndim();
1333 for (
unsigned i = 0;
i < n_dim;
i++)
1335 some_file << this->
node_pt(n)->
x(
i) <<
" ";
1337 some_file << std::endl;
1341 error_stream <<
"Doced problem mesh in ProblemMesh.dat" << std::endl;
1344 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1348 oomph_info <<
"Mesh refined: Max. error in integrity check: "
1351 <<
"i.e. less than RefineableElement::max_integrity_tolerance()="
1360 oomph_info <<
"Time for (paranoid only) checking of integrity: "
1361 << t_end - t_start << std::endl;
1384 oomph_info <<
"Time for deactivating objects and pruning nodes: "
1385 << t_end - t_start << std::endl;
1399 <<
" nodes: " << t_end - t_start << std::endl;
1409 for (
unsigned b = 0; b < n_boundary; b++)
1412 unsigned n_del = deleted_node_pt.size();
1413 for (
unsigned j = 0; j < n_del; j++)
1415 hanging_nodes_on_boundary_pt[b].erase(deleted_node_pt[j]);
1420 for (std::set<Node*>::iterator it =
1421 hanging_nodes_on_boundary_pt[b].begin();
1422 it != hanging_nodes_on_boundary_pt[b].end();)
1424 if ((*it)->is_hanging())
1426 hanging_nodes_on_boundary_pt[b].erase(it++);
1439 if (hanging_nodes_on_boundary_pt[b].size() > 0)
1443 for (
unsigned e = 0;
e < n_boundary_element; ++
e)
1455 if (solid_el_pt != 0)
1467 unsigned n_el_node = el_pt->
nnode();
1468 for (
unsigned n = 0; n < n_el_node; n++)
1475 std::set<Node*>::iterator it =
1476 hanging_nodes_on_boundary_pt[b].find(nod_pt);
1480 if (it != hanging_nodes_on_boundary_pt[b].end())
1490 const unsigned ntstorage = nod_pt->
ntstorage();
1511 for (
unsigned i = 0;
i < 3;
i++)
1513 solid_node_pt->
xi(
i) = xi[
i];
1520 for (
unsigned t = 0;
t < ntstorage;
t++)
1527 for (
unsigned i = 0;
i < 3;
i++)
1529 nod_pt->
x(
t,
i) = x[
i];
1535 hanging_nodes_on_boundary_pt[b].erase(it);
1538 if (hanging_nodes_on_boundary_pt[b].size() == 0)
1540 e = n_boundary_element;
1567 unsigned max_nval = 0;
1568 for (
unsigned n = 0; n < el_pt->
nnode(); n++)
1577 std::ofstream bcs_file;
1581 bcs_file.open(fullname.str().c_str());
1584 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
1586 el_pt = tree_nodes_pt[
e]->object_pt();
1588 unsigned n_nod = el_pt->
nnode();
1589 for (
unsigned n = 0; n < n_nod; n++)
1594 unsigned n_dim = nod_pt->
ndim();
1596 for (
unsigned i = 0;
i < n_dim;
i++)
1598 bcs_file << nod_pt->
x(
i) <<
" ";
1602 for (
unsigned i = 0;
i < max_nval;
i++)
1605 if (i < nod_pt->nvalue())
1615 bcs_file << std::endl;
1622 std::ofstream all_nodes_file;
1626 all_nodes_file.open(fullname.str().c_str());
1628 all_nodes_file <<
"ZONE \n";
1632 n_node = this->
nnode();
1633 for (
unsigned long n = 0; n < n_node; n++)
1636 unsigned n_dim = nod_pt->
ndim();
1637 for (
unsigned i = 0;
i < n_dim;
i++)
1639 all_nodes_file << this->
node_pt(n)->
x(
i) <<
" ";
1641 all_nodes_file << std::endl;
1644 all_nodes_file.close();
1649 std::ofstream some_file;
1653 some_file.open(fullname.str().c_str());
1654 for (
unsigned long n = 0; n < n_node; n++)
1660 unsigned n_dim = nod_pt->
ndim();
1661 for (
unsigned i = 0;
i < n_dim;
i++)
1663 some_file << nod_pt->
x(
i) <<
" ";
1667 if (this->
node_pt(n)->nvalue() > 0)
1669 some_file <<
" " << nod_pt->
raw_value(0);
1671 some_file << std::endl;
1681 some_file.open(fullname.str().c_str());
1682 for (
unsigned long n = 0; n < n_node; n++)
1687 unsigned n_dim = nod_pt->
ndim();
1689 some_file <<
"ZONE I=" << nmaster + 1 << std::endl;
1690 for (
unsigned i = 0;
i < n_dim;
i++)
1692 some_file << nod_pt->
x(
i) <<
" ";
1694 some_file <<
" 2 " << std::endl;
1696 for (
unsigned imaster = 0; imaster < nmaster; imaster++)
1698 Node* master_nod_pt =
1700 unsigned n_dim = master_nod_pt->
ndim();
1701 for (
unsigned i = 0;
i < n_dim;
i++)
1703 some_file << master_nod_pt->
x(
i) <<
" ";
1705 some_file <<
" 1 " << std::endl;
1713 for (
unsigned i = 0;
i < ncont_interpolated_values;
i++)
1717 <<
"/nonstandard_hangnodes_withmasters" <<
i <<
"_"
1719 some_file.open(fullname.str().c_str());
1720 unsigned n_nod = this->
nnode();
1721 for (
unsigned long n = 0; n < n_nod; n++)
1729 some_file <<
"ZONE I=" << nmaster + 1 << std::endl;
1730 unsigned n_dim = nod_pt->
ndim();
1731 for (
unsigned j = 0; j < n_dim; j++)
1733 some_file << nod_pt->
x(j) <<
" ";
1735 some_file <<
" 2 " << std::endl;
1736 for (
unsigned imaster = 0; imaster < nmaster; imaster++)
1738 Node* master_nod_pt =
1740 unsigned n_dim = master_nod_pt->
ndim();
1741 for (
unsigned j = 0; j < n_dim; j++)
1745 some_file <<
" 1 " << std::endl;
1756 #ifdef OOMPH_HAS_MPI
1775 unsigned long Nelement = this->
nelement();
1776 for (
unsigned long e = 0;
e < Nelement;
e++)
1779 ->select_for_refinement();
1793 unsigned long Nelement = this->
nelement();
1794 for (
unsigned long e = 0;
e < Nelement;
e++)
1819 #ifdef OOMPH_HAS_MPI
1822 std::ostringstream warn_stream;
1823 warn_stream <<
"You are attempting to refine selected elements of a "
1825 <<
"distributed mesh. This may have undesired effects."
1829 "TreeBasedRefineableMeshBase::refine_selected_elements()",
1830 OOMPH_EXCEPTION_LOCATION);
1835 unsigned long nref = elements_to_be_refined.size();
1836 for (
unsigned long e = 0;
e < nref;
e++)
1840 ->select_for_refinement();
1855 #ifdef OOMPH_HAS_MPI
1858 std::ostringstream warn_stream;
1859 warn_stream <<
"You are attempting to refine selected elements of a "
1861 <<
"distributed mesh. This may have undesired effects."
1865 "TreeBasedRefineableMeshBase::refine_selected_elements()",
1866 OOMPH_EXCEPTION_LOCATION);
1871 unsigned long nref = elements_to_be_refined_pt.size();
1872 for (
unsigned long e = 0;
e < nref;
e++)
1874 elements_to_be_refined_pt[
e]->select_for_refinement();
1917 unsigned nrefinement_levels = to_be_refined.size();
1921 if (nrefinement_levels == 0)
1930 to_be_refined.resize(nrefinement_levels - 1);
1950 oomph_info <<
"WARNING : This has not been checked comprehensively yet"
1952 <<
"Check it and remove this break " << std::endl;
1953 pause(
"Yes really pause");
1958 unsigned my_min, my_max;
1961 unsigned ref_min, ref_max;
1964 if (ref_max != my_max + 1)
1966 std::ostringstream error_stream;
1968 <<
"Meshes definitely don't differ by one refinement level \n"
1969 <<
"max. refinement levels: " << ref_max <<
" " << my_max << std::endl;
1972 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1981 std::map<Tree*, unsigned> father_element_included;
1990 unsigned nelem = leaf_nodes_pt.size();
1991 for (
unsigned e = 0;
e < nelem;
e++)
1994 Tree* leaf_pt = leaf_nodes_pt[
e];
2003 coarse_elements_pt.push_back(leaf_pt);
2009 bool can_unrefine =
true;
2010 unsigned n_sons = father_pt->
nsons();
2011 for (
unsigned i = 0;
i < n_sons;
i++)
2021 if (father_element_included[father_pt] == 0)
2023 coarse_elements_pt.push_back(father_pt);
2024 father_element_included[father_pt] = 1;
2030 coarse_elements_pt.push_back(leaf_pt);
2036 unsigned nel_coarse = coarse_elements_pt.size();
2040 bool stop_it =
false;
2042 if (nel_coarse != this->
nelement())
2044 oomph_info <<
"Number of elements in uniformly unrefined reference mesh: "
2045 << nel_coarse << std::endl;
2046 oomph_info <<
"Number of elements in 'this' mesh: " << nel_coarse
2058 for (
unsigned i = 0;
i < nel_coarse;
i++)
2060 if (father_element_included[coarse_elements_pt[
i]] == 1)
2062 elements_to_be_refined.push_back(
i);
2071 std::ofstream some_file;
2072 some_file.open(
"orig_mesh.dat");
2075 oomph_info <<
"Documented original ('this')mesh in orig_mesh.dat"
2089 double tol = 1.0e-5;
2090 for (
unsigned e = 0;
e < nelem;
e++)
2097 unsigned nnod = ref_el_pt->
nnode();
2098 for (
unsigned j = 0; j < nnod; j++)
2107 for (
unsigned i = 0;
i < ndim;
i++)
2109 error += pow(
node_pt->
x(
i) - ref_node_pt->
x(
i), 2);
2111 error = sqrt(error);
2115 oomph_info <<
"Error in nodal position of node " << j <<
": " << error
2116 <<
" [tol=" << tol <<
"]" << std::endl;
2126 std::ofstream some_file;
2127 some_file.open(
"refined_mesh.dat");
2131 some_file.open(
"finer_mesh.dat");
2132 ref_mesh_pt->
output(some_file);
2136 "Bailing out. Doced refined_mesh.dat finer_mesh.dat\n",
2137 OOMPH_CURRENT_FUNCTION,
2138 OOMPH_EXCEPTION_LOCATION);
2161 unsigned long Nelement = this->
nelement();
2176 for (
unsigned long e = 0;
e < Nelement;
e++)
2178 elemental_error[
e] = error;
2187 adapt(elemental_error);
2225 unsigned nmaster = hang_pt->
nmaster();
2227 for (
unsigned m = 0; m < nmaster; m++)
2237 int first_new_node = master_nodes.size();
2241 master_nod_pt, master_nodes, hang_weights,
i);
2245 unsigned n_new_master_node = master_nodes.size();
2249 for (
unsigned k = first_new_node; k < n_new_master_node; k++)
2251 hang_weights[k] = mtr_weight * hang_weights[k];
2258 master_nodes.push_back(nod_pt);
2259 hang_weights.push_back(1.0);
2272 const int& ncont_interpolated_values)
2275 unsigned long n_node = this->
nnode();
2276 double min_weight = 1.0e-8;
2279 for (
unsigned long n = 0; n < n_node; n++)
2286 for (
int i = -1;
i < ncont_interpolated_values;
i++)
2300 nod_pt, master_nodes, hanging_weights,
i);
2304 std::map<Node*, double> hang_weights;
2305 unsigned n_master = master_nodes.size();
2306 for (
unsigned k = 0; k < n_master; k++)
2308 if (std::fabs(hanging_weights[k]) > min_weight)
2309 hang_weights[master_nodes[k]] += hanging_weights[k];
2315 unsigned hang_weights_index = 0;
2317 typedef std::map<Node*, double>::iterator IT;
2318 for (IT it = hang_weights.begin(); it != hang_weights.end(); ++it)
2321 hang_weights_index, it->first, it->second);
2322 ++hang_weights_index;
2337 for (
int i = -1;
i < ncont_interpolated_values;
i++)
2340 for (
unsigned long n = 0; n < n_node; n++)
2350 for (
unsigned imaster = 0; imaster < nmaster; imaster++)
2354 if (std::fabs(sum - 1.0) > 1.0e-7)
2356 oomph_info <<
"WARNING: Sum of master node weights fabs(sum-1.0) "
2357 << std::fabs(sum - 1.0) <<
" for node number " << n
2358 <<
" at value " <<
i << std::endl;
2369 #ifdef OOMPH_HAS_MPI
2376 const unsigned& ncont_interpolated_values)
2380 int n_proc =
Comm_pt->nproc();
2381 int my_rank =
Comm_pt->my_rank();
2383 double t_start = 0.0;
2391 unsigned nnode_still_requiring_synchronisation = 0;
2399 int ncont_inter_values = ncont_interpolated_values;
2403 for (
int d = 0; d < n_proc; d++)
2411 for (
unsigned j = 0; j < nh; j++)
2418 for (
int icont = -1; icont < ncont_inter_values; icont++)
2424 haloed_hanging[d].push_back(n_master);
2428 haloed_hanging[d].push_back(0);
2434 unsigned count_haloed = haloed_hanging[d].size();
2439 MPI_Recv(&tmp, 1, MPI_UNSIGNED, d, 0,
Comm_pt->mpi_comm(), &status);
2440 if (tmp != count_haloed)
2442 std::ostringstream error_stream;
2443 error_stream <<
"Number of halo data, " << tmp
2444 <<
", does not match number of haloed data, "
2445 << count_haloed << std::endl;
2447 OOMPH_CURRENT_FUNCTION,
2448 OOMPH_EXCEPTION_LOCATION);
2453 if (count_haloed != 0)
2455 halo_hanging[d].resize(count_haloed);
2456 MPI_Recv(&halo_hanging[d][0],
2469 for (
int dd = 0; dd < n_proc; dd++)
2479 for (
unsigned j = 0; j < nh; j++)
2486 for (
int icont = -1; icont < ncont_inter_values; icont++)
2492 local_halo_hanging.push_back(n_master);
2496 local_halo_hanging.push_back(0);
2503 unsigned count_halo = local_halo_hanging.size();
2507 MPI_Send(&count_halo, 1, MPI_UNSIGNED, dd, 0,
Comm_pt->mpi_comm());
2511 if (count_halo != 0)
2513 MPI_Send(&local_halo_hanging[0],
2528 oomph_info <<
"Time for first all-to-all in synchronise_hanging_nodes(): "
2529 << t_end - t_start << std::endl;
2547 for (
int d = 0; d < n_proc; d++)
2550 for (
unsigned jj = 0; jj < n; jj++)
2560 for (
int d = 0; d < n_proc; d++)
2565 unsigned discrepancy_count = 0;
2566 unsigned discrepancy_count_buff = 0;
2582 unsigned discrepancy = 0;
2583 unsigned discrepancy_buff = 0;
2587 for (
unsigned j = 0; j < nh; j++)
2594 for (
int icont = -1; icont < ncont_inter_values; icont++)
2601 if ((haloed_hanging[d][count] > 0) &&
2602 (haloed_hanging[d][count] != halo_hanging[d][count]))
2604 discrepancy_buff = 1;
2605 discrepancy_count_buff++;
2608 bool found_all_masters =
true;
2612 unsigned nhd_master = hang_pt->
nmaster();
2615 send_data_buff.push_back(nhd_master);
2618 for (
unsigned m = 0; m < nhd_master; m++)
2668 std::map<Node*, unsigned>::iterator it =
2669 shared_node_map[d].find(master_nod_pt);
2673 if (it != shared_node_map[d].end())
2678 send_data_buff.push_back(my_rank);
2682 send_data_buff.push_back((*it).second);
2699 if (non_halo_proc_id < 0)
2712 if (shared_node_map[non_halo_proc_id].size() > 0)
2714 std::map<Node*, unsigned>::iterator it =
2715 shared_node_map[non_halo_proc_id].find(master_nod_pt);
2719 if (it != shared_node_map[non_halo_proc_id].end())
2725 send_data_buff.push_back(non_halo_proc_id);
2729 send_data_buff.push_back((*it).second);
2732 send_double_data_buff.push_back(
2950 found_all_masters =
false;
2960 if (found_all_masters)
2963 discrepancy = discrepancy_buff;
2964 discrepancy_count += discrepancy_count_buff;
2965 for (
unsigned i = 0;
i < send_data_buff.size();
i++)
2967 send_data.push_back(send_data_buff[
i]);
2969 for (
unsigned i = 0;
i < send_double_data_buff.size();
i++)
2971 send_double_data.push_back(send_double_data_buff[
i]);
2975 discrepancy_buff = 0;
2976 discrepancy_count_buff = 0;
2977 send_data_buff.clear();
2978 send_double_data_buff.clear();
2985 send_data.push_back(0);
2988 discrepancy_buff = 0;
2989 discrepancy_count_buff = 0;
2990 send_data_buff.clear();
2991 send_double_data_buff.clear();
2994 nnode_still_requiring_synchronisation++;
3000 else if ((haloed_hanging[d][count] == 0) &&
3001 (halo_hanging[d][count] > 0))
3004 discrepancy_count++;
3005 send_data.push_back(-1);
3009 else if (haloed_hanging[d][count] == halo_hanging[d][count])
3011 send_data.push_back(0);
3015 std::ostringstream error_stream;
3016 error_stream <<
"Never get here!\n "
3017 <<
"haloed_hanging[d][count]="
3018 << haloed_hanging[d][count]
3019 <<
"; halo_hanging[d][count]="
3020 << halo_hanging[d][count] << std::endl;
3022 OOMPH_CURRENT_FUNCTION,
3023 OOMPH_EXCEPTION_LOCATION);
3033 if (discrepancy == 0)
3035 MPI_Send(&n_all_send[0], 2, MPI_UNSIGNED, d, 0,
Comm_pt->mpi_comm());
3040 n_all_send[0] = send_data.size();
3041 n_all_send[1] = send_double_data.size();
3042 MPI_Send(&n_all_send[0], 2, MPI_UNSIGNED, d, 0,
Comm_pt->mpi_comm());
3045 if (n_all_send[0] != 0)
3048 &send_data[0], n_all_send[0], MPI_INT, d, 1,
Comm_pt->mpi_comm());
3052 if (n_all_send[1] != 0)
3054 MPI_Send(&send_double_data[0],
3067 for (
int dd = 0; dd < n_proc; dd++)
3075 MPI_Recv(&n_all_recv[0],
3088 if (n_all_recv[0] != 0)
3091 receive_data.resize(n_all_recv[0]);
3092 MPI_Recv(&receive_data[0],
3102 if (n_all_recv[1] != 0)
3105 receive_double_data.resize(n_all_recv[1]);
3106 MPI_Recv(&receive_double_data[0],
3116 if (n_all_recv[0] != 0)
3120 unsigned count_double = 0;
3124 for (
unsigned j = 0; j < nh; j++)
3131 for (
int icont = -1; icont < ncont_inter_values; icont++)
3134 int next_entry = receive_data[count++];
3140 unsigned nhd_master = unsigned(next_entry);
3146 for (
unsigned m = 0; m < nhd_master; m++)
3153 unsigned shared_node_proc =
3154 unsigned(receive_data[count++]);
3157 unsigned shared_node_id = unsigned(receive_data[count++]);
3160 double mtr_weight = receive_double_data[count_double++];
3164 if (shared_node_proc ==
unsigned(dd))
3167 Node* master_nod_pt =
3172 m, master_nod_pt, mtr_weight);
3194 hang_info.push_back(tmp);
3204 else if (next_entry < 0)
3221 oomph_info <<
"Time for second all-to-all in synchronise_hanging_nodes() "
3222 << t_end - t_start << std::endl;
3230 unsigned n = hang_info.size();
3233 unsigned global_n = 0;
3234 MPI_Allreduce(&n, &global_n, 1, MPI_UNSIGNED, MPI_MAX,
Comm_pt->mpi_comm());
3238 <<
"No need for reconciliation of wrongly synchronised hang nodes\n";
3243 oomph_info <<
"Need to reconcile of wrongly syncronised hang nodes\n";
3269 for (
int rank = 0; rank < n_proc; rank++)
3272 send_displacement[rank] = send_data.size();
3276 if (rank != my_rank)
3282 for (
unsigned i = 0;
i < n;
i++)
3297 hang_info_index_for_proc[rank].push_back(
i);
3303 send_n[rank] = send_data.size() - send_displacement[rank];
3311 MPI_Alltoall(&send_n[0],
3322 int receive_data_count = 0;
3323 for (
int rank = 0; rank < n_proc; ++rank)
3326 receive_displacement[rank] = receive_data_count;
3327 receive_data_count += receive_n[rank];
3332 if (receive_data_count == 0)
3334 ++receive_data_count;
3340 if (send_data.size() == 0)
3342 send_data.resize(1);
3346 MPI_Alltoallv(&send_data[0],
3348 &send_displacement[0],
3352 &receive_displacement[0],
3357 for (
int send_rank = 0; send_rank < n_proc; send_rank++)
3361 if ((send_rank != my_rank) && (receive_n[send_rank] != 0))
3364 unsigned count = receive_displacement[send_rank];
3367 unsigned n_rec = unsigned(receive_n[send_rank]);
3368 for (
unsigned i = 0;
i < n_rec / 2;
i++)
3371 unsigned orig_sending_proc = receive_data[count];
3377 unsigned shared_node_id_on_orig_sending_proc =
3378 receive_data[count];
3383 orig_sending_proc, shared_node_id_on_orig_sending_proc);
3388 std::map<Node*, unsigned>::iterator it =
3389 shared_node_map[send_rank].find(master_nod_pt);
3393 if (it != shared_node_map[send_rank].end())
3396 translated_entry[send_rank].push_back((*it).second);
3403 translated_entry[send_rank].push_back(-1);
3435 <<
"Time for third all-to-all in synchronise_hanging_nodes() "
3436 << t_end - t_start << std::endl;
3455 for (
int rank = 0; rank < n_proc; rank++)
3458 send_displacement[rank] = send_data.size();
3462 if (rank != my_rank)
3466 unsigned n = translated_entry[rank].size();
3467 for (
unsigned j = 0; j < n; j++)
3469 send_data.push_back(translated_entry[rank][j]);
3474 send_n[rank] = send_data.size() - send_displacement[rank];
3482 MPI_Alltoall(&send_n[0],
3493 int receive_data_count = 0;
3494 for (
int rank = 0; rank < n_proc; ++rank)
3497 receive_displacement[rank] = receive_data_count;
3498 receive_data_count += receive_n[rank];
3503 if (receive_data_count == 0)
3505 ++receive_data_count;
3511 if (send_data.size() == 0)
3513 send_data.resize(1);
3517 MPI_Alltoallv(&send_data[0],
3519 &send_displacement[0],
3523 &receive_displacement[0],
3528 for (
int send_rank = 0; send_rank < n_proc; send_rank++)
3532 if ((send_rank != my_rank) && (receive_n[send_rank] != 0))
3535 unsigned count = receive_displacement[send_rank];
3538 unsigned n_rec = unsigned(receive_n[send_rank]);
3539 for (
unsigned i = 0;
i < n_rec;
i++)
3544 int index = receive_data[count];
3551 unsigned hang_info_index =
3552 hang_info_index_for_proc[send_rank][
i];
3569 unsigned hang_info_index =
3570 hang_info_index_for_proc[send_rank][
i];
3580 nnode_still_requiring_synchronisation++;
3593 <<
"Time for fourth all-to-all in synchronise_hanging_nodes() "
3594 << t_end - t_start << std::endl;
3605 unsigned global_nnode_still_requiring_synchronisation = 0;
3606 MPI_Allreduce(&nnode_still_requiring_synchronisation,
3607 &global_nnode_still_requiring_synchronisation,
3612 if (global_nnode_still_requiring_synchronisation > 0)
3614 double tt_start = 0.0;
3620 oomph_info <<
"Need to do additional synchronisation of hanging nodes"
3626 double tt_end = 0.0;
3631 <<
"Time for RefineableMesh::additional_synchronise_hanging_nodes() "
3632 <<
"in TreeBasedRefineableMeshBase::synchronise_hanging_nodes(): "
3633 << tt_end - tt_start << std::endl;
3639 oomph_info <<
"No need to do additional synchronisation of hanging nodes"
3654 int n_proc =
Comm_pt->nproc();
3655 int my_rank =
Comm_pt->my_rank();
3657 double t_start = 0.0;
3672 for (
int d = 0; d < n_proc; d++)
3679 unsigned recv_unsigneds_count = 0;
3680 MPI_Recv(&recv_unsigneds_count,
3687 unsigned recv_doubles_count = 0;
3688 MPI_Recv(&recv_doubles_count,
3697 if (recv_unsigneds_count != 0)
3699 recv_unsigneds[d].resize(recv_unsigneds_count);
3700 MPI_Recv(&recv_unsigneds[d][0],
3701 recv_unsigneds_count,
3708 if (recv_doubles_count != 0)
3710 recv_doubles[d].resize(recv_doubles_count);
3711 MPI_Recv(&recv_doubles[d][0],
3721 unsigned recv_unsigneds_index = 0;
3722 double recv_doubles_index = 0;
3728 while (recv_unsigneds_index < recv_unsigneds_count)
3738 unsigned n_dim = el_pt->
dim();
3742 el_pt->
node_pt(recv_unsigneds[d][recv_unsigneds_index++]);
3746 for (
unsigned dir = 0; dir < n_dim; dir++)
3748 x_cur[dir] = nod_pt->
x(dir);
3753 for (
unsigned dir = 0; dir < n_dim; dir++)
3755 x_rec[dir] = recv_doubles[d][recv_doubles_index + dir];
3759 bool node_pos_differs =
false;
3760 for (
unsigned dir = 0; dir < n_dim; dir++)
3762 node_pos_differs = node_pos_differs ||
3763 (std::fabs(x_cur[dir] - x_rec[dir]) > 1.0e-14);
3768 for (
unsigned dir = 0; dir < n_dim; dir++)
3770 nod_pt->
x(dir) = recv_doubles[d][recv_doubles_index++];
3775 if (recv_unsigneds_count != recv_unsigneds_index)
3777 std::ostringstream error_stream;
3778 error_stream <<
"recv_unsigneds_count != recv_unsigneds_index ( "
3779 << recv_unsigneds_count <<
" != " << recv_unsigneds_index
3780 <<
")" << std::endl;
3783 "TreeBasedRefineableMeshBase::synchronise_nonhanging_nodes()",
3784 OOMPH_EXCEPTION_LOCATION);
3791 for (
int dd = 0; dd < n_proc; dd++)
3801 std::set<Node*> nodes_requiring_adjustment;
3809 for (
unsigned e = 0;
e < nh;
e++)
3819 unsigned n_dim = el_pt->
dim();
3822 unsigned n_node = el_pt->
nnode();
3823 for (
unsigned j = 0; j < n_node; j++)
3836 for (
unsigned t = 0;
t < nt;
t++)
3845 for (
unsigned dir = 0; dir < n_dim; dir++)
3847 x_act[dir] = nod_pt->
x(dir);
3851 bool node_pos_differs =
false;
3852 for (
unsigned dir = 0; dir < n_dim; dir++)
3856 (std::fabs(x_act[dir] - x_exp[dir]) > 1.0e-14);
3862 if (node_pos_differs)
3865 if (nodes_requiring_adjustment.insert(nod_pt).second)
3868 send_unsigneds.push_back(
e);
3870 send_unsigneds.push_back(j);
3872 for (
unsigned dir = 0; dir < n_dim; dir++)
3874 send_doubles.push_back(x_act[dir]);
3885 unsigned send_unsigneds_count = send_unsigneds.size();
3886 unsigned send_doubles_count = send_doubles.size();
3888 if (send_unsigneds_count > 0)
3894 MPI_Send(&send_unsigneds_count,
3901 &send_doubles_count, 1, MPI_UNSIGNED, dd, 1,
Comm_pt->mpi_comm());
3904 if (send_unsigneds_count != 0)
3906 MPI_Send(&send_unsigneds[0],
3907 send_unsigneds_count,
3913 if (send_doubles_count != 0)
3915 MPI_Send(&send_doubles[0],
3930 oomph_info <<
"Time for synchronise_nonhanging_nodes(): "
3931 << t_end - t_start << std::endl;
3973 if (refine_tol <= unrefine_tol)
3975 std::ostringstream error_stream;
3976 error_stream <<
"Refinement tolerance <= Unrefinement tolerance"
3977 << refine_tol <<
" " << unrefine_tol << std::endl
3978 <<
"doesn't make sense and will almost certainly crash"
3980 <<
"this beautiful code!" << std::endl;
3983 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3993 unsigned n_refine = 0;
3994 unsigned n_unrefine = 0;
3996 unsigned long Nelement = this->
nelement();
3997 for (
unsigned long e = 0;
e < Nelement;
e++)
4011 if (elemental_error[
e] > refine_tol)
4027 if (elemental_error[
e] < unrefine_tol)
4034 (el_pt->
p_order() > this->min_p_refinement_level()) &&
4050 oomph_info <<
"p-refinement is not possible for these elements"
4057 oomph_info <<
" \n Number of elements to be refined: " << n_refine
4059 oomph_info <<
" \n Number of elements whose refinement was overruled: "
4062 oomph_info <<
" \n Number of elements to be unrefined : " << n_unrefine
4082 unsigned total_n_refine = 0;
4083 #ifdef OOMPH_HAS_MPI
4088 &n_refine, &total_n_refine, 1, MPI_INT, MPI_SUM,
Comm_pt->mpi_comm());
4092 total_n_refine = n_refine;
4095 total_n_refine = n_refine;
4106 unsigned total_n_unrefine = 0;
4107 #ifdef OOMPH_HAS_MPI
4111 MPI_Allreduce(&n_unrefine,
4120 total_n_unrefine = n_unrefine;
4123 total_n_unrefine = n_unrefine;
4126 oomph_info <<
"---> " << total_n_refine <<
" elements to be refined, and "
4127 << total_n_unrefine <<
" to be unrefined, in total."
4133 #ifdef OOMPH_HAS_MPI
4142 int n_proc =
Comm_pt->nproc();
4143 int my_rank =
Comm_pt->my_rank();
4146 for (
int d = 0; d < n_proc; d++)
4159 unsigned nhalo = halo_elem_pt.size();
4161 for (
unsigned e = 0;
e < nhalo;
e++)
4164 ->to_be_p_unrefined())
4166 halo_to_be_unrefined[
e] = 1;
4175 MPI_Send(&halo_to_be_unrefined[0],
4191 unsigned nhaloed = haloed_elem_pt.size();
4196 MPI_Recv(&halo_to_be_unrefined[0],
4206 for (
unsigned e = 0;
e < nhaloed;
e++)
4208 if (((halo_to_be_unrefined[
e] == 0) &&
4210 ->to_be_p_unrefined())) ||
4211 ((halo_to_be_unrefined[
e] == 1) &&
4213 ->to_be_p_unrefined())))
4215 std::ostringstream error_message;
4217 <<
"Error in refinement: \n"
4218 <<
"Haloed element: " <<
e <<
" on proc " << my_rank
4220 <<
"wants to be unrefined whereas its halo counterpart on\n"
4221 <<
"proc " << d <<
" doesn't (or vice versa)...\n"
4222 <<
"This is most likely because the error estimator\n"
4223 <<
"has not assigned the same errors to halo and haloed\n"
4224 <<
"elements -- it ought to!\n";
4226 OOMPH_CURRENT_FUNCTION,
4227 OOMPH_EXCEPTION_LOCATION);
4236 for (
int d = 0; d < n_proc; d++)
4249 unsigned nhalo = halo_elem_pt.size();
4251 for (
unsigned e = 0;
e < nhalo;
e++)
4254 ->to_be_p_refined())
4256 halo_to_be_refined[
e] = 1;
4263 MPI_Send(&halo_to_be_refined[0],
4279 unsigned nhaloed = haloed_elem_pt.size();
4283 MPI_Recv(&halo_to_be_refined[0],
4293 for (
unsigned e = 0;
e < nhaloed;
e++)
4295 if (((halo_to_be_refined[
e] == 0) &&
4297 ->to_be_p_refined())) ||
4298 ((halo_to_be_refined[
e] == 1) &&
4300 ->to_be_p_refined())))
4302 std::ostringstream error_message;
4304 <<
"Error in refinement: \n"
4305 <<
"Haloed element: " <<
e <<
" on proc " << my_rank
4307 <<
"wants to be refined whereas its halo counterpart on\n"
4308 <<
"proc " << d <<
" doesn't (or vice versa)...\n"
4309 <<
"This is most likely because the error estimator\n"
4310 <<
"has not assigned the same errors to halo and haloed\n"
4311 <<
"elements -- it ought to!\n";
4313 OOMPH_CURRENT_FUNCTION,
4314 OOMPH_EXCEPTION_LOCATION);
4335 #ifdef OOMPH_HAS_MPI
4349 #ifdef OOMPH_HAS_MPI
4366 oomph_info <<
"\n Not enough benefit in adapting mesh. " << std::endl
4435 #ifdef OOMPH_HAS_MPI
4446 double t_start = 0.0;
4458 oomph_info <<
"Time for p-refinement/unrefinement: " << t_end - t_start
4485 const unsigned n_boundary = this->
nboundary();
4489 unsigned long n_node = this->
nnode();
4490 for (
unsigned long n = 0; n < n_node; n++)
4496 unsigned n_value = nod_pt->
nvalue();
4501 for (
unsigned n = 0; n < n_value; n++)
4517 unsigned n_dim = nod_pt->
ndim();
4520 for (
unsigned t = 0;
t < nt;
t++)
4522 nod_pt->
value(
t, values);
4523 for (
unsigned i = 0;
i < n_value;
i++)
4528 for (
unsigned i = 0;
i < n_dim;
i++)
4530 nod_pt->
x(
t,
i) = position[
i];
4536 if (alg_node_pt != 0)
4538 bool update_all_time_levels =
true;
4546 if (solid_node_pt != 0)
4548 unsigned n_lagrangian = solid_node_pt->
nlagrangian();
4549 for (
unsigned i = 0;
i < n_lagrangian;
i++)
4558 if ((mesh_dim > 2) && (nod_pt->
is_hanging()))
4565 std::set<unsigned>* boundaries_pt;
4567 if (boundaries_pt != 0)
4571 for (std::set<unsigned>::iterator it = boundaries_pt->begin();
4572 it != boundaries_pt->end();
4575 hanging_nodes_on_boundary_pt[*it].insert(nod_pt);
4592 oomph_info <<
"Time for sorting out initial hanging status: "
4593 << t_end - t_start << std::endl;
4602 unsigned long num_tree_nodes = tree_nodes_pt.size();
4604 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
4610 unsigned n_node = this_el_pt->
nnode();
4611 for (
unsigned n = 0; n < n_node; n++)
4638 hanging_output_files);
4640 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
4643 tree_nodes_pt[
e]->object_pt()->setup_hanging_nodes(
4644 hanging_output_files);
4646 tree_nodes_pt[
e]->object_pt()->further_setup_hanging_nodes();
4652 hanging_output_files);
4658 oomph_info <<
"Time for setup_hanging_nodes() and "
4659 "further_setup_hanging_nodes() for "
4660 << num_tree_nodes <<
" elements: " << t_end - t_start
4667 unsigned ncont_interpolated_values =
4668 tree_nodes_pt[0]->object_pt()->ncont_interpolated_values();
4678 oomph_info <<
"Time for complete_hanging_nodes: " << t_end - t_start
4694 oomph_info <<
"Time for boundary element info: " << t_end - t_start
4707 if (first_macro_el_pt != 0)
4716 if (macro_el_pt != 0)
4743 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
4745 double max_el_error;
4746 tree_nodes_pt[
e]->object_pt()->check_integrity(max_el_error);
4757 std::ostringstream error_stream;
4758 error_stream <<
"Mesh refined: Max. error in integrity check: "
4760 <<
"\ni.e. bigger than RefineableElement::"
4761 <<
"max_integrity_tolerance()="
4765 std::ofstream some_file;
4766 some_file.open(
"ProblemMesh.dat");
4767 for (
unsigned long n = 0; n < n_node; n++)
4772 unsigned n_dim = nod_pt->
ndim();
4774 for (
unsigned i = 0;
i < n_dim;
i++)
4776 some_file << this->
node_pt(n)->
x(
i) <<
" ";
4778 some_file << std::endl;
4782 error_stream <<
"Documented problem mesh in ProblemMesh.dat"
4786 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
4790 oomph_info <<
"Mesh refined: Max. error in integrity check: "
4793 <<
"i.e. less than RefineableElement::max_integrity_tolerance()="
4802 oomph_info <<
"Time for (paranoid only) checking of integrity: "
4803 << t_end - t_start << std::endl;
4827 oomph_info <<
"Time for deactivating objects and pruning nodes: "
4828 << t_end - t_start << std::endl;
4842 <<
" nodes: " << t_end - t_start << std::endl;
4852 for (
unsigned b = 0; b < n_boundary; b++)
4855 unsigned n_del = deleted_node_pt.size();
4856 for (
unsigned j = 0; j < n_del; j++)
4858 hanging_nodes_on_boundary_pt[b].erase(deleted_node_pt[j]);
4863 for (std::set<Node*>::iterator it =
4864 hanging_nodes_on_boundary_pt[b].begin();
4865 it != hanging_nodes_on_boundary_pt[b].end();)
4867 if ((*it)->is_hanging())
4869 hanging_nodes_on_boundary_pt[b].erase(it++);
4882 if (hanging_nodes_on_boundary_pt[b].size() > 0)
4886 for (
unsigned e = 0;
e < n_boundary_element; ++
e)
4898 if (solid_el_pt != 0)
4910 unsigned n_el_node = el_pt->
nnode();
4911 for (
unsigned n = 0; n < n_el_node; n++)
4918 std::set<Node*>::iterator it =
4919 hanging_nodes_on_boundary_pt[b].find(nod_pt);
4922 if (it != hanging_nodes_on_boundary_pt[b].end())
4930 const unsigned ntstorage = nod_pt->
ntstorage();
4951 for (
unsigned i = 0;
i < 3;
i++)
4953 solid_node_pt->
xi(
i) = xi[
i];
4960 for (
unsigned t = 0;
t < ntstorage;
t++)
4967 for (
unsigned i = 0;
i < 3;
i++)
4969 nod_pt->
x(
t,
i) = x[
i];
4975 hanging_nodes_on_boundary_pt[b].erase(it);
4977 if (hanging_nodes_on_boundary_pt[b].size() == 0)
4979 e = n_boundary_element;
5005 unsigned max_nval = 0;
5006 for (
unsigned n = 0; n < el_pt->
nnode(); n++)
5015 std::ostringstream fullname;
5016 std::ofstream bcs_file;
5020 bcs_file.open(fullname.str().c_str());
5023 for (
unsigned long e = 0;
e < num_tree_nodes;
e++)
5025 el_pt = tree_nodes_pt[
e]->object_pt();
5027 unsigned n_nod = el_pt->
nnode();
5028 for (
unsigned n = 0; n < n_nod; n++)
5033 unsigned n_dim = nod_pt->
ndim();
5035 for (
unsigned i = 0;
i < n_dim;
i++)
5037 bcs_file << nod_pt->
x(
i) <<
" ";
5041 for (
unsigned i = 0;
i < max_nval;
i++)
5044 if (i < nod_pt->nvalue())
5054 bcs_file << std::endl;
5061 std::ofstream all_nodes_file;
5065 all_nodes_file.open(fullname.str().c_str());
5067 all_nodes_file <<
"ZONE \n";
5071 n_node = this->
nnode();
5072 for (
unsigned long n = 0; n < n_node; n++)
5075 unsigned n_dim = nod_pt->
ndim();
5076 for (
unsigned i = 0;
i < n_dim;
i++)
5078 all_nodes_file << this->
node_pt(n)->
x(
i) <<
" ";
5080 all_nodes_file << std::endl;
5083 all_nodes_file.close();
5088 std::ofstream some_file;
5092 some_file.open(fullname.str().c_str());
5093 for (
unsigned long n = 0; n < n_node; n++)
5099 unsigned n_dim = nod_pt->
ndim();
5100 for (
unsigned i = 0;
i < n_dim;
i++)
5102 some_file << nod_pt->
x(
i) <<
" ";
5106 if (this->
node_pt(n)->nvalue() > 0)
5108 some_file <<
" " << nod_pt->
raw_value(0);
5110 some_file << std::endl;
5120 some_file.open(fullname.str().c_str());
5121 for (
unsigned long n = 0; n < n_node; n++)
5126 unsigned n_dim = nod_pt->
ndim();
5128 some_file <<
"ZONE I=" << nmaster + 1 << std::endl;
5129 for (
unsigned i = 0;
i < n_dim;
i++)
5131 some_file << nod_pt->
x(
i) <<
" ";
5133 some_file <<
" 2 " << std::endl;
5135 for (
unsigned imaster = 0; imaster < nmaster; imaster++)
5137 Node* master_nod_pt =
5139 unsigned n_dim = master_nod_pt->
ndim();
5140 for (
unsigned i = 0;
i < n_dim;
i++)
5142 some_file << master_nod_pt->
x(
i) <<
" ";
5144 some_file <<
" 1 " << std::endl;
5152 for (
unsigned i = 0;
i < ncont_interpolated_values;
i++)
5156 <<
"/nonstandard_hangnodes_withmasters" <<
i <<
"_"
5158 some_file.open(fullname.str().c_str());
5159 unsigned n_nod = this->
nnode();
5160 for (
unsigned long n = 0; n < n_nod; n++)
5168 some_file <<
"ZONE I=" << nmaster + 1 << std::endl;
5169 unsigned n_dim = nod_pt->
ndim();
5170 for (
unsigned j = 0; j < n_dim; j++)
5172 some_file << nod_pt->
x(j) <<
" ";
5174 some_file <<
" 2 " << std::endl;
5175 for (
unsigned imaster = 0; imaster < nmaster; imaster++)
5177 Node* master_nod_pt =
5179 unsigned n_dim = master_nod_pt->
ndim();
5180 for (
unsigned j = 0; j < n_dim; j++)
5184 some_file <<
" 1 " << std::endl;
5224 #ifdef OOMPH_HAS_MPI
5243 unsigned long Nelement = this->
nelement();
5244 for (
unsigned long e = 0;
e < Nelement;
e++)
5267 #ifdef OOMPH_HAS_MPI
5270 std::ostringstream warn_stream;
5271 warn_stream <<
"You are attempting to refine selected elements of a "
5273 <<
"distributed mesh. This may have undesired effects."
5277 "TreeBasedRefineableMeshBase::refine_selected_elements()",
5278 OOMPH_EXCEPTION_LOCATION);
5283 unsigned long nref = elements_to_be_refined.size();
5284 for (
unsigned long e = 0;
e < nref;
e++)
5307 #ifdef OOMPH_HAS_MPI
5310 std::ostringstream warn_stream;
5311 warn_stream <<
"You are attempting to refine selected elements of a "
5313 <<
"distributed mesh. This may have undesired effects."
5317 "TreeBasedRefineableMeshBase::refine_selected_elements()",
5318 OOMPH_EXCEPTION_LOCATION);
5323 unsigned long nref = elements_to_be_refined_pt.size();
5324 for (
unsigned long e = 0;
e < nref;
e++)
5326 elements_to_be_refined_pt[
e]->select_for_p_refinement();
////////////////////////////////////////////////////////////////////
void node_update(const bool &update_all_time_levels_for_new_node=false)
Broken assignment operator.
void set_value(const unsigned &i, const double &value_)
Set the i-th stored data value to specified value. The only reason that we require an explicit set fu...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
unsigned ntstorage() const
Return total number of doubles stored per value to record time history of each value (one for steady ...
int non_halo_proc_ID()
ID of processor ID that holds non-halo counterpart of halo node; negative if not a halo.
bool is_pinned(const unsigned &i) const
Test whether the i-th variable is pinned (1: true; 0: false).
Information for documentation of results: Directory and file number to enable output in the form RESL...
bool is_doc_enabled() const
Are we documenting?
void disable_doc()
Disable documentation.
std::string directory() const
Output directory.
unsigned & number()
Number used (e.g.) for labeling output files.
A general Finite Element class.
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual)
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
unsigned nnode() const
Return the number of nodes.
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...
MacroElement * macro_elem_pt()
Access function to pointer to macro element.
Class that contains data for hanging nodes.
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
unsigned nmaster() const
Return the number of master nodes.
void set_master_node_pt(const unsigned &i, Node *const &master_node_pt, const double &weight)
Set the pointer to the i-th master node and its weight.
////////////////////////////////////////////////////////////////////
Vector< GeomObject * > & geom_object_pt()
Vector of (pointers to) geometric objects involved in node update function.
virtual void set_node_update_info(const Vector< GeomObject * > &geom_object_pt)=0
Set node update information: Pass the vector of (pointers to) the geometric objects that affect the n...
Node * halo_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th halo node in this Mesh whose non-halo counterpart is held on processor p.
std::map< unsigned, Vector< Node * > > Shared_node_pt
Map of vectors holding the pointers to the shared nodes. These are all the nodes that are on two "nei...
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
Node * haloed_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th haloed node in this Mesh whose halo counterpart is held on processor p.
bool Lookup_for_elements_next_boundary_is_setup
Flag to indicate that the lookup schemes for elements that are adjacent to the boundaries has been se...
Node * shared_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th shared node in this Mesh who has a counterpart on processor p.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Vector< GeneralisedElement * > haloed_element_pt(const unsigned &p)
Return vector of haloed elements in this Mesh whose haloing counterpart is held on processor p.
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
virtual void setup_boundary_element_info()
Interface for function that is used to setup the boundary information (Empty virtual function – imple...
OomphCommunicator * Comm_pt
Pointer to communicator – set to NULL if mesh is not distributed.
virtual void reorder_nodes(const bool &use_old_ordering=true)
Re-order nodes in the order in which they appear in elements – can be overloaded for more efficient r...
unsigned nboundary() const
Return number of boundaries.
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
unsigned long nnode() const
Return number of nodes in the mesh.
void delete_all_external_storage()
Wipe the storage for all externally-based elements.
unsigned nhalo_node()
Total number of halo nodes in this Mesh.
void output(std::ostream &outfile)
Output for all elements.
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Vector< Node * > prune_dead_nodes()
Prune nodes. Nodes that have been marked as obsolete are removed from the mesh (and its boundary-node...
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
unsigned nhaloed_node()
Total number of haloed nodes in this Mesh.
unsigned long nelement() const
Return number of elements in the mesh.
Vector< GeneralisedElement * > halo_element_pt(const unsigned &p)
Return vector of halo elements in this Mesh whose non-halo counterpart is held on processor p.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
void set_nonhanging()
Label node as non-hanging node by removing all hanging node data.
virtual bool is_on_boundary() const
Test whether the Node lies on a boundary. The "bulk" Node cannot lie on a boundary,...
void set_obsolete()
Mark node as obsolete.
virtual void get_boundaries_pt(std::set< unsigned > *&boundaries_pt)
Return a pointer to set of mesh boundaries that this node occupies; this will be overloaded by Bounda...
void position(Vector< double > &pos) const
Compute Vector of nodal positions either directly or via hanging node representation.
void set_non_obsolete()
Mark node as non-obsolete.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
void set_hanging_pt(HangInfo *const &hang_pt, const int &i)
Set the hanging data for the i-th value. (hang_pt=0 to make non-hanging)
double raw_value(const unsigned &i) const
Return the i-th value stored at the Node. This interface does NOT take the hanging status of the Node...
bool is_hanging() const
Test whether the node is geometrically hanging.
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation....
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
bool p_refinement_is_enabled()
Flag to indicate suppression of any refinement.
unsigned & p_order()
Access function to P_order.
virtual unsigned initial_p_order() const =0
Get the initial P_order This is required so that elements which are constructed with a higher p-order...
void select_for_p_refinement()
Select the element for p-refinement.
void deselect_for_p_unrefinement()
Deselect the element for p-unrefinement.
void select_for_p_unrefinement()
Select the element for p-unrefinement.
void deselect_for_p_refinement()
Deselect the element for p-refinement.
RefineableElements are FiniteElements that may be subdivided into children to provide a better local ...
void select_sons_for_unrefinement()
Unrefinement will be performed by merging the four sons of this element.
Tree * tree_pt()
Access function: Pointer to quadtree representation of this element.
static double & max_integrity_tolerance()
Max. allowed discrepancy in element integrity check.
void select_for_refinement()
Select the element for refinement.
unsigned refinement_level() const
Return the Refinement level.
bool refinement_is_enabled()
Flag to indicate suppression of any refinement.
void deselect_for_refinement()
Deselect the element for refinement.
void deselect_sons_for_unrefinement()
No unrefinement will be performed by merging the four sons of this element.
unsigned Nrefined
Stats: Number of elements that were refined.
unsigned & max_keep_unrefined()
Max. number of elements that we allow to remain unrefined if no other mesh adaptation is required (to...
DocInfo doc_info()
Access fct for DocInfo.
unsigned Nunrefined
Stats: Number of elements that were unrefined.
DocInfo *& doc_info_pt()
Access fct for pointer to DocInfo.
double & max_error()
Access fct for max. actual error in present solution (i.e. before re-solve on adapted mesh)
double & min_permitted_error()
Access fct for min. error (i.e. (try to) merge elements if their error is smaller)
double & max_permitted_error()
Access fct for max. error (i.e. split elements if their error is larger)
unsigned & nrefinement_overruled()
Number of elements that would have liked to be refined further but can't because they've reached the ...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
MacroElement * undeformed_macro_elem_pt()
Access function to pointer to "undeformed" macro element.
virtual void get_x_and_xi(const Vector< double > &s, Vector< double > &x_fe, Vector< double > &x, Vector< double > &xi_fe, Vector< double > &xi) const
Eulerian and Lagrangian coordinates as function of the local coordinates: The Eulerian position is re...
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
double lagrangian_position(const unsigned &i) const
Return lagrangian coordinate either directly or via hanging node representation.
double & xi(const unsigned &i)
Reference to i-th Lagrangian position.
unsigned nlagrangian() const
Return number of lagrangian coordinates.
///////////////////////////////////////////////////////////////// ///////////////////////////////////...
void synchronise_hanging_nodes(const unsigned &ncont_interpolated_values)
Synchronise the hanging nodes if the mesh is distributed.
virtual void get_elements_at_refinement_level(unsigned &refinement_level, Vector< RefineableElement * > &level_elements)
Extract the elements at a particular refinement level in the refinement pattern - used in Mesh::redis...
void refine_base_mesh(Vector< Vector< unsigned >> &to_be_refined)
Refine base mesh according to specified refinement pattern.
virtual void refine_selected_elements(const Vector< unsigned > &elements_to_be_refined)
Refine mesh by splitting the elements identified by their numbers.
unsigned & max_refinement_level()
Access fct for max. permissible refinement level (relative to base mesh)
virtual void dump_refinement(std::ostream &outfile)
Dump refinement pattern to allow for rebuild.
TreeForest * forest_pt()
Return pointer to the Forest represenation of the mesh.
virtual void read_refinement(std::ifstream &restart_file, Vector< Vector< unsigned >> &to_be_refined)
Read refinement pattern to allow for rebuild.
unsigned unrefine_uniformly()
Unrefine mesh uniformly: Return 0 for success, 1 for failure (if unrefinement has reached the coarses...
virtual void refine(std::ifstream &restart_file)
Refine mesh according to refinement pattern in restart file.
virtual void additional_synchronise_hanging_nodes(const unsigned &ncont_interpolated_values)=0
Additional synchronisation of hanging nodes Required for reconcilliation of hanging nodes on the oute...
virtual void adapt_mesh()
Perform the actual tree-based mesh adaptation. A simple wrapper to call the function without document...
virtual void refine_base_mesh_as_in_reference_mesh(TreeBasedRefineableMeshBase *const &ref_mesh_pt)
Refine base mesh to same degree as reference mesh (relative to original unrefined mesh).
void complete_hanging_nodes_recursively(Node *&nod_pt, Vector< Node * > &master_nodes, Vector< double > &hang_weights, const int &ival)
Auxiliary routine for recursive hanging node completion.
virtual void refine_as_in_reference_mesh(TreeBasedRefineableMeshBase *const &ref_mesh_pt)
Refine mesh once so that its topology etc becomes that of the (finer!) reference mesh – if possible!...
void p_refine_selected_elements(const Vector< unsigned > &elements_to_be_refined)
p-refine mesh by refining the elements identified by their numbers.
virtual void split_elements_if_required()=0
Split all the elements in the mesh if required. This template free interface will be overloaded in Re...
void refine_uniformly()
Refine mesh uniformly.
void p_unrefine_uniformly(DocInfo &doc_info)
p-unrefine mesh uniformly
virtual void get_refinement_levels(unsigned &min_refinement_level, unsigned &max_refinement_level)
Get max/min refinement levels in mesh.
unsigned & max_p_refinement_level()
Access fct for max. permissible p-refinement level (relative to base mesh)
virtual void p_refine_elements_if_required()=0
p-refine all the elements in the mesh if required. This template free interface will be overloaded in...
void complete_hanging_nodes(const int &ncont_interpolated_values)
Complete the hanging node scheme recursively.
TreeForest * Forest_pt
Forest representation of the mesh.
void synchronise_nonhanging_nodes()
Synchronise the positions of non-hanging nodes that depend on non-existent neighbours (e....
void adapt(const Vector< double > &elemental_error)
Adapt mesh: Refine elements whose error is lager than err_max and (try to) unrefine those whose error...
void p_adapt(const Vector< double > &elemental_error)
p-adapt mesh: Refine elements whose error is lager than err_max and (try to) unrefine those whose err...
void p_adapt_mesh()
Perform the actual tree-based mesh p-adaptation. A simple wrapper to call the function without docume...
virtual void get_refinement_pattern(Vector< Vector< unsigned >> &to_be_refined)
Extract refinement pattern: Consider the hypothetical mesh obtained by truncating the refinement of t...
virtual bool refine_base_mesh_as_in_reference_mesh_minus_one(TreeBasedRefineableMeshBase *const &ref_mesh_pt)
Refine base mesh to same degree as reference mesh minus one level of refinement (relative to original...
void p_refine_uniformly()
p-refine mesh uniformly
void classify_halo_and_haloed_nodes(DocInfo &doc_info, const bool &report_stats)
Classify all halo and haloed information in the mesh (overloaded version from Mesh base class....
unsigned & min_refinement_level()
Access fct for min. permissible refinement level (relative to base mesh)
virtual void check_all_neighbours(DocInfo &doc_info)=0
Document/check the neighbours of all the nodes in the forest. This must be overloaded for different t...
void stick_all_tree_nodes_into_vector(Vector< Tree * > &all_forest_nodes)
Traverse forest and stick pointers to all "nodes" into Vector.
virtual void open_hanging_node_files(DocInfo &doc_info, Vector< std::ofstream * > &output_stream)=0
Open output files that will store any hanging nodes in the forest. Return a vector of the output stre...
unsigned ntree()
Number of trees in forest.
void stick_leaves_into_vector(Vector< Tree * > &forest_nodes)
Traverse forst and stick pointers to leaf "nodes" into Vector.
TreeRoot * tree_pt(const unsigned &i) const
Return pointer to i-th tree in forest.
void close_hanging_node_files(DocInfo &doc_info, Vector< std::ofstream * > &output_stream)
Close output files that will store any hanging nodes in the forest and delete any associated storage....
A generalised tree base class that abstracts the common functionality between the quad- and octrees u...
RefineableElement * object_pt() const
Return the pointer to the object (RefineableElement) represented by the tree.
unsigned nsons() const
Return number of sons (zero if it's a leaf node)
void traverse_all(Tree::VoidMemberFctPt member_function)
Traverse the tree and execute void Tree member function member_function() at all its "nodes".
Tree * father_pt() const
Return pointer to father: NULL if it's a root node.
bool is_leaf()
Return true if the tree is a leaf node.
int son_type() const
Return son type.
Tree * son_pt(const int &son_index) const
Return pointer to the son for a given index. Note that to aid code readability specific enums have be...
void deactivate_object()
Call the RefineableElement's deactivate_element() function.
void traverse_all_but_leaves(Tree::VoidMemberFctPt member_function)
Traverse the tree and execute void Tree member function member_function() at all its "nodes" aparat f...
void merge_sons_if_required(Mesh *&mesh_pt)
If required, merge the four sons for unrefinement – criterion: bool object_pt()-> sons_to_be_unrefine...
A slight extension to the standard template vector class so that we can include "graceful" array rang...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
bool Doc_comprehensive_timings
Global boolean to switch on comprehensive timing – can probably be declared const false when developm...
double timer()
returns the time in seconds after some point in past
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
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...
Helper struct to collate data required during TreeBasedRefineableMeshBase::synchronise_hanging_nodes.
unsigned Shared_node_proc
unsigned Sending_processor
unsigned Shared_node_id_on_sending_processor
unsigned Master_node_index