75 unsigned nsub_mesh=sub_mesh_pt.size();
78 unsigned long n_element=0;
79 unsigned long n_node=0;
84 for(
unsigned imesh=0;imesh<nsub_mesh;imesh++)
86 n_element += sub_mesh_pt[imesh]->nelement();
87 n_node += sub_mesh_pt[imesh]->nnode();
88 n_bound += sub_mesh_pt[imesh]->nboundary();
104 std::set<GeneralisedElement*> element_set_pt;
105 std::set<Node*> node_set_pt;
108 unsigned ibound_global=0;
110 for(
unsigned imesh=0;imesh<nsub_mesh;imesh++)
114 unsigned nel_before=0;
115 unsigned long n_element=sub_mesh_pt[imesh]->nelement();
116 for (
unsigned long e=0;
e<n_element;
e++)
119 element_set_pt.insert(el_pt);
121 unsigned nel_now=element_set_pt.size();
122 if (nel_now==nel_before)
124 std::ostringstream warning_stream;
125 warning_stream <<
"WARNING: " << std::endl
126 <<
"Element " <<
e <<
" in submesh " << imesh
127 <<
" is a duplicate \n and was ignored when assembling" 128 <<
" combined mesh." << std::endl;
130 "Mesh::Mesh(const Vector<Mesh*>&)",
131 OOMPH_EXCEPTION_LOCATION);
142 unsigned nnod_before=0;
143 unsigned long n_node=sub_mesh_pt[imesh]->nnode();
144 for (
unsigned long n=0;n<n_node;n++)
146 Node* nod_pt=sub_mesh_pt[imesh]->node_pt(n);
147 node_set_pt.insert(nod_pt);
149 unsigned nnod_now=node_set_pt.size();
150 if (nnod_now==nnod_before)
152 std::ostringstream warning_stream;
153 warning_stream<<
"WARNING: " << std::endl
154 <<
"Node " << n <<
" in submesh " << imesh
155 <<
" is a duplicate \n and was ignored when assembling " 156 <<
"combined mesh." << std::endl;
158 "Mesh::Mesh(const Vector<Mesh*>&)",
159 OOMPH_EXCEPTION_LOCATION);
165 nnod_before=nnod_now;
169 unsigned n_bound=sub_mesh_pt[imesh]->nboundary();
170 for (
unsigned ibound=0;ibound<n_bound;ibound++)
174 unsigned long n_bound_node=sub_mesh_pt[imesh]->nboundary_node(ibound);
175 for (
unsigned long n=0;n<n_bound_node;n++)
197 for(
unsigned n=0;n<n_boundary_node;n++)
255 bool node_already_on_this_boundary=
false;
257 for (
unsigned n=0; n<nbound_node; n++)
262 node_already_on_this_boundary=
true;
267 if (!node_already_on_this_boundary)
296 for(
unsigned long n=0;n<
nnode();n++)
303 for (
unsigned imaster=0;imaster<nmaster;imaster++)
314 = std::find(external_halo_node_pt.begin(),
315 external_halo_node_pt.end(),
319 if(it != external_halo_node_pt.end())
326 std::ostringstream err_stream;
328 err_stream <<
"Calling node_update() for a mesh which contains" 330 <<
"master nodes which live in the external storage." 332 <<
"These nodes do not belong to elements on this" 334 <<
"processor and therefore cannot be updated locally." 338 OOMPH_CURRENT_FUNCTION,
339 OOMPH_EXCEPTION_LOCATION);
359 for (
unsigned e=0;
e<nel;
e++)
369 unsigned ndim_el=el_pt->
dim();
373 unsigned n_node=el_pt->
nnode();
374 for (
unsigned j=0;j<n_node;j++)
381 unsigned ndim_node=nod_pt->
ndim();
397 for (
unsigned i=0;
i<ndim_node;
i++)
400 if (solid_node_pt!=0)
403 if (update_all_solid_nodes)
405 solid_node_pt->
x(
i) = r[
i];
429 unsigned nnod=ext_halo_node_pt.size();
430 for (
unsigned j=0;j<nnod;j++)
432 ext_halo_node_pt[j]->node_update();
439 unsigned long n_node =
nnode();
440 for(
unsigned long n=0;n<n_node;n++)
446 unsigned ndim_node=nod_pt->
ndim();
449 for (
unsigned i=0;
i<ndim_node;
i++)
456 for (
unsigned imaster=0;imaster<nmaster;imaster++)
459 for (
unsigned i=0;
i<ndim_node;
i++)
462 master_node_pt(imaster)->x(
i)*
471 for(
unsigned long n=0;n<n_node;n++)
473 Node_pt[n]->perform_auxiliary_node_update_fct();
488 unsigned n_node =
nnode();
489 for(
unsigned i=0;
i<n_node;
i++)
501 const bool& use_old_ordering)
const 506 std::map<Node*,bool> done;
509 unsigned nnod=
nnode();
512 reordering.assign(nnod,0);
520 for (
unsigned j=0;j<nnod;j++)
526 unsigned long count=0;
530 for (
unsigned e=0;
e<nel;
e++)
534 unsigned nnod=el_pt->
nnode();
535 for (
unsigned j=0;j<nnod;j++)
550 reordering[count]=nod_pt;
562 "Trouble: Number of nodes hasn't stayed constant during reordering!\n",
563 OOMPH_CURRENT_FUNCTION,
564 OOMPH_EXCEPTION_LOCATION);
571 unsigned n_node =
nnode();
572 reordering.resize(n_node);
573 for(
unsigned i=0;
i<n_node;
i++)
579 std::sort(reordering.begin(), reordering.end(),
592 unsigned long Node_pt_range =
Node_pt.size();
593 for(
unsigned long i=Node_pt_range;
i>0;
i--)
600 unsigned long Element_pt_range =
Element_pt.size();
601 for(
unsigned long i=Element_pt_range;
i>0;
i--)
617 unsigned long equation_number=Dof_pt.size();
620 unsigned long nnod =
Node_pt.size();
622 for(
unsigned long i=0;
i<nnod;
i++)
624 Node_pt[
i]->assign_eqn_numbers(equation_number,Dof_pt);
629 for(
unsigned long i=0;
i<nel;
i++)
631 Element_pt[
i]->assign_internal_eqn_numbers(equation_number,Dof_pt);
635 return(equation_number);
652 unsigned long nnod =
Node_pt.size();
653 for(
unsigned long i=0;
i<nnod;
i++)
655 std::stringstream conversion;
656 conversion <<
" of Node " <<
i << current_string;
663 for(
unsigned long i=0;
i<nel;
i++)
665 std::stringstream conversion;
666 conversion <<
" in Element "<<
i<<
" ["<<
typeid(*
Element_pt[
i]).name()<<
"] " 688 for(
unsigned long i=0;
i<nel;
i++)
690 std::stringstream conversion;
691 conversion <<
" in Element"<<
i<<
" ["<<
typeid(*
Element_pt[
i]).name()<<
"] " 705 unsigned long Element_pt_range =
Element_pt.size();
706 for(
unsigned long i=0;
i<Element_pt_range;
i++)
708 Element_pt[
i]->assign_local_eqn_numbers(store_local_dof_pt);
738 std::set<GeneralisedElement*> element_set_pt;
739 unsigned long Element_pt_range =
Element_pt.size();
740 for(
unsigned long i=0;
i<Element_pt_range;
i++)
745 oomph_info <<
"\n ERROR: Failed Element::self_test() for element i=" 753 if (element_set_pt.size()!=Element_pt_range)
755 oomph_info <<
"ERROR: " << Element_pt_range-element_set_pt.size()
756 <<
" duplicate elements were encountered in mesh!" << std::endl;
762 std::set<Node*> node_set_pt;
763 unsigned long Node_pt_range =
Node_pt.size();
764 for(
unsigned long i=0;
i<Node_pt_range;
i++)
769 oomph_info <<
"\n ERROR: Failed Node::self_test() for node i=" 777 if (node_set_pt.size()!=Node_pt_range)
779 oomph_info <<
"ERROR: " << Node_pt_range-node_set_pt.size()
780 <<
" duplicate nodes were encountered in mesh!" << std::endl;
785 if (passed) {
return 0;}
803 std::ofstream& inverted_element_file)
806 mesh_has_inverted_elements=
false;
815 for (
unsigned e=0;
e<nelem;
e++)
824 unsigned n_node = el_pt->
nnode();
825 unsigned n_dim=el_pt->
dim();
830 if (n_dim==ndim_node)
835 DShape dpsidx(n_node,n_dim);
839 bool is_inverted=
false;
842 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
845 for(
unsigned i=0;
i<n_dim;
i++)
880 mesh_has_inverted_elements=
true;
881 if (inverted_element_file.is_open())
883 el_pt->
output(inverted_element_file);
911 unsigned long n_node =
nnode();
912 for(
unsigned long n=0;n<n_node;n++)
915 if(!(
Node_pt[n]->is_obsolete()))
917 new_node_pt.push_back(
Node_pt[n]);
925 if(!(
Node_pt[n]->is_on_boundary()))
927 deleted_node_pt.push_back(
Node_pt[n]);
945 for(
unsigned ibound=0;ibound<num_bound;ibound++)
955 new_boundary_node_pt.reserve(Nboundary_node);
957 for(
unsigned long n=0;n<Nboundary_node;n++)
974 deleted_node_pt.push_back(
988 return deleted_node_pt;
1005 for(
unsigned long ibound=0;ibound<num_bound;ibound++)
1010 outfile <<
"ZONE T=\"boundary" << ibound <<
"\"\n";
1012 for (
unsigned inod=0;inod<nnod;inod++)
1027 void Mesh::dump(std::ofstream &dump_file,
const bool& use_old_ordering)
const 1036 unsigned long Node_pt_range = this->
nnode();
1039 dump_file << Node_pt_range <<
" # number of nodes " << std::endl;
1042 for(
unsigned nd=0; nd<Node_pt_range; nd++)
1044 reordering[nd]->dump(dump_file);
1048 unsigned n_element = this->
nelement();
1049 for(
unsigned e=0;
e<n_element;
e++)
1055 dump_file << n_internal
1056 <<
" # number of internal Data items in element " 1058 for(
unsigned i=0;
i<n_internal;
i++)
1082 unsigned long n_node = this->
nnode();
1085 getline(restart_file,input_string,
'#');
1088 restart_file.ignore(80,
'\n');
1091 unsigned long check_n_node=atoi(input_string.c_str());
1092 if (check_n_node!=n_node)
1094 std::ostringstream error_stream;
1095 error_stream <<
"The number of nodes allocated " << n_node
1096 <<
" is not the same as specified in the restart file " 1097 << check_n_node << std::endl;
1100 OOMPH_CURRENT_FUNCTION,
1101 OOMPH_EXCEPTION_LOCATION);
1105 for(
unsigned long n=0;n<n_node;n++)
1112 el_node_pt->
read(restart_file);
1123 unsigned n_element = this->
nelement();
1124 for (
unsigned e=0;
e<n_element;
e++)
1131 getline(restart_file,input_string,
'#');
1134 restart_file.ignore(80,
'\n');
1137 unsigned long check_n_internal=atoi(input_string.c_str());
1138 if (check_n_internal!=n_internal)
1140 std::ostringstream error_stream;
1141 error_stream <<
"The number of internal data " << n_internal
1142 <<
" is not the same as specified in the restart file " 1143 << check_n_internal << std::endl;
1146 OOMPH_CURRENT_FUNCTION,
1147 OOMPH_EXCEPTION_LOCATION);
1150 for (
unsigned i=0;
i<n_internal;
i++)
1168 const unsigned &nplot)
const 1172 file_out.setf(std::ios_base::uppercase);
1175 unsigned long number_of_elements=this->
Element_pt.size();
1184 "Recast for FiniteElement failed for element 0!\n",
1185 OOMPH_CURRENT_FUNCTION,
1186 OOMPH_EXCEPTION_LOCATION);
1195 for(
unsigned i=1;
i<number_of_elements;
i++)
1199 if(el_zero_ndof!=el_i_ndof)
1201 std::stringstream error_stream;
1203 <<
"Element " <<
i <<
" has different number of degrees of freedom\n" 1204 <<
"than from previous elements, Paraview cannot handle this.\n" 1205 <<
"We suggest that the problem is broken up into submeshes instead." 1209 OOMPH_CURRENT_FUNCTION,
1210 OOMPH_EXCEPTION_LOCATION);
1216 unsigned long number_of_nodes=0;
1217 unsigned long total_number_of_elements=0;
1220 for(
unsigned i=0;
i<number_of_elements;
i++)
1229 std::stringstream error_stream;
1231 <<
"Recast for element " <<
i <<
" failed" << std::endl;
1234 OOMPH_CURRENT_FUNCTION,
1235 OOMPH_EXCEPTION_LOCATION);
1251 <<
"<?xml version=\"1.0\"?>\n" 1252 <<
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" " 1253 <<
"byte_order=\"LittleEndian\">\n" 1254 <<
"<UnstructuredGrid>\n" 1255 <<
"<Piece NumberOfPoints=\"" 1257 <<
"\" NumberOfCells=\"" 1258 << total_number_of_elements
1269 file_out <<
"<PointData ";
1274 file_out <<
"Scalars=\"" 1279 for(
unsigned i=0;
i<ndof;
i++)
1281 file_out <<
"<DataArray type=\"Float32\" " 1285 <<
"format=\"ascii\"" 1288 for(
unsigned j=0;j<number_of_elements;j++)
1297 std::stringstream error_stream;
1299 <<
"Recast for element " << j <<
" failed" << std::endl;
1302 OOMPH_CURRENT_FUNCTION,
1303 OOMPH_EXCEPTION_LOCATION);
1311 file_out <<
"</DataArray>\n";
1315 file_out <<
"</PointData>\n";
1323 <<
"<DataArray type=\"Float32\"" 1324 <<
" NumberOfComponents=\"" 1327 <<
"format=\"ascii\">\n";
1330 for(
unsigned i=0;
i<number_of_elements;
i++)
1339 std::stringstream error_stream;
1341 <<
"Recast for element " <<
i <<
" faild" << std::endl;
1344 OOMPH_CURRENT_FUNCTION,
1345 OOMPH_EXCEPTION_LOCATION);
1362 <<
"<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1369 for(
unsigned i=0;
i<number_of_elements;
i++)
1378 std::stringstream error_stream;
1380 <<
"Recast for element " <<
i <<
" faild" << std::endl;
1383 OOMPH_CURRENT_FUNCTION,
1384 OOMPH_EXCEPTION_LOCATION);
1390 file_out <<
"</DataArray>\n" 1391 <<
"<DataArray type=\"Int32\" " 1392 <<
"Name=\"offsets\" format=\"ascii\">\n";
1395 unsigned offset_sum=0;
1398 for(
unsigned i=0;
i<number_of_elements;
i++)
1407 std::stringstream error_stream;
1409 <<
"Recast for element " <<
i <<
" failed" << std::endl;
1412 OOMPH_CURRENT_FUNCTION,
1413 OOMPH_EXCEPTION_LOCATION);
1419 file_out <<
"</DataArray>\n" 1420 <<
"<DataArray type=\"UInt8\" Name=\"types\">\n";
1423 for(
unsigned i=0;
i<number_of_elements;
i++)
1432 std::stringstream error_stream;
1434 <<
"Recast for element " <<
i <<
" failed" << std::endl;
1437 OOMPH_CURRENT_FUNCTION,
1438 OOMPH_EXCEPTION_LOCATION);
1445 file_out <<
"</DataArray>\n" 1451 file_out <<
"</Piece>\n" 1452 <<
"</UnstructuredGrid>\n" 1466 const unsigned &nplot,
1471 file_out.setf(std::ios_base::uppercase);
1474 unsigned long number_of_elements=this->
Element_pt.size();
1483 "Recast for FiniteElement failed for element 0!\n",
1484 OOMPH_CURRENT_FUNCTION,
1485 OOMPH_EXCEPTION_LOCATION);
1494 for(
unsigned i=1;
i<number_of_elements;
i++)
1498 if(el_zero_ndof!=el_i_ndof)
1500 std::stringstream error_stream;
1502 <<
"Element " <<
i <<
" has different number of degrees of freedom\n" 1503 <<
"than from previous elements, Paraview cannot handle this.\n" 1504 <<
"We suggest that the problem is broken up into submeshes instead." 1508 OOMPH_CURRENT_FUNCTION,
1509 OOMPH_EXCEPTION_LOCATION);
1515 unsigned long number_of_nodes=0;
1516 unsigned long total_number_of_elements=0;
1519 for(
unsigned i=0;
i<number_of_elements;
i++)
1528 std::stringstream error_stream;
1530 <<
"Recast for element " <<
i <<
" failed" << std::endl;
1533 OOMPH_CURRENT_FUNCTION,
1534 OOMPH_EXCEPTION_LOCATION);
1550 <<
"<?xml version=\"1.0\"?>\n" 1551 <<
"<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" " 1552 <<
"byte_order=\"LittleEndian\">\n" 1553 <<
"<UnstructuredGrid>\n" 1554 <<
"<Piece NumberOfPoints=\"" 1556 <<
"\" NumberOfCells=\"" 1557 << total_number_of_elements
1568 file_out <<
"<PointData ";
1573 file_out <<
"Scalars=\"" 1578 for(
unsigned i=0;
i<ndof;
i++)
1580 file_out <<
"<DataArray type=\"Float32\" " 1584 <<
"format=\"ascii\"" 1587 for(
unsigned j=0;j<number_of_elements;j++)
1596 std::stringstream error_stream;
1598 <<
"Recast for element " << j <<
" failed" << std::endl;
1601 OOMPH_CURRENT_FUNCTION,
1602 OOMPH_EXCEPTION_LOCATION);
1610 file_out <<
"</DataArray>\n";
1614 file_out <<
"</PointData>\n";
1622 <<
"<DataArray type=\"Float32\"" 1623 <<
" NumberOfComponents=\"" 1626 <<
"format=\"ascii\">\n";
1629 for(
unsigned i=0;
i<number_of_elements;
i++)
1638 std::stringstream error_stream;
1640 <<
"Recast for element " <<
i <<
" faild" << std::endl;
1643 OOMPH_CURRENT_FUNCTION,
1644 OOMPH_EXCEPTION_LOCATION);
1661 <<
"<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1668 for(
unsigned i=0;
i<number_of_elements;
i++)
1677 std::stringstream error_stream;
1679 <<
"Recast for element " <<
i <<
" faild" << std::endl;
1682 OOMPH_CURRENT_FUNCTION,
1683 OOMPH_EXCEPTION_LOCATION);
1689 file_out <<
"</DataArray>\n" 1690 <<
"<DataArray type=\"Int32\" " 1691 <<
"Name=\"offsets\" format=\"ascii\">\n";
1694 unsigned offset_sum=0;
1697 for(
unsigned i=0;
i<number_of_elements;
i++)
1706 std::stringstream error_stream;
1708 <<
"Recast for element " <<
i <<
" failed" << std::endl;
1711 OOMPH_CURRENT_FUNCTION,
1712 OOMPH_EXCEPTION_LOCATION);
1718 file_out <<
"</DataArray>\n" 1719 <<
"<DataArray type=\"UInt8\" Name=\"types\">\n";
1722 for(
unsigned i=0;
i<number_of_elements;
i++)
1731 std::stringstream error_stream;
1733 <<
"Recast for element " <<
i <<
" failed" << std::endl;
1736 OOMPH_CURRENT_FUNCTION,
1737 OOMPH_EXCEPTION_LOCATION);
1744 file_out <<
"</DataArray>\n" 1750 file_out <<
"</Piece>\n" 1751 <<
"</UnstructuredGrid>\n" 1765 unsigned long Element_pt_range =
Element_pt.size();
1766 for(
unsigned long e=0;
e<Element_pt_range;
e++)
1772 oomph_info <<
"Can't execute output(...) for non FiniteElements" 1777 #ifdef OOMPH_HAS_MPI 1783 #ifdef OOMPH_HAS_MPI 1807 unsigned long Element_pt_range =
Element_pt.size();
1809 for(
unsigned long e=0;
e<Element_pt_range;
e++)
1815 oomph_info <<
"Can't execute output(...) for non FiniteElements" 1820 #ifdef OOMPH_HAS_MPI 1824 el_pt->
output(outfile,n_plot);
1826 #ifdef OOMPH_HAS_MPI 1831 el_pt->
output(outfile,n_plot);
1854 unsigned long Element_pt_range =
Element_pt.size();
1855 for(
unsigned long e=0;
e<Element_pt_range;
e++)
1861 oomph_info <<
"Can't execute output(...) for non FiniteElements" 1866 #ifdef OOMPH_HAS_MPI 1872 #ifdef OOMPH_HAS_MPI 1897 unsigned long Element_pt_range =
Element_pt.size();
1898 for(
unsigned long e=0;
e<Element_pt_range;
e++)
1904 oomph_info <<
"Can't execute output(...) for non FiniteElements" 1909 #ifdef OOMPH_HAS_MPI 1913 el_pt->
output(file_pt,n_plot);
1915 #ifdef OOMPH_HAS_MPI 1920 el_pt->
output(file_pt,n_plot);
1941 unsigned long Element_pt_range =
Element_pt.size();
1942 for(
unsigned long e=0;
e<Element_pt_range;
e++)
1948 oomph_info <<
"Can't execute output_fct(...) for non FiniteElements" 1953 #ifdef OOMPH_HAS_MPI 1957 el_pt->
output_fct(outfile,n_plot,exact_soln_pt);
1959 #ifdef OOMPH_HAS_MPI 1964 el_pt->
output_fct(outfile,n_plot,exact_soln_pt);
1985 unsigned long Element_pt_range =
Element_pt.size();
1986 for(
unsigned long e=0;
e<Element_pt_range;
e++)
1992 oomph_info <<
"Can't execute output_fct(...) for non FiniteElements" 1997 #ifdef OOMPH_HAS_MPI 2001 el_pt->
output_fct(outfile,n_plot,time,exact_soln_pt);
2003 #ifdef OOMPH_HAS_MPI 2008 el_pt->
output_fct(outfile,n_plot,time,exact_soln_pt);
2027 for(
unsigned long e=0;
e<Nelement;
e++)
2030 unsigned Ninternal =
element_pt(
e)->ninternal_data();
2033 for(
unsigned j=0;j<Ninternal;j++)
2035 element_pt(
e)->internal_data_pt(j)->time_stepper_pt()->
2041 unsigned long n_node=
nnode();
2042 for (
unsigned long n=0;n<n_node;n++)
2045 Node_pt[n]->time_stepper_pt()->
2048 Node_pt[n]->position_time_stepper_pt()->
2049 assign_initial_positions_impulsive(
Node_pt[n]);
2063 const unsigned long Nelement=
nelement();
2064 for (
unsigned long e=0;
e<Nelement;
e++)
2067 const unsigned Ninternal =
element_pt(
e)->ninternal_data();
2070 for(
unsigned j=0;j<Ninternal;j++)
2072 element_pt(
e)->internal_data_pt(j)->time_stepper_pt()->
2078 const unsigned long n_node=
nnode();
2079 for (
unsigned long n=0;n<n_node;n++)
2085 Node_pt[n]->position_time_stepper_pt()->shift_time_positions(
Node_pt[n]);
2102 const unsigned long Nelement=
nelement();
2103 for (
unsigned long e=0;
e<Nelement;
e++)
2106 const unsigned Ninternal =
element_pt(
e)->ninternal_data();
2109 for(
unsigned j=0;j<Ninternal;j++)
2111 element_pt(
e)->internal_data_pt(j)->time_stepper_pt()->
2112 calculate_predicted_values(
element_pt(
e)->internal_data_pt(j));
2117 const unsigned long n_node=
nnode();
2118 for (
unsigned long n=0;n<n_node;n++)
2121 Node_pt[n]->time_stepper_pt()->calculate_predicted_values(
Node_pt[n]);
2123 Node_pt[n]->position_time_stepper_pt()->
2124 calculate_predicted_positions(
Node_pt[n]);
2133 const bool &preserve_existing_data)
2138 std::ostringstream warning_stream;
2140 "Empty set_mesh_level_time_stepper() has been called.\n" 2142 "This function needs to be overloaded to reset any (pointers to) \n" 2144 "timesteppers for meshes that store timesteppers in locations other\n" 2145 <<
"than the Nodes or Elements;\n" 2146 <<
"e.g. SpineMeshes have SpineData with timesteppers,\n" 2148 "Triangle and TetMeshes store the timestepper for use in adaptivity.\n\n\n";
2149 warning_stream <<
"If you are solving a continuation or bifurcation detecion\n" 2150 <<
"problem and strange things are happening, then check that\n" 2151 <<
"you don't need to overload this function for your mesh." 2152 <<
"\n This warning can be suppressed by setting:\n" 2154 "Mesh::Suppress_warning_about_empty_mesh_level_time_stepper_function=true" 2157 OOMPH_CURRENT_FUNCTION,
2158 OOMPH_EXCEPTION_LOCATION);
2171 const unsigned long n_node=this->
nnode();
2172 for(
unsigned long n=0;n<n_node;n++)
2179 const unsigned long n_element=this->
nelement();
2180 for (
unsigned long e=0;
e<n_element;
e++)
2188 for(
unsigned j=0;j<n_internal;j++)
2190 continuation_storage_pt->
2204 const unsigned long n_node=this->
nnode();
2205 for(
unsigned long n=0;n<n_node;n++)
2209 (this->
Node_pt[n]->does_pointer_correspond_to_value(parameter_pt))
2211 (this->
Node_pt[n]->does_pointer_correspond_to_position_data(parameter_pt)))
2216 const unsigned long n_element=this->
nelement();
2217 for (
unsigned long e=0;
e<n_element;
e++)
2226 for(
unsigned j=0;j<n_internal;j++)
2245 const bool &preserve_existing_data)
2248 const unsigned long n_node=this->
nnode();
2249 for(
unsigned long n=0;n<n_node;n++)
2252 this->
Node_pt[n]->set_time_stepper(time_stepper_pt,preserve_existing_data);
2253 this->
Node_pt[n]->set_position_time_stepper(time_stepper_pt,
2254 preserve_existing_data);
2263 TimeStepper*
const &time_stepper_pt,
const bool &preserve_existing_data)
2266 const unsigned long n_element=this->
nelement();
2267 for (
unsigned long e=0;
e<n_element;
e++)
2270 const unsigned n_internal = this->
element_pt(
e)->ninternal_data();
2273 for(
unsigned j=0;j<n_internal;j++)
2276 ->set_time_stepper(time_stepper_pt,preserve_existing_data);
2322 if (dynamic_cast<BoundaryNodeBase*>(node_pt)!=0)
2332 std::list<std::pair<unsigned long, int> >
2333 list_of_elements_and_local_node_numbers;
2336 unsigned long n_element=this->
nelement();
2337 for(
unsigned long e=0;
e<n_element;
e++)
2345 int node_number = finite_element_pt[
e]->get_node_number(node_pt);
2350 list_of_elements_and_local_node_numbers.insert(
2351 list_of_elements_and_local_node_numbers.end(),
2352 std::make_pair(
e,node_number));
2354 finite_element_pt[
e]->node_pt(node_number)=0;
2360 if(list_of_elements_and_local_node_numbers.empty())
2362 std::ostringstream error_stream;
2363 error_stream <<
"Node " << node_pt
2364 <<
" is not contained in any elements in the Mesh." 2366 <<
"How was it created then?" << std::endl;
2369 OOMPH_CURRENT_FUNCTION,
2370 OOMPH_EXCEPTION_LOCATION);
2381 std::list<std::pair<unsigned long,int> >::iterator list_it
2382 = list_of_elements_and_local_node_numbers.begin();
2386 Node* new_node_pt = finite_element_pt[list_it->first]
2387 ->construct_boundary_node(list_it->second,node_pt->
time_stepper_pt());
2394 if(solid_node_pt!=0)
2396 solid_node_pt->
copy(dynamic_cast<SolidNode*>(old_node_pt));
2400 new_node_pt->
copy(old_node_pt);
2406 list_it!=list_of_elements_and_local_node_numbers.end();
2409 finite_element_pt[list_it->first]->node_pt(list_it->second)
2418 if(it!=
Node_pt.end()) {*it = new_node_pt;}
2427 node_pt = new_node_pt;
2431 #ifdef OOMPH_HAS_MPI 2448 double t_start = 0.0;
2456 int my_rank=
Comm_pt->my_rank();
2461 for (
int d=0;d<n_proc;d++)
2466 std::map<Node*,bool> node_shared;
2475 unsigned nhalo_elem=halo_elem_pt.size();
2477 for (
unsigned e=0;
e<nhalo_elem;
e++)
2484 unsigned nnod=el_pt->
nnode();
2485 for (
unsigned j=0;j<nnod;j++)
2490 if (!node_shared[nod_pt])
2493 node_shared[nod_pt]=
true;
2503 unsigned nhaloed_elem=haloed_elem_pt.size();
2505 for (
unsigned e=0;
e<nhaloed_elem;
e++)
2512 unsigned nnod=el_pt->
nnode();
2513 for (
unsigned j=0;j<nnod;j++)
2518 if (!node_shared[nod_pt])
2521 node_shared[nod_pt]=
true;
2537 unsigned nhaloed_elem=haloed_elem_pt.size();
2539 for (
unsigned e=0;
e<nhaloed_elem;
e++)
2546 unsigned nnod=el_pt->
nnode();
2547 for (
unsigned j=0;j<nnod;j++)
2552 if (!node_shared[nod_pt])
2555 node_shared[nod_pt]=
true;
2564 unsigned nhalo_elem=halo_elem_pt.size();
2566 for (
unsigned e=0;
e<nhalo_elem;
e++)
2573 unsigned nnod=el_pt->
nnode();
2574 for (
unsigned j=0;j<nnod;j++)
2579 if (!node_shared[nod_pt])
2582 node_shared[nod_pt]=
true;
2598 oomph_info <<
"Time for identification of shared nodes: " 2599 << t_end-t_start << std::endl;
2627 double tt_start=0.0;
2636 int my_rank=
Comm_pt->my_rank();
2645 "Processor has shared nodes with itself! Something's gone wrong!",
2646 OOMPH_CURRENT_FUNCTION,
2647 OOMPH_EXCEPTION_LOCATION);
2654 std::map<Node*,std::set<int> > shared_domain_set;
2657 std::map<Node*,unsigned> global_haloed_node_number_plus_one;
2658 unsigned global_haloed_count=0;
2661 for (
int d=0;d<n_proc;d++)
2668 for (
unsigned j=0;j<nnod_haloed;j++)
2671 shared_domain_set[nod_pt].insert(d);
2672 if (global_haloed_node_number_plus_one[nod_pt]==0)
2674 global_haloed_node_number_plus_one[nod_pt]=global_haloed_count+1;
2675 global_haloed_count++;
2685 <<
"Time for initial classification in Mesh::synchronise_shared_nodes(): " 2686 << tt_end-tt_start << std::endl;
2708 for (
int domain=0;domain<n_proc;domain++)
2711 send_displacement[domain] = send_data.size();
2722 for (
unsigned j=0;j<nnod_haloed;j++)
2727 send_data.push_back(global_haloed_node_number_plus_one[nod_pt]-1);
2730 std::set<int> tmp_shared_domain_set=shared_domain_set[nod_pt];
2733 unsigned n_shared_domains= tmp_shared_domain_set.size();
2734 send_data.push_back(n_shared_domains);
2737 for (std::set<int>::iterator it=tmp_shared_domain_set.begin();
2738 it!=tmp_shared_domain_set.end();it++)
2740 send_data.push_back(*it);
2746 send_n[domain] = send_data.size() - send_displacement[domain];
2756 MPI_Alltoall(&send_n[0],1,MPI_INT,&receive_n[0],1,MPI_INT,
2763 int receive_data_count=0;
2764 for(
int rank=0;rank<n_proc;++rank)
2767 receive_displacement[rank] = receive_data_count;
2768 receive_data_count += receive_n[rank];
2773 if(receive_data_count==0) {++receive_data_count;}
2778 if(send_data.size()==0) {send_data.resize(1);}
2781 MPI_Alltoallv(&send_data[0],&send_n[0],&send_displacement[0],
2783 &receive_data[0],&receive_n[0],
2784 &receive_displacement[0],
2793 <<
"Time for alltoall in Mesh::synchronise_shared_nodes(): " 2794 << tt_end-tt_start << std::endl;
2802 <<
"Starting vector to set conversion in " 2803 <<
"Mesh::synchronise_shared_nodes() for a total of " 2812 for (
int d=0;d<n_proc;d++)
2815 for (
unsigned i=0;
i<n_vector;
i++)
2826 <<
"Time for vector to set in Mesh::synchronise_shared_nodes(): " 2827 << tt_end-tt_start << std::endl;
2833 for (
int send_rank=0;send_rank<n_proc;send_rank++)
2837 if((send_rank != my_rank) && (receive_n[send_rank] != 0))
2840 unsigned count=receive_displacement[send_rank];
2850 std::map<unsigned,std::pair<Node*,std::set<unsigned> > > domains_map;
2853 unsigned nnod_halo=this->
nhalo_node(send_rank);
2854 for (
unsigned j=0;j<nnod_halo;j++)
2859 unsigned haloed_node_id_on_send_proc=receive_data[count++];
2862 unsigned n_shared_domains=receive_data[count++];
2865 std::set<unsigned> domain_set;
2868 for (
unsigned i=0;
i<n_shared_domains;
i++)
2870 int shared_domain=receive_data[count++];
2873 domain_set.insert(shared_domain);
2877 domains_map[haloed_node_id_on_send_proc]=std::make_pair(nod_pt,
2886 int previous_one=-1;
2888 for (std::map<
unsigned,std::pair<
Node*,std::set<unsigned> > >::iterator
2889 it=domains_map.begin();it!=domains_map.end();it++)
2895 if (
int((*it).first)<previous_one)
2897 std::ostringstream error_stream;
2898 error_stream <<
"Map did not store entries in order of key\n " 2899 <<
"Current key: " << (*it).first
2900 <<
"; previous one: " << previous_one <<
"\n" 2901 <<
"Need to rewrite this...\n";
2903 OOMPH_CURRENT_FUNCTION,
2904 OOMPH_EXCEPTION_LOCATION);
2906 previous_one=(*it).first;
2910 Node* nod_pt=(*it).second.first;
2913 std::set<unsigned> domain_set((*it).second.second);
2916 for (std::set<unsigned>::iterator itt=domain_set.begin();
2917 itt!=domain_set.end();itt++)
2919 int shared_domain=(*itt);
2922 if (shared_domain!=my_rank)
2926 std::set<Node*>::iterator ittt=
2927 shared_node_set[shared_domain].find(nod_pt);
2931 if (ittt==shared_node_set[shared_domain].end())
2937 shared_node_set[shared_domain].insert(nod_pt);
2955 "Processor has shared nodes with itself! Something's gone wrong!",
2956 OOMPH_CURRENT_FUNCTION,
2957 OOMPH_EXCEPTION_LOCATION);
2966 <<
"Time for final processing in Mesh::synchronise_shared_nodes(): " 2967 << tt_end-tt_start << std::endl;
2974 oomph_info <<
"Total time for Mesh::synchronise_shared_nodes(): " 2975 << t_end-t_start << std::endl;
2985 const bool& report_stats)
2992 double t_start = 0.0;
2998 double tt_start = 0.0;
3014 <<
"Time for Mesh::setup_shared_node_scheme() " 3015 <<
" Mesh::classify_halo_and_haloed_nodes(): " 3016 << tt_end-tt_start << std::endl;
3028 int my_rank=
Comm_pt->my_rank();
3033 std::map<Data*,std::set<unsigned> > processors_associated_with_data;
3034 std::map<Data*,unsigned> processor_in_charge;
3038 for (
int domain=0;domain<n_proc;domain++)
3044 unsigned nelem=halo_elem_pt.size();
3045 for (
unsigned e=0;
e<nelem;
e++)
3052 unsigned nnod=finite_el_pt->
nnode();
3053 for (
unsigned j=0;j<nnod;j++)
3057 processors_associated_with_data[nod_pt].insert(domain);
3061 if (solid_nod_pt!=0)
3063 processors_associated_with_data[
3075 for (
unsigned e=0;
e<nelem;
e++)
3081 if((finite_el_pt!=0) && (!finite_el_pt->
is_halo()))
3084 unsigned nnod=finite_el_pt->
nnode();
3085 for (
unsigned j=0;j<nnod;j++)
3090 processors_associated_with_data[nod_pt].insert(my_rank);
3094 if (solid_nod_pt!=0)
3096 processors_associated_with_data
3108 <<
"Time for setup loops in Mesh::classify_halo_and_haloed_nodes: " 3109 << tt_end-tt_start << std::endl;
3125 for (
int d=0;d<n_proc;d++)
3138 unsigned count_data=0;
3141 unsigned n_haloed_elem=haloed_elem_pt.size();
3142 for (
unsigned e=0;
e<n_haloed_elem;
e++)
3150 unsigned n_node=haloed_el_pt->
nnode();
3151 for (
unsigned j=0;j<n_node;j++)
3156 unsigned n_assoc=processors_associated_with_data[nod_pt].size();
3159 processors_associated_with_data_on_other_proc.push_back(n_assoc);
3163 std::set<unsigned> procs_set=
3164 processors_associated_with_data[nod_pt];
3165 for (std::set<unsigned>::iterator it=procs_set.begin();
3166 it!=procs_set.end();it++)
3168 processors_associated_with_data_on_other_proc.push_back(*it);
3178 MPI_Send(&count_data,1,MPI_UNSIGNED,d,0,
Comm_pt->mpi_comm());
3181 MPI_Send(&processors_associated_with_data_on_other_proc[0],count_data,
3182 MPI_UNSIGNED,d,1,
Comm_pt->mpi_comm());
3188 for (
int dd=0;dd<n_proc;dd++)
3194 unsigned n_halo_elem=halo_elem_pt.size();
3195 unsigned count_data=0;
3196 MPI_Recv(&count_data,1,MPI_UNSIGNED,dd,0,
Comm_pt->mpi_comm(),&status);
3199 processors_associated_with_data_on_other_proc.resize(count_data);
3200 MPI_Recv(&processors_associated_with_data_on_other_proc[0],
3201 count_data,MPI_UNSIGNED,dd,1,
Comm_pt->mpi_comm(),&status);
3205 for (
unsigned e=0;
e<n_halo_elem;
e++)
3211 unsigned n_node=halo_el_pt->
nnode();
3212 for (
unsigned j=0;j<n_node;j++)
3218 processors_associated_with_data_on_other_proc[count_data];
3221 for (
unsigned i_assoc=0;i_assoc<n_assoc;i_assoc++)
3224 unsigned sent_domain=
3225 processors_associated_with_data_on_other_proc[count_data];
3229 processors_associated_with_data[nod_pt].insert(sent_domain);
3233 if (solid_nod_pt!=0)
3235 processors_associated_with_data
3237 insert(sent_domain);
3253 <<
"Time for pt2pt send/recv in Mesh::classify_halo_and_haloed_nodes: " 3254 << tt_end-tt_start << std::endl;
3264 unsigned nnod=this->
nnode();
3265 for (
unsigned j=0;j<nnod;j++)
3275 if (solid_nod_pt!=0)
3281 unsigned proc_max=0;
3282 std::set<unsigned> procs_set=processors_associated_with_data[nod_pt];
3283 for (std::set<unsigned>::iterator it=procs_set.begin();
3284 it!=procs_set.end();it++)
3286 if (*it>proc_max) proc_max=*it;
3288 processor_in_charge[nod_pt]=proc_max;
3291 if (solid_nod_pt!=0)
3294 unsigned proc_max_solid=0;
3295 std::set<unsigned> procs_set_solid=processors_associated_with_data
3297 for (std::set<unsigned>::iterator it=procs_set_solid.begin();
3298 it!=procs_set_solid.end();it++)
3300 if (*it>proc_max_solid) proc_max_solid=*it;
3312 std::map<Node*,bool> done;
3315 for (
int domain=0;domain<n_proc;domain++)
3321 unsigned nelem=halo_elem_pt.size();
3323 for (
unsigned e=0;
e<nelem;
e++)
3333 unsigned nnod=finite_el_pt->
nnode();
3334 for (
unsigned j=0;j<nnod;j++)
3342 int proc_in_charge=processor_in_charge[nod_pt];
3344 if (proc_in_charge!=my_rank)
3350 if (proc_in_charge==
int(domain))
3357 nod_pt->set_halo(proc_in_charge);
3362 if (solid_nod_pt!=0)
3365 set_halo(proc_in_charge);
3379 for (
unsigned iintern=0;iintern<nintern_data;iintern++)
3391 for (
int domain=0;domain<n_proc;domain++)
3394 std::map<Node*,bool> node_done;
3400 unsigned nelem=haloed_elem_pt.size();
3402 for (
unsigned e=0;
e<nelem;
e++)
3412 unsigned nnod=finite_el_pt->
nnode();
3413 for (
unsigned j=0;j<nnod;j++)
3418 if (!node_done[nod_pt])
3421 int proc_in_charge=processor_in_charge[nod_pt];
3423 if (proc_in_charge==my_rank)
3429 node_done[nod_pt]=
true;
3443 <<
"Time for first classific in Mesh::classify_halo_and_haloed_nodes: " 3444 << tt_end-tt_start << std::endl;
3471 unsigned n_overlooked_halo=0;
3491 for (
int domain=0;domain<n_proc;domain++)
3494 send_displacement[domain] = send_data.size();
3501 for (
unsigned j=0;j<nnod;j++)
3506 int proc_in_charge=processor_in_charge[nod_pt];
3507 if ((proc_in_charge!=my_rank)&&!(nod_pt->
is_halo()))
3514 n_overlooked_halo++;
3515 over_looked_halo_node_pt[proc_in_charge].push_back(nod_pt);
3523 if (solid_nod_pt!=0)
3531 send_data.push_back(j);
3532 send_data.push_back(proc_in_charge);
3538 send_data.push_back(-1);
3541 send_n[domain] = send_data.size() - send_displacement[domain];
3547 unsigned global_max_n_overlooked_halo=0;
3548 MPI_Allreduce(&n_overlooked_halo,&global_max_n_overlooked_halo,1,
3549 MPI_UNSIGNED,MPI_MAX,
3553 oomph_info <<
"Global max number of overlooked haloes: " 3554 << global_max_n_overlooked_halo << std::endl;
3560 <<
"Time for setup 1st alltoalls in Mesh::classify_halo_and_haloed_nodes: " 3561 << tt_end-tt_start << std::endl;
3569 if (global_max_n_overlooked_halo>0)
3578 MPI_Alltoall(&send_n[0],1,MPI_INT,&receive_n[0],1,MPI_INT,
3587 <<
"Time for 1st alltoall in Mesh::classify_halo_and_haloed_nodes: " 3588 << tt_end-tt_start << std::endl;
3599 int receive_data_count=0;
3600 for(
int rank=0;rank<n_proc;++rank)
3603 receive_displacement[rank] = receive_data_count;
3604 receive_data_count += receive_n[rank];
3609 if(receive_data_count==0) {++receive_data_count;}
3614 if(send_data.size()==0) {send_data.resize(1);}
3617 MPI_Alltoallv(&send_data[0],&send_n[0],&send_displacement[0],
3619 &receive_data[0],&receive_n[0],
3620 &receive_displacement[0],
3630 <<
"Time for 2nd alltoall in Mesh::classify_halo_and_haloed_nodes: " 3631 << tt_end-tt_start << std::endl;
3643 for (
int send_rank=0;send_rank<n_proc;send_rank++)
3647 if((send_rank != my_rank) && (receive_n[send_rank] != 0))
3650 unsigned count=receive_displacement[send_rank];
3657 int next_one=receive_data[count++];
3667 unsigned j=unsigned(next_one);
3670 unsigned proc_in_charge=unsigned(receive_data[count++]);
3686 for (
unsigned jj=0;jj<nnod;jj++)
3694 send_data_for_proc_in_charge[proc_in_charge].push_back(jj);
3697 send_data_for_proc_in_charge[proc_in_charge].push_back(
3706 std::ostringstream error_stream;
3707 error_stream <<
"Failed to find node that is shared node " << j
3708 <<
" (with processor " << send_rank
3709 <<
") \n in shared node lookup scheme with processor " 3710 << proc_in_charge <<
" which is in charge.\n";
3712 OOMPH_CURRENT_FUNCTION,
3713 OOMPH_EXCEPTION_LOCATION);
3726 <<
"Time for 1st setup 3rd alltoall in Mesh::classify_halo_and_haloed_nodes: " 3727 << tt_end-tt_start << std::endl;
3744 for (
int domain=0;domain<n_proc;domain++)
3747 all_send_displacement[domain] = all_send_data.size();
3753 unsigned n=send_data_for_proc_in_charge[domain].size();
3754 for (
unsigned j=0;j<n;j++)
3756 all_send_data.push_back(
3757 send_data_for_proc_in_charge[domain][j]);
3762 all_send_data.push_back(-1);
3765 all_send_n[domain]=all_send_data.size()-all_send_displacement[domain];
3773 <<
"Time for 2nd setup 3rd alltoall in Mesh::classify_halo_and_haloed_nodes: " 3774 << tt_end-tt_start << std::endl;
3785 MPI_Alltoall(&all_send_n[0],1,MPI_INT,&all_receive_n[0],1,MPI_INT,
3794 <<
"Time for 3rd alltoall in Mesh::classify_halo_and_haloed_nodes: " 3795 << tt_end-tt_start << std::endl;
3805 int all_receive_data_count=0;
3807 for(
int rank=0;rank<n_proc;++rank)
3810 all_receive_displacement[rank] = all_receive_data_count;
3811 all_receive_data_count += all_receive_n[rank];
3816 if (all_receive_data_count==0) {++all_receive_data_count;}
3817 Vector<int> all_receive_data(all_receive_data_count);
3821 if(all_send_data.size()==0) {all_send_data.resize(1);}
3824 MPI_Alltoallv(&all_send_data[0],&all_send_n[0],&all_send_displacement[0],
3826 &all_receive_data[0],&all_receive_n[0],
3827 &all_receive_displacement[0],
3836 <<
"Time for 4th alltoall in Mesh::classify_halo_and_haloed_nodes: " 3837 << tt_end-tt_start << std::endl;
3846 for (
int send_rank=0;send_rank<n_proc;send_rank++)
3850 if((send_rank != my_rank) && (all_receive_n[send_rank] != 0))
3853 unsigned count=all_receive_displacement[send_rank];
3860 int next_one=all_receive_data[count++];
3870 unsigned j=unsigned(next_one);
3876 unsigned proc_with_overlooked_halo=all_receive_data[count++];
3883 over_looked_haloed_node_pt[proc_with_overlooked_halo].
3894 <<
"Time for postproc 4th alltoall in Mesh::classify_halo_and_haloed_nodes: " 3895 << tt_end-tt_start << std::endl;
3904 for (
int d=0;d<n_proc;d++)
3911 unsigned nnod=over_looked_halo_node_pt[d].size();
3912 for (
unsigned j=0;j<nnod;j++)
3916 nnod=over_looked_haloed_node_pt[d].size();
3917 for (
unsigned j=0;j<nnod;j++)
3925 unsigned nnod=over_looked_haloed_node_pt[d].size();
3926 for (
unsigned j=0;j<nnod;j++)
3930 nnod=over_looked_halo_node_pt[d].size();
3931 for (
unsigned j=0;j<nnod;j++)
3943 oomph_info <<
"BEFORE SYNCHRONISE SHARED NODES Processor " << my_rank
3944 <<
" holds " << this->
nnode()
3948 <<
" are shared nodes." << std::endl;
3952 for (
int iproc=0;iproc<n_proc;iproc++)
3958 oomph_info <<
"With process " << iproc <<
", there are " 3959 << this->
nhalo_node(iproc) <<
" halo nodes, and " << std::endl
3961 << this->
nshared_node(iproc) <<
" shared nodes" << std::endl
3962 << halo_elem_pt.size() <<
" halo elements and " 3963 << haloed_elem_pt.size() <<
" haloed elements\n";
4010 "Processor has haloed nodes with itself! Something's gone wrong!",
4011 OOMPH_CURRENT_FUNCTION,
4012 OOMPH_EXCEPTION_LOCATION);
4018 "Processor has halo nodes with itself! Something's gone wrong!",
4019 OOMPH_CURRENT_FUNCTION,
4020 OOMPH_EXCEPTION_LOCATION);
4026 "Processor has root haloed elements with itself! Something's gone wrong!",
4027 OOMPH_CURRENT_FUNCTION,
4028 OOMPH_EXCEPTION_LOCATION);
4034 "Processor has root halo elements with itself! Something's gone wrong!",
4035 OOMPH_CURRENT_FUNCTION,
4036 OOMPH_EXCEPTION_LOCATION);
4045 <<
" holds " << this->
nnode()
4049 <<
" are shared nodes." << std::endl;
4053 for (
int iproc=0;iproc<n_proc;iproc++)
4059 oomph_info <<
"With process " << iproc <<
", there are " 4060 << this->
nhalo_node(iproc) <<
" halo nodes, and " << std::endl
4062 << this->
nshared_node(iproc) <<
" shared nodes" << std::endl
4063 << halo_elem_pt.size() <<
" halo elements and " 4064 << haloed_elem_pt.size() <<
" haloed elements\n";
4085 oomph_info <<
"Total time for Mesh::classify_halo_and_halo_nodes(): " 4086 << t_end-t_start << std::endl;
4110 double t_start = 0.0;
4124 int my_rank=
Comm_pt->my_rank();
4127 for (
int d=0;d<n_proc;d++)
4134 for (
int dd=0;dd<n_proc;dd++)
4143 if ((nnod_halo+nnod_ext_halo)!=0)
4149 MPI_Recv(&tmp[0],3,MPI_INT,dd,0,
Comm_pt->mpi_comm(),&status);
4153 int nnod_haloed=tmp[0];
4154 if (nnod_haloed!=nnod_halo)
4156 std::ostringstream error_message;
4158 <<
"Clash in numbers of halo and haloed nodes " 4161 <<
" between procs " 4162 << dd <<
" and " << d <<
": " 4163 << nnod_haloed <<
" " << nnod_halo << std::endl;
4165 OOMPH_CURRENT_FUNCTION,
4166 OOMPH_EXCEPTION_LOCATION);
4170 int nnod_ext_haloed=tmp[1];
4171 if (nnod_ext_haloed!=nnod_ext_halo)
4173 std::ostringstream error_message;
4175 <<
"Clash in numbers of external halo and haloed nodes " 4178 <<
" between procs " 4179 << dd <<
" and " << d <<
": " 4180 << nnod_ext_haloed <<
" " << nnod_ext_halo << std::endl;
4182 OOMPH_CURRENT_FUNCTION,
4183 OOMPH_EXCEPTION_LOCATION);
4188 unsigned n_rec=tmp[2];
4192 MPI_Recv(&unsigned_rec_data[0],n_rec,MPI_UNSIGNED,dd,
4193 0,
Comm_pt->mpi_comm(),&status);
4199 for (
unsigned loop=0;loop<2;loop++)
4201 unsigned hi_nod=nnod_halo;
4204 hi_nod=nnod_ext_halo;
4206 for (
int j=0;j<int(hi_nod);j++)
4220 unsigned nval_local=nod_pt->
nvalue();
4223 unsigned nval_other=unsigned_rec_data[count++];
4225 if (nval_local!=nval_other)
4227 nod_pt->
resize(nval_other);
4231 unsigned nentry=unsigned_rec_data[count++];
4241 "Failed to cast node to boundary node even though we've received data for boundary node",
4242 OOMPH_CURRENT_FUNCTION,
4243 OOMPH_EXCEPTION_LOCATION);
4248 bool already_existed=
true;
4250 index_of_first_value_assigned_by_face_element_pt()==0)
4253 index_of_first_value_assigned_by_face_element_pt()=
4254 new std::map<unsigned, unsigned>;
4255 already_existed=
false;
4260 std::map<unsigned, unsigned>* map_pt=
4264 for (
unsigned i=0;
i<nentry;
i++)
4267 unsigned first_received=unsigned_rec_data[count++];
4268 unsigned second_received=unsigned_rec_data[count++];
4271 if (already_existed)
4274 if ((*map_pt)[first_received]!=second_received)
4276 std::ostringstream error_message;
4278 <<
"Existing map entry for map entry " 4279 <<
i <<
" for node located at ";
4280 unsigned n=nod_pt->
ndim();
4281 for (
unsigned ii=0;ii<n;ii++)
4283 error_message << nod_pt->
position(ii) <<
" ";
4286 <<
"Key: " << first_received <<
" " 4287 <<
"Local value: " << (*map_pt)[first_received] <<
" " 4288 <<
"Received value: " << second_received << std::endl;
4290 OOMPH_CURRENT_FUNCTION,
4291 OOMPH_EXCEPTION_LOCATION);
4298 (*map_pt)[first_received]=second_received;
4318 tmp[1]=nnod_ext_haloed;
4319 if ((nnod_haloed+nnod_ext_haloed)!=0)
4325 for (
unsigned loop=0;loop<2;loop++)
4327 unsigned hi_nod=nnod_haloed;
4330 hi_nod=nnod_ext_haloed;
4332 for (
int j=0;j<int(hi_nod);j++)
4346 unsigned_send_data.push_back(nod_pt->
nvalue());
4356 unsigned_send_data.push_back(0);
4361 std::map<unsigned, unsigned>* map_pt=
4368 unsigned_send_data.push_back(0);
4374 unsigned_send_data.push_back(map_pt->size());
4377 for (std::map<unsigned, unsigned>::iterator p=
4379 p!=map_pt->end();p++)
4381 unsigned_send_data.push_back((*p).first);
4382 unsigned_send_data.push_back((*p).second);
4390 int n_send=unsigned_send_data.size();
4394 MPI_Send(&tmp[0],3,MPI_INT,d,0,
Comm_pt->mpi_comm());
4397 MPI_Send(&unsigned_send_data[0],n_send,MPI_UNSIGNED,d,0,
4407 oomph_info <<
"Total time for Mesh::resize_halo_nodes(): " 4408 << t_end-t_start << std::endl;
4426 unsigned n_node = (it->second).size();
4428 for(
unsigned n=0;n<n_node;n++)
4432 (it->second)[n]->add_value_pt_to_map(map_of_halo_data);
4443 unsigned n_element = (it->second).size();
4444 for(
unsigned e=0;
e<n_element;
e++)
4459 unsigned nleaf=leaf_pt.size();
4460 for (
unsigned l=0;l<nleaf;l++)
4462 leaf_pt[l]->object_pt()->
4463 add_internal_value_pt_to_map(map_of_halo_data);
4479 unsigned n_node = (it->second).size();
4481 for(
unsigned n=0;n<n_node;n++)
4485 (it->second)[n]->add_value_pt_to_map(map_of_halo_data);
4496 unsigned n_element = (it->second).size();
4497 for(
unsigned e=0;
e<n_element;
e++)
4499 (it->second)[
e]->add_internal_value_pt_to_map(map_of_halo_data);
4515 unsigned& max_number,
4516 unsigned& min_number)
4520 int my_rank=
Comm_pt->my_rank();
4532 MPI_Gather(&nhalo_node_local,1,MPI_INT,
4533 &nhalo_nodes[0],1, MPI_INT,
4543 for (
int i=0;
i<n_proc;
i++)
4545 av_number+=double(nhalo_nodes[
i]);
4546 if (
int(nhalo_nodes[i])>max) max=nhalo_nodes[
i];
4547 if (
int(nhalo_nodes[i])<min) min=nhalo_nodes[
i];
4550 av_number/=double(n_proc);
4554 MPI_Bcast(&max,1,MPI_INT,0,
Comm_pt->mpi_comm());
4555 MPI_Bcast(&min,1,MPI_INT,0,
Comm_pt->mpi_comm());
4556 MPI_Bcast(&av_number,1,MPI_DOUBLE,0,
Comm_pt->mpi_comm());
4570 unsigned& max_number,
4571 unsigned& min_number)
4575 int my_rank=
Comm_pt->my_rank();
4587 MPI_Gather(&nhaloed_node_local,1,MPI_INT,
4588 &nhaloed_nodes[0],1, MPI_INT,
4598 for (
int i=0;
i<n_proc;
i++)
4600 av_number+=double(nhaloed_nodes[
i]);
4601 if (
int(nhaloed_nodes[i])>max) max=nhaloed_nodes[
i];
4602 if (
int(nhaloed_nodes[i])<min) min=nhaloed_nodes[
i];
4605 av_number/=double(n_proc);
4609 MPI_Bcast(&max,1,MPI_INT,0,
Comm_pt->mpi_comm());
4610 MPI_Bcast(&min,1,MPI_INT,0,
Comm_pt->mpi_comm());
4611 MPI_Bcast(&av_number,1,MPI_DOUBLE,0,
Comm_pt->mpi_comm());
4624 const bool& report_stats,
4625 const bool& overrule_keep_as_halo_element_status)
4632 int n_proc=comm_pt->nproc();
4633 int my_rank=comm_pt->my_rank();
4637 unsigned nnod=this->
nnode();
4639 std::ostringstream filename;
4649 for (
int d=0;d<n_proc;d++)
4655 filename << doc_info.
directory() <<
"/domain" 4656 << d <<
"-" << doc_info.
number() <<
".dat";
4657 domain_file[d]=
new std::ofstream(filename.str().c_str());
4661 for (
unsigned e=0;
e<nelem;
e++)
4669 f_el_pt->
output(*domain_file[element_domain[
e]],5);
4673 for (
int d=0;d<n_proc;d++)
4675 domain_file[d]->close();
4676 delete domain_file[d];
4690 std::map<Data*,std::set<unsigned> > processors_associated_with_data;
4691 std::map<Data*,unsigned> processor_in_charge;
4694 for (
unsigned j=0;j<nnod;j++)
4697 processor_in_charge[nod_pt]=0;
4701 for (
unsigned e=0;
e<nelem;
e++)
4708 unsigned el_domain=element_domain[
e];
4711 unsigned nnod=el_pt->
nnode();
4712 for (
unsigned j=0;j<nnod;j++)
4717 if (el_domain>processor_in_charge[nod_pt])
4719 processor_in_charge[nod_pt]=el_domain;
4721 processors_associated_with_data[nod_pt].insert(el_domain);
4734 for (
int d=0;d<n_proc;d++)
4740 filename << doc_info.
directory() <<
"/node" 4741 << d <<
"-" << doc_info.
number() <<
".dat";
4742 node_file[d]=
new std::ofstream(filename.str().c_str());
4746 for (
unsigned j=0;j<nnod;j++)
4749 const unsigned n_dim = nod_pt->
ndim();
4750 for(
unsigned i=0;
i<n_dim;
i++)
4752 *node_file[processor_in_charge[nod_pt]] << nod_pt->
x(
i) <<
" ";
4754 *node_file[processor_in_charge[nod_pt]] <<
"\n";
4756 for (
int d=0;d<n_proc;d++)
4758 node_file[d]->close();
4759 delete node_file[d];
4768 for (
unsigned j=0;j<nnod;j++)
4779 for (
unsigned e=0;
e<nelem;
e++)
4789 const unsigned tmp_nboundary = this->
nboundary();
4800 bool is_a_triangle_mesh_base_mesh =
false;
4801 if (triangle_mesh_pt!=0)
4805 is_a_triangle_mesh_base_mesh =
true;
4808 const unsigned n_regions = triangle_mesh_pt->
nregion();
4811 for (
unsigned ib = 0; ib < tmp_nboundary; ib++)
4817 ntmp_boundary_elements_in_region[ib].resize(n_regions);
4820 for (
unsigned rr = 0 ; rr < n_regions; rr++)
4823 const unsigned region_id =
4829 ntmp_boundary_elements_in_region[ib][rr] =
4836 for (
unsigned e=0;
e<nelem;
e++)
4852 std::vector<bool> element_retained(nelem,
false);
4862 for (
int p=0;p<n_proc;p++)
4864 root_halo_element[p].push_back(-1);
4869 unsigned number_of_retained_elements=0;
4872 nelem=backed_up_el_pt.size();
4873 for (
unsigned e=0;
e<nelem;
e++)
4877 unsigned el_domain=element_domain[
e];
4880 if (el_domain==
unsigned(my_rank))
4883 element_retained[
e]=
true;
4884 number_of_retained_elements++;
4895 if (!overrule_keep_as_halo_element_status)
4899 if (!element_retained[
e])
4901 root_halo_element[el_domain].push_back(e);
4902 element_retained[
e]=
true;
4903 number_of_retained_elements++;
4914 unsigned n_node = finite_el_pt->
nnode();
4915 for (
unsigned n=0;n<n_node;n++)
4920 unsigned keep_it=
false;
4921 for (std::set<unsigned>::iterator
4922 it=processors_associated_with_data[nod_pt].begin();
4923 it!=processors_associated_with_data[nod_pt].end();
4926 if (*it==
unsigned(my_rank))
4939 if (!element_retained[
e])
4941 root_halo_element[el_domain].push_back(e);
4942 element_retained[
e]=
true;
4943 number_of_retained_elements++;
4962 if (is_a_triangle_mesh_base_mesh)
4974 processors_associated_with_data,
4975 overrule_keep_as_halo_element_status);
4992 nelem=backed_up_el_pt.size();
4993 for (
unsigned e=0;
e<nelem;
e++)
4996 if (element_retained[
e])
5015 if (!is_a_triangle_mesh_base_mesh)
5017 deleted_element_pt.push_back(el_pt);
5020 if (is_a_triangle_mesh_base_mesh)
5023 deleted_f_element_pt.push_back(backed_up_f_el_pt[e]);
5037 std::map<unsigned,bool> done;
5039 for (
int d=0;d<n_proc;d++)
5041 nelem=root_halo_element[d].size();
5042 for (
unsigned e=0;
e<nelem;
e++)
5044 int number=root_halo_element[d][
e];
5050 std::ostringstream error_message;
5052 <<
"Have already added element " << number
5053 <<
" as root halo element\n" 5056 OOMPH_CURRENT_FUNCTION,
5057 OOMPH_EXCEPTION_LOCATION);
5077 for (
int p=0;p<n_proc;p++)
5079 nhalo[p]=root_halo_element[p].size();
5084 for (
int p=0;p<n_proc;p++)
5089 MPI_Gather(&nhalo[p], 1, MPI_INT,
5090 &nhaloed[0], 1, MPI_INT,
5091 p,comm_pt->mpi_comm());
5099 unsigned total_number_of_root_haloed_elements=0;
5100 for (
int i_proc=0; i_proc<n_proc; i_proc++)
5102 total_number_of_root_haloed_elements+=nhaloed[i_proc];
5105 start_index[i_proc]=total_number_of_root_haloed_elements-
5117 Vector<int> all_root_haloed_element(total_number_of_root_haloed_elements,
5121 for (
int p=0;p<n_proc;p++)
5126 MPI_Gatherv(&root_halo_element[p][0],
5130 &all_root_haloed_element[0],
5142 comm_pt->mpi_comm());
5151 for (
int d=0;d<n_proc;d++)
5155 std::map<unsigned,bool> done;
5159 unsigned n=nhaloed[d];
5160 for (
unsigned e=0;
e<n;
e++)
5163 int number=all_root_haloed_element[count];
5180 std::ostringstream error_message;
5182 <<
"Have already added element " << number
5183 <<
" as root haloed element\n" 5186 OOMPH_CURRENT_FUNCTION,
5187 OOMPH_EXCEPTION_LOCATION);
5206 <<
" are root halo elements \n while " 5208 <<
" are root haloed elements" << std::endl;
5217 for (
unsigned e=0;
e<nelem;
e++)
5225 unsigned nnod=f_el_pt->
nnode();
5226 for (
unsigned j=0;j<nnod;j++)
5239 #ifdef OOMPH_HAS_TRIANGLE_LIB 5240 if (is_a_triangle_mesh_base_mesh)
5244 ntmp_boundary_elements_in_region,
5245 deleted_f_element_pt);
5249 #endif // #ifdef OOMPH_HAS_TRIANGLE_LIB 5254 #ifdef OOMPH_HAS_TRIANGLE_LIB 5292 const bool& report_stats)
5298 #ifdef OOMPH_HAS_MPI 5311 int my_rank=
Comm_pt->my_rank();
5316 oomph_info <<
"\n----------------------------------------------------\n";
5317 oomph_info <<
"Before pruning: Processor " << my_rank
5320 <<
" are root halo elements \n while " 5322 <<
" are root haloed elements" << std::endl;
5325 oomph_info <<
"Before pruning: Processor " << my_rank
5326 <<
" holds " << this->
nnode()
5330 <<
" are shared nodes." << std::endl;
5334 for (
int iproc=0;iproc<n_proc;iproc++)
5336 oomph_info <<
"Before pruning: With process " << iproc <<
", there are " 5337 << this->
nhalo_node(iproc) <<
" halo nodes, and " << std::endl
5339 << this->
nshared_node(iproc) <<
" shared nodes" << std::endl;
5341 oomph_info <<
"----------------------------------------------------\n\n";
5345 double t_start = 0.0;
5354 unsigned nnod=this->
nnode();
5355 for (
unsigned j=0;j<nnod;j++)
5364 std::map<RefineableElement*,bool> keep_element;
5365 for (
unsigned e=0;
e<nelem;
e++)
5377 unsigned local_min_ref=0;
5378 unsigned local_max_ref=0;
5384 int int_local_min_ref=local_min_ref;
5385 int int_local_max_ref=local_max_ref;
5389 int_local_min_ref=INT_MAX;
5390 int_local_max_ref=INT_MIN;
5396 MPI_Allreduce(&int_local_min_ref,&int_min_ref,1,
5399 MPI_Allreduce(&int_local_max_ref,&int_max_ref,1,
5403 min_ref=unsigned(int_min_ref);
5404 max_ref=unsigned(int_max_ref);
5412 int local_n_ref=current_refined.size();
5417 local_n_ref=INT_MIN;
5422 MPI_Allreduce(&local_n_ref,&int_n_ref,1,
5425 unsigned n_ref=int(int_n_ref);
5433 <<
"Time for establishing refinement levels in " 5434 <<
" Mesh::prune_halo_elements_and_nodes() [includes comms]: " 5435 << t_end-t_start << std::endl;
5446 unsigned base_level=n_ref-(max_ref-min_ref);
5455 base_level_elements_pt);
5458 unsigned n_base_el=base_level_elements_pt.size();
5459 for (
unsigned e=0;
e<n_base_el;
e++)
5471 keep_element[ref_el_pt]=
true;
5474 unsigned nnod=ref_el_pt->
nnode();
5475 for (
unsigned j=0;j<nnod;j++)
5490 MPI_Allreduce(&n_unif_local,&n_unif,1,
5491 MPI_UNSIGNED,MPI_MAX,
5501 <<
"Time for synchronising refinement levels in " 5502 <<
" Mesh::prune_halo_elements_and_nodes() [includes comms]: " 5503 << t_end-t_start << std::endl;
5519 std::map<unsigned, Vector<FiniteElement*> > tmp_root_halo_element_pt;
5522 std::map<unsigned, Vector<FiniteElement*> > tmp_root_haloed_element_pt;
5525 std::map<unsigned,std::map<FiniteElement*,bool> >
5526 tmp_root_halo_element_is_retained;
5529 std::map<FiniteElement*,bool> halo_element_is_retained;
5531 for (
int domain=0;domain<n_proc;domain++)
5537 unsigned nelem=halo_elem_pt.size();
5538 for (
unsigned e=0;
e<nelem;
e++)
5549 if (halo_el_level==min_ref)
5566 unsigned nnod=el_pt->
nnode();
5567 for (
unsigned j=0;j<nnod;j++)
5575 if (!tmp_root_halo_element_is_retained[domain][el_pt])
5577 tmp_root_halo_element_pt[domain].push_back(el_pt);
5578 tmp_root_halo_element_is_retained[domain][el_pt]=
true;
5580 keep_element[el_pt]=
true;
5581 halo_element_is_retained[el_pt]=
true;
5592 <<
"Time for setup of retention pattern in " 5593 <<
" Mesh::prune_halo_elements_and_nodes(): " 5594 << t_end-t_start << std::endl;
5601 MPI_Barrier(
Comm_pt->mpi_comm());
5611 for (
int d=0;d<n_proc;d++)
5614 for (
int dd=0;dd<n_proc;dd++)
5628 unsigned nelem=haloed_elem_pt.size();
5635 MPI_Recv(&halo_kept[0],nelem,MPI_INT,dd,0,
Comm_pt->mpi_comm(),
5639 for (
unsigned e=0;
e<nelem;
e++)
5642 (haloed_elem_pt[
e]);
5651 if (haloed_el_level==min_ref)
5661 (min_ref,father_el_pt);
5665 if (halo_kept[
e]==1)
5669 bool already_root_haloed=
false;
5670 unsigned n_root_haloed=tmp_root_haloed_element_pt[dd].
size();
5671 for (
unsigned e_root=0;e_root<n_root_haloed;e_root++)
5673 if (el_pt==tmp_root_haloed_element_pt[dd][e_root])
5675 already_root_haloed=
true;
5679 if (!already_root_haloed)
5681 tmp_root_haloed_element_pt[dd].push_back(el_pt);
5699 unsigned nelem=halo_elem_pt.size();
5701 for (
unsigned e=0;
e<nelem;
e++)
5712 if (halo_el_level==min_ref)
5722 (min_ref,father_el_pt);
5726 if (halo_element_is_retained[el_pt])
5737 MPI_Send(&halo_kept[0],nelem,MPI_INT,d,0,
Comm_pt->mpi_comm());
5749 <<
"Time for pt2pt comms of retention pattern in " 5750 <<
" Mesh::prune_halo_elements_and_nodes(): " 5751 << t_end-t_start << std::endl;
5761 for (
unsigned j=0;j<nnod;j++)
5763 backed_up_nod_pt[j]=this->
node_pt(j);
5770 std::set<Tree*> trees_to_be_deleted_pt;
5773 nelem=backed_up_el_pt.size();
5774 for (
unsigned e=0;
e<nelem;
e++)
5777 (backed_up_el_pt[
e]);
5795 (min_ref,father_el_pt);
5801 if (keep_element[el_pt])
5820 tmp_all_tree_nodes_pt);
5824 unsigned n_tree=tmp_all_tree_nodes_pt.size();
5825 for (
unsigned j=0;j<n_tree;j++)
5827 if (tmp_all_tree_nodes_pt[j]->object_pt()!=0)
5829 unsigned lev=tmp_all_tree_nodes_pt[j]->object_pt()->refinement_level();
5832 if (!keep_element[tmp_all_tree_nodes_pt[j]->object_pt()])
5834 trees_to_be_deleted_pt.insert(tmp_all_tree_nodes_pt[j]);
5841 deleted_element_pt.push_back(ref_el_pt);
5849 for (std::set<Tree*>::iterator it=trees_to_be_deleted_pt.begin();
5850 it!=trees_to_be_deleted_pt.end();it++)
5852 Tree* tree_pt=(*it);
5855 deleted_element_pt.push_back(tree_pt->
object_pt());
5867 for (
int domain=0;domain<n_proc;domain++)
5869 unsigned nelem=tmp_root_halo_element_pt[domain].size();
5870 for (
unsigned e=0;
e<nelem;
e++)
5873 tmp_root_halo_element_pt[domain][
e]);
5876 nelem=tmp_root_haloed_element_pt[domain].size();
5877 for (
unsigned e=0;
e<nelem;
e++)
5880 tmp_root_haloed_element_pt[domain][
e]);
5892 for (
unsigned e=0;
e<nelem;
e++)
5897 unsigned nnod=el_pt->
nnode();
5898 for (
unsigned j=0;j<nnod;j++)
5910 nnod=backed_up_nod_pt.size();
5911 for (
unsigned j=0;j<nnod;j++)
5913 Node* nod_pt=backed_up_nod_pt[j];
5952 <<
"Time for local rebuild of mesh from retained elements in " 5953 <<
" Mesh::prune_halo_elements_and_nodes(): " 5954 << t_end-t_start << std::endl;
5965 <<
"Time for Mesh::classify_halo_and_haloed_nodes() " 5966 <<
" Mesh::prune_halo_elements_and_nodes(): " 5967 << t_end-t_start << std::endl;
5979 << doc_info.
number() << std::endl;
5994 <<
"Time for Mesh::reorder_nodes() " 5995 <<
" Mesh::prune_halo_elements_and_nodes(): " 5996 << t_end-t_start << std::endl;
6005 oomph_info <<
"\n----------------------------------------------------\n";
6006 oomph_info <<
"After pruning: Processor " << my_rank
6009 <<
" are root halo elements \n while " 6011 <<
" are root haloed elements" << std::endl;
6014 oomph_info <<
"After pruning: Processor " << my_rank
6015 <<
" holds " << this->
nnode()
6019 <<
" are shared nodes." << std::endl;
6023 for (
int iproc=0;iproc<n_proc;iproc++)
6025 oomph_info <<
"After pruning: With process " << iproc <<
", there are " 6026 << this->
nhalo_node(iproc) <<
" halo nodes, and " << std::endl
6028 << this->
nshared_node(iproc) <<
" shared nodes" << std::endl;
6030 oomph_info <<
"----------------------------------------------------\n\n";
6051 double& max_efficiency,
6052 double& min_efficiency)
6056 int my_rank=
Comm_pt->my_rank();
6064 for (
int d=0;d<n_proc;d++)
6067 count+=halo_elem_pt.size();
6071 int nhalo_element_local=count;
6078 MPI_Gather(&nhalo_element_local,1,MPI_INT,
6079 &nhalo_elements[0],1, MPI_INT,
6081 MPI_Gather(&n_element_local,1,MPI_INT,
6082 &n_elements[0],1, MPI_INT,
6088 double min=1000000000.0;
6092 for (
int i=0;
i<n_proc;
i++)
6094 unsigned nel=n_elements[
i];
6098 eff=double(n_elements[
i]-nhalo_elements[
i])/double(nel);
6101 if (eff>max) max=eff;
6102 if (eff<min) min=eff;
6105 av_efficiency/=double(n_proc);
6109 MPI_Bcast(&max,1,MPI_DOUBLE,0,
Comm_pt->mpi_comm());
6110 MPI_Bcast(&min,1,MPI_DOUBLE,0,
Comm_pt->mpi_comm());
6111 MPI_Bcast(&av_efficiency,1,MPI_DOUBLE,0,
Comm_pt->mpi_comm());
6126 int my_rank=
Comm_pt->my_rank();
6129 std::ostringstream filename;
6130 std::ostringstream filename2;
6131 std::ofstream some_file;
6132 std::ofstream some_file2;
6135 filename << doc_info.
directory() <<
"/"<< doc_info.
label()<<
"elements_on_proc" 6136 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6137 some_file.open(filename.str().c_str());
6138 this->
output(some_file,5);
6144 << doc_info.
label()<<
"non_halo_elements_on_proc" 6145 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6146 some_file.open(filename.str().c_str());
6150 for (
unsigned e=0;
e<nelem;
e++)
6161 some_file <<
"Generalised Element " <<
e <<
"\n";
6166 f_el_pt->
output(some_file,5);
6177 <<
"halo_elements_on_proc" 6178 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6179 some_file.open(filename.str().c_str());
6180 for (
int domain=0; domain<n_proc; domain++)
6184 <<
"halo_elements_with_proc" << domain <<
"_on_proc" 6185 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6186 some_file2.open(filename2.str().c_str());
6190 unsigned nelem=halo_elem_pt.size();
6191 for (
unsigned e=0;
e<nelem;
e++)
6206 std::ostringstream error_message;
6208 <<
"Haloed element is not a leaf element. This shouldn't happen" 6211 <<
"Here are the nodal positions: " << std::endl;
6212 unsigned nnod=ref_el_pt->
nnode();
6213 for (
unsigned j=0;j<nnod;j++)
6216 unsigned n_dim=nod_pt->
ndim();
6217 for (
unsigned i=0;
i<n_dim;
i++)
6219 error_message << nod_pt->
x(
i) <<
" ";
6221 error_message <<
"\n";
6223 OOMPH_CURRENT_FUNCTION,
6224 OOMPH_EXCEPTION_LOCATION);
6230 f_el_pt->
output(some_file,5);
6231 f_el_pt->
output(some_file2,5);
6236 some_file <<
"Generalised Element " <<
e <<
"\n";
6237 some_file2 <<
"Generalised Element " << e <<
"\n";
6247 <<
"haloed_elements_on_proc" 6248 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6249 some_file.open(filename.str().c_str());
6250 for (
int domain=0; domain<n_proc; domain++)
6254 <<
"haloed_elements_with_proc" << domain <<
"_on_proc" 6255 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6256 some_file2.open(filename2.str().c_str());
6260 unsigned nelem=haloed_elem_pt.size();
6261 for (
unsigned e=0;
e<nelem;
e++)
6265 (haloed_elem_pt[
e]);
6278 std::ostringstream error_message;
6280 <<
"Haloed element is not a leaf element. This shouldn't happen" 6283 <<
"Here are the nodal positions: " << std::endl;
6284 unsigned nnod=ref_el_pt->
nnode();
6285 for (
unsigned j=0;j<nnod;j++)
6288 unsigned n_dim=nod_pt->
ndim();
6289 for (
unsigned i=0;
i<n_dim;
i++)
6291 error_message << nod_pt->
x(
i) <<
" ";
6293 error_message <<
"\n";
6295 OOMPH_CURRENT_FUNCTION,
6296 OOMPH_EXCEPTION_LOCATION);
6302 finite_el_pt->
output(some_file,5);
6303 finite_el_pt->
output(some_file2,5);
6308 some_file <<
"Generalised Element " <<
e <<
"\n";
6309 some_file2 <<
"Generalised Element " << e <<
"\n";
6320 <<
"non_halo_nodes_on_proc" 6321 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6322 some_file.open(filename.str().c_str());
6323 unsigned nnod=this->
nnode();
6324 for (
unsigned j=0;j<nnod;j++)
6329 unsigned ndim=nod_pt->
ndim();
6330 for (
unsigned i=0;
i<ndim;
i++)
6332 some_file << nod_pt->
x(
i) <<
" " ;
6334 some_file << nod_pt->
nvalue() <<
" " 6347 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6348 some_file.open(filename.str().c_str());
6349 for (
unsigned j=0;j<nnod;j++)
6352 unsigned ndim=nod_pt->
ndim();
6353 for (
unsigned i=0;
i<ndim;
i++)
6355 some_file << nod_pt->
x(
i) <<
" " ;
6357 some_file << nod_pt->
nvalue() <<
" " 6367 << doc_info.
label()<<
"solid_nodes_on_proc" 6368 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6369 some_file.open(filename.str().c_str());
6370 unsigned nsnod=this->
nnode();
6371 for (
unsigned j=0;j<nsnod;j++)
6375 if (solid_nod_pt!=0)
6377 unsigned ndim=solid_nod_pt->
ndim();
6378 for (
unsigned i=0;
i<ndim;
i++)
6380 some_file << nod_pt->
x(
i) <<
" " ;
6382 some_file << nod_pt->
nvalue() <<
" " 6394 <<
"halo_nodes_on_proc" 6395 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6396 some_file.open(filename.str().c_str());
6397 for (
int domain=0; domain<n_proc; domain++)
6401 <<
"halo_nodes_with_proc" << domain <<
"_on_proc" 6402 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6403 some_file2.open(filename2.str().c_str());
6405 for (
unsigned j=0;j<nnod;j++)
6408 unsigned ndim=nod_pt->
ndim();
6409 for (
unsigned i=0;
i<ndim;
i++)
6411 some_file << nod_pt->
x(
i) <<
" " ;
6412 some_file2 << nod_pt->
x(
i) <<
" " ;
6414 some_file << nod_pt->
nvalue() <<
" " 6418 some_file2 << nod_pt->
nvalue() <<
" " 6432 <<
"haloed_nodes_on_proc" 6433 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6434 some_file.open(filename.str().c_str());
6435 for (
int domain=0; domain<n_proc; domain++)
6439 <<
"haloed_nodes_with_proc" << domain <<
"_on_proc" 6440 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6441 some_file2.open(filename2.str().c_str());
6443 for (
unsigned j=0;j<nnod;j++)
6446 unsigned ndim=nod_pt->
ndim();
6447 for (
unsigned i=0;
i<ndim;
i++)
6449 some_file << nod_pt->
x(
i) <<
" " ;
6450 some_file2 << nod_pt->
x(
i) <<
" " ;
6452 some_file << nod_pt->
nvalue() <<
" " 6456 some_file2 << nod_pt->
nvalue() <<
" " 6470 <<
"shared_nodes_on_proc" 6471 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6472 some_file.open(filename.str().c_str());
6473 for (
int domain=0; domain<n_proc; domain++)
6477 <<
"shared_nodes_with_proc" << domain <<
"_on_proc" 6478 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6479 some_file2.open(filename2.str().c_str());
6481 for (
unsigned j=0;j<nnod;j++)
6484 unsigned ndim=nod_pt->
ndim();
6485 for (
unsigned i=0;
i<ndim;
i++)
6487 some_file << nod_pt->
x(
i) <<
" " ;
6488 some_file2 << nod_pt->
x(
i) <<
" " ;
6490 some_file << nod_pt->
nvalue() <<
" " 6493 some_file2 << nod_pt->
nvalue() <<
" " 6507 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6508 some_file.open(filename.str().c_str());
6509 this->
output(some_file,5);
6517 << my_rank <<
"_" << doc_info.
number() <<
".dat";
6518 some_file.open(filename.str().c_str());
6529 for (
unsigned b=0;b<nbound;b++)
6533 <<
"boundary_elements" 6534 << my_rank <<
"_" << b <<
"_" << doc_info.
number() <<
".dat";
6535 some_file.open(filename.str().c_str());
6537 for (
unsigned e=0;
e<nelem;
e++)
6552 double& max_permitted_error_for_halo_check)
6555 oomph_info <<
"Doing check_halo_schemes for mesh: " 6556 <<
typeid(*this).name() << std::endl;
6563 std::ostringstream filename;
6564 std::ofstream shared_file;
6565 std::ofstream halo_file;
6566 std::ofstream haloed_file;
6567 std::ofstream ext_halo_file;
6568 std::ofstream ext_haloed_file;
6572 int my_rank=
Comm_pt->my_rank();
6583 for (
int dd=0;dd<n_proc;dd++)
6587 <<
"/shared_node_check" << doc_info.
label() <<
"_on_proc" 6588 << my_rank <<
"_with_proc" << dd <<
"_" 6589 << doc_info.
number() <<
".dat";
6590 shared_file.open(filename.str().c_str());
6591 shared_file <<
"ZONE " << std::endl;
6594 for (
unsigned j=0;j<nnod;j++)
6597 unsigned ndim=nod_pt->
ndim();
6598 for (
unsigned i=0;
i<ndim;
i++)
6600 shared_file << nod_pt->
position(
i) <<
" ";
6602 shared_file << j <<
" " << nod_pt << std::endl;
6612 shared_file <<
"0.0" << std::endl;
6619 shared_file <<
" 1.0 1.1 " << std::endl;
6623 shared_file <<
" 1.0 1.1 1.1" << std::endl;
6627 shared_file.close();
6635 for (
int d=0;d<n_proc;d++)
6638 std::set<Node*> shared_node_set;
6639 for (
unsigned i=0;
i<n_vector;
i++)
6641 unsigned old_size=shared_node_set.size();
6643 unsigned new_size=shared_node_set.size();
6644 if (old_size==new_size)
6647 oomph_info <<
"Repeated node in shared node lookup scheme: " 6648 << i <<
"-th node with proc " << d <<
" : " 6649 << nod_pt <<
" at: ";
6650 unsigned n=nod_pt->
ndim();
6651 for (
unsigned ii=0;ii<n;ii++)
6658 unsigned n_set=shared_node_set.size();
6659 if (n_vector!=n_set)
6661 std::ostringstream warning_stream;
6663 <<
"WARNING: " << std::endl
6664 <<
"There seem to be repeated entries in shared node scheme " 6665 <<
"with proc " << d <<
".\n" 6666 <<
"n_vector=" << n_vector
6667 <<
"; n_set=" << n_set << std::endl;
6671 <<
"Shared node scheme has been output in files like\n" 6672 << filename.str() << std::endl;
6677 <<
"Re-run with doc_info enabled to see where the shared nodes are.\n";
6680 "Mesh::check_halo_schemes",
6681 OOMPH_EXCEPTION_LOCATION);
6689 double max_error=0.0;
6692 for (
int d=0;d<n_proc;d++)
6698 for (
int dd=0;dd<n_proc;dd++)
6711 MPI_Recv(&nnod_share,1, MPI_INT,dd,0,
Comm_pt->mpi_comm(),&status);
6713 if (nnod_shared!=nnod_share)
6715 std::ostringstream error_message;
6718 <<
"Clash in numbers of shared nodes! " 6721 <<
"# of shared nodes on proc " 6722 << dd <<
": " << nnod_shared << std::endl;
6724 <<
"# of shared nodes on proc " 6725 << d <<
": " << nnod_share << std::endl;
6727 <<
"(Re-)run Problem::check_halo_schemes() with DocInfo object" 6730 <<
"to identify the problem" << std::endl;
6732 OOMPH_CURRENT_FUNCTION,
6733 OOMPH_EXCEPTION_LOCATION);
6741 MPI_Recv(&other_nodal_positions[0],nod_dim*nnod_share,MPI_DOUBLE,dd,
6742 0,
Comm_pt->mpi_comm(),&status);
6746 for (
int j=0;j<nnod_share;j++)
6749 for(
unsigned i=0;
i<nod_dim;
i++)
6754 for(
unsigned i=0;
i<nod_dim;
i++)
6756 x_share[
i] = other_nodal_positions[count];
6760 for(
unsigned i=0;
i<nod_dim;
i++)
6761 {error += (x_shared[
i] - x_share[
i])*(x_shared[
i] - x_share[
i]);}
6762 error = sqrt(error);
6765 if (error>max_permitted_error_for_halo_check)
6768 for(
unsigned i=0;
i<nod_dim;
i++)
6772 for(
unsigned i=0;
i<nod_dim;
i++)
6789 if (error>max_error)
6807 MPI_Send(&nnod_share,1,MPI_INT,d,0,
Comm_pt->mpi_comm());
6814 for (
int j=0;j<nnod_share;j++)
6816 for(
unsigned i=0;
i<nod_dim;
i++)
6823 MPI_Send(&nodal_positions[0],nod_dim*nnod_share,MPI_DOUBLE,d,0,
6829 oomph_info <<
"Max. error for shared nodes " << max_error
6831 if (max_error>max_permitted_error_for_halo_check)
6833 std::ostringstream error_message;
6835 <<
"This is bigger than the permitted threshold " 6836 << max_permitted_error_for_halo_check << std::endl;
6838 <<
"If you believe this to be acceptable for your problem\n" 6839 <<
"increase Problem::Max_permitted_error_for_halo_check and re-run \n";
6841 OOMPH_CURRENT_FUNCTION,
6842 OOMPH_EXCEPTION_LOCATION);
6852 for (
int dd=0;dd<n_proc;dd++)
6855 filename << doc_info.
directory() <<
"/halo_element_check" 6856 << doc_info.
label() <<
"_on_proc" 6857 << my_rank <<
"_with_proc" << dd <<
"_" 6860 halo_file.open(filename.str().c_str());
6865 unsigned nelem=halo_elem_pt.size();
6867 for (
unsigned e=0;
e<nelem;
e++)
6869 halo_file <<
"ZONE " << std::endl;
6875 unsigned nnod=finite_el_pt->
nnode();
6876 for (
unsigned j=0;j<nnod;j++)
6879 unsigned ndim=nod_pt->
ndim();
6880 for (
unsigned i=0;
i<ndim;
i++)
6882 halo_file << nod_pt->
position(
i) <<
" ";
6884 halo_file << std::endl;
6892 for (
int d=0;d<n_proc;d++)
6895 filename << doc_info.
directory() <<
"/haloed_element_check" 6896 << doc_info.
label() <<
"_on_proc" 6897 << my_rank <<
"_with_proc" << d <<
"_" 6900 haloed_file.open(filename.str().c_str());
6906 unsigned nelem2=haloed_elem_pt.size();
6907 for (
unsigned e=0;
e<nelem2;
e++)
6909 haloed_file <<
"ZONE " << std::endl;
6924 std::ostringstream error_message;
6926 <<
"Haloed element is not a leaf element. This shouldn't happen" 6929 <<
"Here are the nodal positions: " << std::endl;
6930 unsigned nnod=ref_el_pt->
nnode();
6931 for (
unsigned j=0;j<nnod;j++)
6934 unsigned n_dim=nod_pt->
ndim();
6935 for (
unsigned i=0;
i<n_dim;
i++)
6937 error_message << nod_pt->
x(
i) <<
" ";
6939 error_message <<
"\n";
6941 OOMPH_CURRENT_FUNCTION,
6942 OOMPH_EXCEPTION_LOCATION);
6946 unsigned nnod2=finite_el_pt->
nnode();
6947 for (
unsigned j=0;j<nnod2;j++)
6950 unsigned ndim=nod_pt->
ndim();
6951 for (
unsigned i=0;
i<ndim;
i++)
6953 haloed_file << nod_pt->
position(
i) <<
" ";
6955 haloed_file << std::endl;
6959 haloed_file.close();
6967 bool shout_and_terminate=
false;
6970 for (
int d=0;d<n_proc;d++)
6976 for (
int dd=0;dd<n_proc;dd++)
6987 int nelem_haloed=haloed_elem_pt.size();
6989 if (nelem_haloed!=0)
6994 MPI_Recv(&nelem_halo,1,MPI_INT,dd,0,
Comm_pt->mpi_comm(),&status);
6995 if (nelem_halo!=nelem_haloed)
6997 std::ostringstream error_message;
6999 <<
"Clash in numbers of halo and haloed elements! " 7002 <<
"# of haloed elements whose halo counterpart lives on proc " 7003 << dd <<
": " << nelem_haloed << std::endl;
7005 <<
"# of halo elements whose non-halo counterpart lives on proc " 7006 << d <<
": " << nelem_halo << std::endl;
7008 <<
"(Re-)run Problem::check_halo_schemes() with DocInfo object" 7011 <<
"to identify the problem" << std::endl;
7013 OOMPH_CURRENT_FUNCTION,
7014 OOMPH_EXCEPTION_LOCATION);
7019 if(dynamic_cast<FiniteElement*>(this->
element_pt(0)))
7029 unsigned n_nodal_positions=0;
7030 MPI_Recv(&n_nodal_positions,1,
7031 MPI_UNSIGNED,dd,0,
Comm_pt->mpi_comm(),&status);
7033 if (n_nodal_positions>0)
7035 MPI_Recv(&other_nodal_positions[0],n_nodal_positions,
7036 MPI_DOUBLE,dd,0,
Comm_pt->mpi_comm(),&status);
7042 unsigned n_other_nodal_hangings=0;
7043 MPI_Recv(&n_other_nodal_hangings,1,
7045 1,
Comm_pt->mpi_comm(),&status);
7046 if (n_other_nodal_hangings>0)
7048 other_nodal_hangings.resize(n_other_nodal_hangings);
7049 MPI_Recv(&other_nodal_hangings[0],n_other_nodal_hangings,
7051 1,
Comm_pt->mpi_comm(),&status);
7058 filename << doc_info.
directory() <<
"/error_haloed_check" 7059 << doc_info.
label() <<
"_on_proc" 7060 << my_rank <<
"_with_proc" << dd <<
"_" 7063 haloed_file.open(filename.str().c_str());
7065 filename << doc_info.
directory() <<
"/error_halo_check" 7066 << doc_info.
label() <<
"_on_proc" 7067 << my_rank <<
"_with_proc" << dd <<
"_" 7070 halo_file.open(filename.str().c_str());
7074 unsigned count_hanging=0;
7075 for (
int e=0;
e<nelem_haloed;
e++)
7082 unsigned nnod_this_el = finite_el_pt->
nnode();
7083 for (
unsigned j=0;j<nnod_this_el;j++)
7091 for(
unsigned i=0;
i<nod_dim;
i++)
7097 for(
unsigned i=0;
i<nod_dim;
i++)
7099 x_halo[
i] = other_nodal_positions[count];
7105 for(
unsigned i=0;
i<nod_dim;
i++)
7107 error += (x_haloed[
i] - x_halo[
i])*
7108 (x_haloed[
i] - x_halo[
i]);
7110 error = sqrt(error);
7112 if (error>max_error) {max_error=error;}
7117 <<
"Discrepancy between nodal coordinates of halo(ed)" 7118 <<
"element larger than tolerance (" << tol
7119 <<
")\n Error: " << error <<
"\n";
7123 unsigned nval=nod_pt->
nvalue();
7124 int nval_other=other_nodal_hangings[count_hanging];
7126 if (
int(nval)!=nval_other)
7129 <<
"Number of values of node, " << nval
7130 <<
", does not match number of values on other proc, " 7131 << nval_other << std::endl;
7133 shout_and_terminate=
true;
7137 int other_geom_hanging=0;
7140 for (
int i=-1;
i<int(nval);
i++)
7142 int nmaster_other=other_nodal_hangings[count_hanging];
7146 if (
i==-1) other_geom_hanging=nmaster_other;
7153 if (
int(nmaster)!=nmaster_other)
7156 <<
"Number of master nodes for hanging value " <<
i 7157 <<
" of node, " << nmaster
7158 <<
", does not match number of master " 7159 <<
"nodes on other proc, " 7160 << nmaster_other << std::endl;
7162 shout_and_terminate=
true;
7170 if (nmaster_other!=0)
7174 <<
" of node is not hanging whereas " 7175 <<
" node on other proc has " 7177 <<
" masters and therefore is hanging. \n";
7179 shout_and_terminate=
true;
7190 <<
"Error(s) displayed above are for " 7191 <<
"domain with non-halo (i.e. haloed) elem: " 7194 <<
"Domain with halo elem: " << d
7200 <<
"Current processor is " << my_rank
7202 <<
"Nodal positions: " << x_halo[0] <<
"\n" 7203 <<
"and haloed: " << x_haloed[0] <<
"\n" 7209 <<
"Current processor is " << my_rank
7211 <<
"Nodal positions: " 7212 << x_halo[0] <<
" " << x_halo[1]
7214 <<
"and haloed: " << x_haloed[0] <<
" " 7215 << x_haloed[1] << std::endl
7221 <<
"Current processor is " << my_rank
7223 <<
"Nodal positions: " 7224 << x_halo[0] <<
" " << x_halo[1] <<
" " << x_halo[2]
7226 <<
"and haloed: " << x_haloed[0] <<
" " 7227 << x_haloed[1] <<
" " << x_haloed[2] << std::endl
7233 "Nodal dimension not equal to 1, 2 or 3\n",
7234 OOMPH_CURRENT_FUNCTION,
7235 OOMPH_EXCEPTION_LOCATION);
7243 for(
unsigned i=0;
i<nod_dim;
i++)
7245 haloed_file << x_haloed[
i] <<
" ";
7246 halo_file << x_halo[
i] <<
" ";
7248 haloed_file << error <<
" " << my_rank <<
" " 7252 halo_file << error <<
" " << my_rank <<
" " 7254 << other_geom_hanging << std::endl;
7264 haloed_file.close();
7283 unsigned nelem_halo=halo_elem_pt.size();
7288 MPI_Send(&nelem_halo,1,MPI_UNSIGNED,d,0,
Comm_pt->mpi_comm());
7291 if(dynamic_cast<FiniteElement*>(this->
element_pt(0)))
7301 nodal_positions.reserve(nod_dim*nnod_first_el*nelem_halo);
7307 for (
unsigned e=0;
e<nelem_halo;
e++)
7313 unsigned nnod_this_el = finite_el_pt->
nnode();
7314 for (
unsigned j=0;j<nnod_this_el;j++)
7323 oomph_info <<
"element: " << finite_el_pt << std::endl;
7324 for(
unsigned i=0;
i<finite_el_pt->
nnode();
i++)
7331 OOMPH_CURRENT_FUNCTION,
7332 OOMPH_EXCEPTION_LOCATION);
7336 for(
unsigned i=0;
i<nod_dim;
i++)
7340 nodal_positions.push_back(nod_pt->
position(
i));
7343 unsigned nval=nod_pt->
nvalue();
7344 nodal_hangings.push_back(nval);
7345 for (
int i=-1;
i<int(nval);
i++)
7350 nodal_hangings.push_back(nmaster);
7354 nodal_hangings.push_back(0);
7362 unsigned n_nodal_positions=nodal_positions.size();
7365 unsigned n_nodal_hangings=nodal_hangings.size();
7371 MPI_Send(&n_nodal_positions,1,
7372 MPI_UNSIGNED,d,0,
Comm_pt->mpi_comm());
7373 if (n_nodal_positions>0)
7375 MPI_Send(&nodal_positions[0],n_nodal_positions,
7376 MPI_DOUBLE,d,0,
Comm_pt->mpi_comm());
7378 MPI_Send(&n_nodal_hangings,1,
7379 MPI_UNSIGNED,d,1,
Comm_pt->mpi_comm());
7380 if (n_nodal_hangings>0)
7382 MPI_Send(&nodal_hangings[0], n_nodal_hangings,
7383 MPI_INT,d,1,
Comm_pt->mpi_comm());
7390 oomph_info <<
"Max. error for halo/haloed elements " << max_error
7392 if (max_error>max_permitted_error_for_halo_check)
7394 shout_and_terminate=
true;
7396 <<
"This is bigger than the permitted threshold " 7397 << max_permitted_error_for_halo_check << std::endl;
7399 <<
"If you believe this to be acceptable for your problem\n" 7400 <<
"increase Problem::Max_permitted_error_for_halo_check and re-run \n";
7403 if (shout_and_terminate)
7406 OOMPH_CURRENT_FUNCTION,
7407 OOMPH_EXCEPTION_LOCATION);
7417 for (
int dd=0;dd<n_proc;dd++)
7420 filename << doc_info.
directory() <<
"/halo_node_check" 7421 << doc_info.
label() <<
"_on_proc" 7422 << my_rank <<
"_with_proc" << dd <<
"_" 7425 halo_file.open(filename.str().c_str());
7426 halo_file <<
"ZONE " << std::endl;
7429 for (
unsigned j=0;j<nnod;j++)
7432 unsigned ndim=nod_pt->
ndim();
7433 for (
unsigned i=0;
i<ndim;
i++)
7435 halo_file << nod_pt->
position(
i) <<
" ";
7437 halo_file << nod_pt->
is_hanging() << std::endl;
7448 halo_file <<
"0.0" << std::endl;
7455 halo_file <<
" 1.0 1.1 " << std::endl;
7459 halo_file <<
" 1.0 1.1 1.1" << std::endl;
7468 for (
int d=0;d<n_proc;d++)
7471 filename << doc_info.
directory() <<
"/haloed_node_check" 7472 << doc_info.
label() <<
"_on_proc" 7473 << my_rank <<
"_with_proc" << d <<
"_" 7476 haloed_file.open(filename.str().c_str());
7477 haloed_file <<
"ZONE " << std::endl;
7480 for (
unsigned j=0;j<nnod;j++)
7483 unsigned ndim=nod_pt->
ndim();
7484 for (
unsigned i=0;
i<ndim;
i++)
7486 haloed_file << nod_pt->
position(
i) <<
" ";
7488 haloed_file << nod_pt->
is_hanging() << std::endl;
7498 haloed_file <<
"0.0" << std::endl;
7505 haloed_file <<
" 1.0 1.1 " << std::endl;
7509 haloed_file <<
" 1.0 1.1 1.1" << std::endl;
7513 haloed_file.close();
7522 for (
int d=0;d<n_proc;d++)
7528 for (
int dd=0;dd<n_proc;dd++)
7542 MPI_Recv(&nnod_halo,1,MPI_INT,dd,0,
Comm_pt->mpi_comm(),&status);
7544 if (nnod_haloed!=nnod_halo)
7546 std::ostringstream error_message;
7549 <<
"Clash in numbers of halo and haloed nodes! " 7552 <<
"# of haloed nodes whose halo counterpart lives on proc " 7553 << dd <<
": " << nnod_haloed << std::endl;
7555 <<
"# of halo nodes whose non-halo counterpart lives on proc " 7556 << d <<
": " << nnod_halo << std::endl;
7558 <<
"(Re-)run Mesh::check_halo_schemes() with DocInfo object" 7561 <<
"to identify the problem" << std::endl;
7563 OOMPH_CURRENT_FUNCTION,
7564 OOMPH_EXCEPTION_LOCATION);
7572 MPI_Recv(&other_nodal_positions[0],nod_dim*nnod_halo,MPI_DOUBLE,dd,
7573 0,
Comm_pt->mpi_comm(),&status);
7577 for (
int j=0;j<nnod_halo;j++)
7580 for(
unsigned i=0;
i<nod_dim;
i++)
7585 for(
unsigned i=0;
i<nod_dim;
i++)
7587 x_halo[
i]=other_nodal_positions[count];
7591 for(
unsigned i=0;
i<nod_dim;
i++)
7593 error += (x_haloed[
i] - x_halo[
i])*(x_haloed[
i] - x_halo[
i]);
7595 error = sqrt(error);
7596 if (error>max_error)
7614 MPI_Send(&nnod_halo,1,MPI_INT,d,0,
Comm_pt->mpi_comm());
7621 for (
int j=0;j<nnod_halo;j++)
7623 for(
unsigned i=0;
i<nod_dim;
i++)
7630 MPI_Send(&nodal_positions[0],nod_dim*nnod_halo,MPI_DOUBLE,d,0,
7636 oomph_info <<
"Max. error for halo/haloed nodes " << max_error
7639 if (max_error>max_permitted_error_for_halo_check)
7641 std::ostringstream error_message;
7643 <<
"This is bigger than the permitted threshold " 7644 << max_permitted_error_for_halo_check << std::endl;
7646 <<
"If you believe this to be acceptable for your problem\n" 7647 <<
"increase Problem::Max_permitted_error_for_halo_check and re-run \n";
7649 OOMPH_CURRENT_FUNCTION,
7650 OOMPH_EXCEPTION_LOCATION);
7666 for (
int dd=0;dd<n_proc;dd++)
7670 filename << doc_info.
directory() <<
"/ext_halo_element_check" 7671 << doc_info.
label() <<
"_on_proc" 7672 << my_rank <<
"_with_proc" << dd <<
"_" 7675 ext_halo_file.open(filename.str().c_str());
7677 ext_halo_file.close();
7681 filename << doc_info.
directory() <<
"/ext_halo_node_check" 7682 << doc_info.
label() <<
"_on_proc" 7683 << my_rank <<
"_with_proc" << dd <<
"_" 7686 ext_halo_file.open(filename.str().c_str());
7691 unsigned nelem=ext_halo_elem_pt.size();
7693 for (
unsigned e=0;
e<nelem;
e++)
7695 ext_halo_file <<
"ZONE " << std::endl;
7701 unsigned nnod=finite_el_pt->
nnode();
7702 for (
unsigned j=0;j<nnod;j++)
7705 unsigned ndim=nod_pt->
ndim();
7706 for (
unsigned i=0;
i<ndim;
i++)
7708 ext_halo_file << nod_pt->
position(
i) <<
" ";
7710 ext_halo_file << std::endl;
7714 ext_halo_file.close();
7718 for (
int d=0;d<n_proc;d++)
7723 filename << doc_info.
directory() <<
"/ext_haloed_element_check" 7724 << doc_info.
label() <<
"_on_proc" 7725 << my_rank <<
"_with_proc" << d <<
"_" 7728 ext_haloed_file.open(filename.str().c_str());
7730 ext_haloed_file.close();
7735 filename << doc_info.
directory() <<
"/ext_haloed_node_check" 7736 << doc_info.
label() <<
"_on_proc" 7737 << my_rank <<
"_with_proc" << d <<
"_" 7740 ext_haloed_file.open(filename.str().c_str());
7746 unsigned nelem2=ext_haloed_elem_pt.size();
7747 for (
unsigned e=0;
e<nelem2;
e++)
7749 ext_haloed_file <<
"ZONE " << std::endl;
7755 unsigned nnod2=finite_el_pt->
nnode();
7756 for (
unsigned j=0;j<nnod2;j++)
7759 unsigned ndim=nod_pt->
ndim();
7760 for (
unsigned i=0;
i<ndim;
i++)
7762 ext_haloed_file << nod_pt->
position(
i) <<
" ";
7764 ext_haloed_file << std::endl;
7768 ext_haloed_file.close();
7776 shout_and_terminate=
false;
7779 for (
int d=0;d<n_proc;d++)
7785 for (
int dd=0;dd<n_proc;dd++)
7796 int nelem_haloed=ext_haloed_elem_pt.size();
7798 if (nelem_haloed!=0)
7803 MPI_Recv(&nelem_halo,1,MPI_INT,dd,0,
Comm_pt->mpi_comm(),&status);
7804 if (nelem_halo!=nelem_haloed)
7806 std::ostringstream error_message;
7808 <<
"Clash in numbers of external halo and haloed elements! " 7811 <<
"# of external haloed elements whose halo counterpart lives on proc " 7812 << dd <<
": " << nelem_haloed << std::endl;
7814 <<
"# of external halo elements whose non-halo counterpart lives on proc " 7815 << d <<
": " << nelem_halo << std::endl;
7817 <<
"(Re-)run Problem::check_halo_schemes() with DocInfo object" 7820 <<
"to identify the problem" << std::endl;
7822 OOMPH_CURRENT_FUNCTION,
7823 OOMPH_EXCEPTION_LOCATION);
7839 unsigned n_nodal_positions=0;
7840 MPI_Recv(&n_nodal_positions,1,
7841 MPI_UNSIGNED,dd,0,
Comm_pt->mpi_comm(),&status);
7843 if (n_nodal_positions>0)
7845 MPI_Recv(&other_nodal_positions[0],n_nodal_positions,
7846 MPI_DOUBLE,dd,0,
Comm_pt->mpi_comm(),&status);
7852 unsigned n_other_nodal_hangings=0;
7853 MPI_Recv(&n_other_nodal_hangings,1,
7855 1,
Comm_pt->mpi_comm(),&status);
7856 if (n_other_nodal_hangings>0)
7858 other_nodal_hangings.resize(n_other_nodal_hangings);
7859 MPI_Recv(&other_nodal_hangings[0],n_other_nodal_hangings,
7861 1,
Comm_pt->mpi_comm(),&status);
7868 filename << doc_info.
directory() <<
"/error_ext_haloed_check" 7869 << doc_info.
label() <<
"_on_proc" 7870 << my_rank <<
"_with_proc" << dd <<
"_" 7873 ext_haloed_file.open(filename.str().c_str());
7875 filename << doc_info.
directory() <<
"/error_ext_halo_check" 7876 << doc_info.
label() <<
"_on_proc" 7877 << my_rank <<
"_with_proc" << dd <<
"_" 7880 ext_halo_file.open(filename.str().c_str());
7884 unsigned count_hanging=0;
7885 for (
int e=0;
e<nelem_haloed;
e++)
7892 unsigned nnod_this_el = finite_el_pt->
nnode();
7893 for (
unsigned j=0;j<nnod_this_el;j++)
7901 for(
unsigned i=0;
i<nod_dim;
i++)
7907 for(
unsigned i=0;
i<nod_dim;
i++)
7909 x_halo[
i] = other_nodal_positions[count];
7915 for(
unsigned i=0;
i<nod_dim;
i++)
7917 error += (x_haloed[
i] - x_halo[
i])*
7918 (x_haloed[
i] - x_halo[
i]);
7920 error = sqrt(error);
7922 if (error>max_error) {max_error=error;}
7927 <<
"Discrepancy between nodal coordinates of external halo(ed)" 7928 <<
"element larger than tolerance (" << tol
7929 <<
")\n Error: " << error <<
"\n";
7933 unsigned nval=nod_pt->
nvalue();
7934 int nval_other=other_nodal_hangings[count_hanging];
7936 if (
int(nval)!=nval_other)
7939 <<
"Number of values of node, " << nval
7940 <<
", does not match number of values on other proc, " 7941 << nval_other << std::endl;
7943 shout_and_terminate=
true;
7947 int other_geom_hanging=0;
7950 for (
int i=-1;
i<int(nval);
i++)
7952 int nmaster_other=other_nodal_hangings[count_hanging];
7956 if (
i==-1) other_geom_hanging=nmaster_other;
7963 if (
int(nmaster)!=nmaster_other)
7966 <<
"Number of master nodes for hanging value " <<
i 7967 <<
" of node, " << nmaster
7968 <<
", does not match number of master " 7969 <<
"nodes on other proc, " 7970 << nmaster_other << std::endl;
7972 shout_and_terminate=
true;
7980 if (nmaster_other!=0)
7984 <<
" of node is not hanging whereas " 7985 <<
" node on other proc has " 7987 <<
" masters and therefore is hanging. \n";
7989 shout_and_terminate=
true;
8000 <<
"Error(s) displayed above are for " 8001 <<
"domain with external non-halo (i.e. haloed) elem: " 8004 <<
"Domain with halo elem: " << d
8010 <<
"Current processor is " << my_rank
8012 <<
"Nodal positions: " << x_halo[0] <<
"\n" 8013 <<
"and haloed: " << x_haloed[0] <<
"\n" 8019 <<
"Current processor is " << my_rank
8021 <<
"Nodal positions: " 8022 << x_halo[0] <<
" " << x_halo[1]
8024 <<
"and haloed: " << x_haloed[0] <<
" " 8025 << x_haloed[1] << std::endl
8031 <<
"Current processor is " << my_rank
8033 <<
"Nodal positions: " 8034 << x_halo[0] <<
" " << x_halo[1] <<
" " << x_halo[2]
8036 <<
"and haloed: " << x_haloed[0] <<
" " 8037 << x_haloed[1] <<
" " << x_haloed[2] << std::endl
8043 "Nodal dimension not equal to 1, 2 or 3\n",
8044 OOMPH_CURRENT_FUNCTION,
8045 OOMPH_EXCEPTION_LOCATION);
8053 for(
unsigned i=0;
i<nod_dim;
i++)
8055 ext_haloed_file << x_haloed[
i] <<
" ";
8056 ext_halo_file << x_halo[
i] <<
" ";
8058 ext_haloed_file << error <<
" " << my_rank <<
" " 8062 ext_halo_file << error <<
" " << my_rank <<
" " 8064 << other_geom_hanging << std::endl;
8074 ext_haloed_file.close();
8075 ext_halo_file.close();
8093 unsigned nelem_halo=ext_halo_elem_pt.size();
8099 MPI_Send(&nelem_halo,1,MPI_UNSIGNED,d,0,
Comm_pt->mpi_comm());
8106 unsigned nnod_first_el=fe_pt->
nnode();
8107 unsigned nod_dim=fe_pt->node_pt(0)->ndim();
8109 nodal_positions.reserve(nod_dim*nnod_first_el*nelem_halo);
8115 for (
unsigned e=0;
e<nelem_halo;
e++)
8121 unsigned nnod_this_el = finite_el_pt->
nnode();
8122 for (
unsigned j=0;j<nnod_this_el;j++)
8127 for(
unsigned i=0;
i<nod_dim;
i++)
8129 nodal_positions.push_back(nod_pt->
position(
i));
8133 unsigned nval=nod_pt->
nvalue();
8134 nodal_hangings.push_back(nval);
8135 for (
int i=-1;
i<int(nval);
i++)
8140 nodal_hangings.push_back(nmaster);
8144 nodal_hangings.push_back(0);
8152 unsigned n_nodal_positions=nodal_positions.size();
8155 unsigned n_nodal_hangings=nodal_hangings.size();
8161 MPI_Send(&n_nodal_positions,1,
8162 MPI_UNSIGNED,d,0,
Comm_pt->mpi_comm());
8163 if (n_nodal_positions>0)
8165 MPI_Send(&nodal_positions[0], n_nodal_positions,
8166 MPI_DOUBLE,d,0,
Comm_pt->mpi_comm());
8168 MPI_Send(&n_nodal_hangings,1,
8169 MPI_UNSIGNED,d,1,
Comm_pt->mpi_comm());
8170 if (n_nodal_hangings>0)
8172 MPI_Send(&nodal_hangings[0], n_nodal_hangings,
8173 MPI_INT,d,1,
Comm_pt->mpi_comm());
8180 oomph_info <<
"Max. error for external halo/haloed elements " << max_error
8182 if (max_error>max_permitted_error_for_halo_check)
8184 shout_and_terminate=
true;
8186 <<
"This is bigger than the permitted threshold " 8187 << max_permitted_error_for_halo_check << std::endl;
8189 <<
"If you believe this to be acceptable for your problem\n" 8190 <<
"increase Problem::Max_permitted_error_for_halo_check and re-run \n";
8193 if (shout_and_terminate)
8196 OOMPH_CURRENT_FUNCTION,
8197 OOMPH_EXCEPTION_LOCATION);
8210 unsigned n=ext_halo_node_pt.size();
8211 for (
unsigned j=0;j<n;j++)
8213 if (ext_halo_node_pt[j]==nod_pt)
8231 int my_rank=
Comm_pt->my_rank();
8246 for (
int domain=0;domain<n_proc;domain++)
8249 send_displacement[domain] = send_data.size();
8262 unsigned nnod=backup_pt.size();
8266 for (
unsigned j=0;j<nnod;j++)
8269 Node* nod_pt=backup_pt[j];
8275 send_data.push_back(j);
8286 send_data.push_back(-1);
8289 send_n[domain] = send_data.size() - send_displacement[domain];
8298 MPI_Alltoall(&send_n[0],1,MPI_INT,&receive_n[0],1,MPI_INT,
8305 int receive_data_count=0;
8306 for(
int rank=0;rank<n_proc;++rank)
8309 receive_displacement[rank] = receive_data_count;
8310 receive_data_count += receive_n[rank];
8315 if(receive_data_count==0) {++receive_data_count;}
8320 if(send_data.size()==0) {send_data.resize(1);}
8323 MPI_Alltoallv(&send_data[0],&send_n[0],&send_displacement[0],
8325 &receive_data[0],&receive_n[0],
8326 &receive_displacement[0],
8331 for (
int send_rank=0;send_rank<n_proc;send_rank++)
8335 if((send_rank != my_rank) && (receive_n[send_rank] != 0))
8338 unsigned count=receive_displacement[send_rank];
8345 int next_one=receive_data[count++];
8365 unsigned nnod=backup_pt.size();
8369 for (
unsigned j=0;j<nnod;j++)
8372 Node* nod_pt=backup_pt[j];
8398 int int_ndof_types = -1;
8402 int_ndof_types =
element_pt(0)->ndof_types();
8406 for (
unsigned i = 1;
i < nel;
i++)
8410 std::ostringstream error_message;
8412 <<
"Every element in the mesh must have the same number of " 8413 <<
"types of DOF for ndof_types() to work\n" 8414 <<
"Element 0 has " << int_ndof_types <<
" DOF types\n" 8415 <<
"Element " <<
i <<
" [out of a total of " << nel <<
" ] has " 8417 <<
"Element types are: Element 0:" <<
typeid(*
element_pt(0)).name()
8419 <<
" Current Element :" <<
typeid(*
element_pt(
i)).name()
8422 OOMPH_CURRENT_FUNCTION,
8423 OOMPH_EXCEPTION_LOCATION);
8429 #ifdef OOMPH_HAS_MPI 8440 unsigned nproc =
Comm_pt->nproc();
8441 unsigned my_rank =
Comm_pt->my_rank();
8446 int* ndof_types_recv = 0;
8449 ndof_types_recv =
new int[nproc];
8452 MPI_Gather(&int_ndof_types,1,MPI_INT,
8453 ndof_types_recv,1,MPI_INT,0,
8463 for (
unsigned p = 1; p < nproc; p++)
8465 if (ndof_types_recv[p] != -1)
8470 if (int_ndof_types == -1)
8472 int_ndof_types = ndof_types_recv[p];
8476 else if (int_ndof_types != ndof_types_recv[p])
8478 std::ostringstream error_message;
8480 <<
"The elements in this mesh must have the same number " 8481 <<
"of types of DOF on each processor";
8482 for (
unsigned p = 0; p < nproc; p++)
8484 if (ndof_types_recv[p] != -1)
8486 error_message <<
"Processor " << p <<
" : " 8487 << ndof_types_recv[p] <<
"\n";
8491 error_message <<
"Processor " << p <<
" : (no elements)\n";
8495 OOMPH_CURRENT_FUNCTION,
8496 OOMPH_EXCEPTION_LOCATION);
8503 for (
unsigned p = 1; p < nproc; p++)
8505 if (ndof_types_recv[p] == -1)
8507 MPI_Send(&int_ndof_types,1,MPI_INT,p,0,
8512 delete[] ndof_types_recv;
8517 else if (int_ndof_types == -1)
8519 MPI_Recv(&int_ndof_types,1,MPI_INT,0,0,
8520 Comm_pt->mpi_comm(),MPI_STATUS_IGNORE);
8528 if (int_ndof_types == -1) int_ndof_types = 0;
8530 return unsigned(int_ndof_types);
8553 std::ostringstream error_message;
8555 <<
"Every element in the mesh must have the same number of " 8556 <<
"elemental dimension for elemental_dimension() to work.\n" 8557 <<
"Element 0 has elemental dimension " << int_dim <<
"\n" 8558 <<
"Element " <<
i <<
" has elemental dimension " 8561 OOMPH_CURRENT_FUNCTION,
8562 OOMPH_EXCEPTION_LOCATION);
8568 #ifdef OOMPH_HAS_MPI 8579 unsigned nproc =
Comm_pt->nproc();
8580 unsigned my_rank =
Comm_pt->my_rank();
8588 dim_recv =
new int[nproc];
8591 MPI_Gather(&int_dim,1,MPI_INT,
8592 dim_recv,1,MPI_INT,0,
8602 for (
unsigned p = 1; p < nproc; p++)
8604 if (dim_recv[p] != -1)
8611 int_dim = dim_recv[p];
8615 else if (int_dim != dim_recv[p])
8617 std::ostringstream error_message;
8619 <<
"The elements in this mesh must have the same elemental " 8620 <<
"dimension number on each processor";
8621 for (
unsigned p = 0; p < nproc; p++)
8623 if (dim_recv[p] != -1)
8625 error_message <<
"Processor " << p <<
" : " 8626 << dim_recv[p] <<
"\n";
8630 error_message <<
"Processor " << p <<
" : (no elements)\n";
8634 OOMPH_CURRENT_FUNCTION,
8635 OOMPH_EXCEPTION_LOCATION);
8643 for (
unsigned p = 1; p < nproc; p++)
8645 if (dim_recv[p] == -1)
8647 MPI_Send(&int_dim,1,MPI_INT,p,0,
8657 else if (int_dim == -1)
8659 MPI_Recv(&int_dim,1,MPI_INT,0,0,
8660 Comm_pt->mpi_comm(),MPI_STATUS_IGNORE);
8668 if (int_dim == -1) int_dim = 0;
8670 return unsigned(int_dim);
8693 std::ostringstream error_message;
8695 <<
"Every element in the mesh must have the same number of " 8696 <<
"nodal dimension for nodal_dimension() to work.\n" 8697 <<
"Element 0 has nodal dimension " << int_dim <<
"\n" 8698 <<
"Element " <<
i <<
" has nodal dimension " 8701 OOMPH_CURRENT_FUNCTION,
8702 OOMPH_EXCEPTION_LOCATION);
8708 #ifdef OOMPH_HAS_MPI 8719 unsigned nproc =
Comm_pt->nproc();
8720 unsigned my_rank =
Comm_pt->my_rank();
8728 dim_recv =
new int[nproc];
8731 MPI_Gather(&int_dim,1,MPI_INT,
8732 dim_recv,1,MPI_INT,0,
8742 for (
unsigned p = 1; p < nproc; p++)
8744 if (dim_recv[p] != -1)
8751 int_dim = dim_recv[p];
8755 else if (int_dim != dim_recv[p])
8757 std::ostringstream error_message;
8759 <<
"The elements in this mesh must have the same nodal " 8760 <<
"dimension number on each processor";
8761 for (
unsigned p = 0; p < nproc; p++)
8763 if (dim_recv[p] != -1)
8765 error_message <<
"Processor " << p <<
" : " 8766 << dim_recv[p] <<
"\n";
8770 error_message <<
"Processor " << p <<
" : (no elements)\n";
8774 OOMPH_CURRENT_FUNCTION,
8775 OOMPH_EXCEPTION_LOCATION);
8783 for (
unsigned p = 1; p < nproc; p++)
8785 if (dim_recv[p] == -1)
8787 MPI_Send(&int_dim,1,MPI_INT,p,0,
8797 else if (int_dim == -1)
8799 MPI_Recv(&int_dim,1,MPI_INT,0,0,
8800 Comm_pt->mpi_comm(),MPI_STATUS_IGNORE);
8808 if (int_dim == -1) int_dim = 0;
8810 return unsigned(int_dim);
8819 #ifdef OOMPH_HAS_MPI 8846 bool found_a_master_in_external_halo_storage =
false;
8847 for(
unsigned m=0; m<hang_pt->
nmaster(); m++)
8853 bool found_this_master_in_external_halo_storage =
false;
8854 for(
int d=0; d<
Comm_pt->nproc(); d++)
8865 found_this_master_in_external_halo_storage =
true;
8872 if(found_this_master_in_external_halo_storage)
8875 found_a_master_in_external_halo_storage =
true;
8882 if(found_a_master_in_external_halo_storage)
8892 unsigned n_value=nod_pt->
nvalue();
8894 unsigned n_dim=nod_pt->
ndim();
8897 for(
unsigned t=0;
t<nt;
t++)
8902 for(
unsigned i=0;
i<n_dim;
i++) {nod_pt->
x(
t,
i)=position[
i];}
8909 bool update_all_time_levels=
true;
8917 if(solid_node_pt!=0)
8919 unsigned n_lagrangian = solid_node_pt->
nlagrangian();
8920 for(
unsigned i=0;
i<n_lagrangian;
i++)
8975 for (
unsigned j=0;j<n_ext_halo_nod;j++)
8979 for (
unsigned i_bnd=0;i_bnd<n_bnd;i_bnd++)
8996 for (
unsigned j=0;j<n_ext_halo_nod;j++)
8999 bool is_a_mesh_node=
false;
9000 unsigned n_node=
nnode();
9001 for (
unsigned jj=0;jj<n_node;jj++)
9005 is_a_mesh_node=
true;
9011 if (!is_a_mesh_node)
9021 int dd=(*itt).first;
9026 for (
unsigned jjj=0;jjj<n_ext_halo;jjj++)
9030 is_a_mesh_node=
true;
9038 if (!is_a_mesh_node)
9053 for (
unsigned e=0;
e<n_ext_halo_el;
e++)
9072 #ifdef OOMPH_HAS_MPI 9094 bool already_external_haloed_element=
false;
9095 unsigned external_haloed_el_index=0;
9096 for (
unsigned eh=0;eh<n_extern_haloed;eh++)
9101 already_external_haloed_element=
true;
9103 external_haloed_el_index=eh;
9109 if (!already_external_haloed_element)
9114 return n_extern_haloed;
9119 return external_haloed_el_index;
9134 bool is_an_external_haloed_node=
false;
9135 unsigned external_haloed_node_index=0;
9136 for (
unsigned k=0;k<n_ext_haloed_nod;k++)
9140 is_an_external_haloed_node=
true;
9141 external_haloed_node_index=k;
9147 if (!is_an_external_haloed_node)
9152 return n_ext_haloed_nod;
9157 return external_haloed_node_index;
9180 unsigned long n_node =
nnode();
9183 for(
unsigned n=0;n<n_node;n++)
9198 for(
unsigned k=0;k<n_lagrangian_type;k++)
9201 for(
unsigned j=0;j<n_lagrangian;j++)
9226 namespace ParaviewHelper
9233 <<
"<?xml version=\"1.0\"?>" << std::endl
9234 <<
"<VTKFile type=\"Collection\" version=\"0.1\">" << std::endl
9235 <<
"<Collection>"<< std::endl;
9246 <<
"<DataSet timestep=\"" 9251 pvd_file <<
"part=\"0\" ";
9257 <<
"\"/>" << std::endl;
9264 <<
"</Collection>" << std::endl
unsigned nshared_node()
Total number of shared nodes in this Mesh.
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
Boolean used to control warning about empty mesh level timestepper function.
void node_update(const bool &update_all_time_levels_for_new_node=false)
Broken assignment operator.
void assign_local_eqn_numbers(const bool &store_local_dof_pt)
Assign the local equation numbers in all elements If the boolean argument is true then also store poi...
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
A Generalised Element class.
virtual void distribute(OomphCommunicator *comm_pt, const Vector< unsigned > &element_domain, Vector< GeneralisedElement *> &deleted_element_pt, DocInfo &doc_info, const bool &report_stats, const bool &overrule_keep_as_halo_element_status)
Distribute the problem and doc; make this virtual to allow overloading for particular meshes where fu...
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...
void add_shared_node_pt(const unsigned &p, Node *&nod_pt)
Add shared node whose counterpart is held on processor p to the storage scheme for shared nodes...
virtual void reset_boundary_element_info(Vector< unsigned > &ntmp_boundary_elements, Vector< Vector< unsigned > > &ntmp_boundary_elements_in_region, Vector< FiniteElement *> &deleted_elements)
Virtual function to perform the reset boundary elements info rutines.
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...
virtual unsigned nscalar_paraview() const
Number of scalars/fields output by this element. Broken virtual. Needs to be implemented for each new...
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) ...
unsigned ndof_types() const
Return number of dof types in mesh.
std::map< unsigned, Vector< Node * > > Shared_node_pt
void write_pvd_footer(std::ofstream &pvd_file)
Write the pvd file footer.
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...
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
Vector< Node * > Node_pt
Vector of pointers to nodes.
std::map< unsigned, Vector< GeneralisedElement * > > Root_halo_element_pt
Map of vectors holding the pointers to the root halo elements.
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
unsigned nexternal_halo_element()
Total number of external halo elements in this Mesh.
std::map< unsigned, Vector< Node * > > Haloed_node_pt
Map of vectors holding the pointers to the haloed nodes.
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement *> &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this...
std::map< unsigned, Vector< GeneralisedElement * > > External_halo_element_pt
Map of vectors holding the pointers to the external halo elements.
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
bool is_doc_enabled() const
Are we documenting?
void resize_halo_nodes()
Helper function that resizes halo nodes to the same size as their non-halo counterparts if required...
bool does_pointer_correspond_to_value(double *const ¶meter_pt)
Check whether the pointer parameter_pt addresses internal data values.
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors. ...
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing...
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt)
Output a given Vector function at f(n_plot) points in each element.
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
unsigned add_external_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add external haloed element whose non-halo counterpart is held on processor p to the storage scheme f...
virtual ~Mesh()
Virtual Destructor to clean up all memory.
void set_nonhanging()
Label node as non-hanging node by removing all hanging node data.
Information for documentation of results: Directory and file number to enable output in the form RESL...
virtual unsigned nplot_points_paraview(const unsigned &nplot) const
Return the number of actual plot points for paraview plot with parameter nplot. Broken virtual; can b...
void get_external_halo_node_pt(Vector< Node *> &external_halo_node_pt)
Get vector of pointers to all external halo nodes.
std::string directory() const
Output directory.
void add_root_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add root haloed element whose non-halo counterpart is held on processor p to the storage scheme for h...
void add_halo_node_pt(const unsigned &p, Node *&nod_pt)
Add halo node whose non-halo counterpart is held on processor p to the storage scheme for halo nodes...
void shift_time_values()
Shift time-dependent data along for next timestep: Deal with nodal Data/positions and the element's i...
void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the elements. The ostream specifies the output stream to which...
virtual void get_refinement_levels(unsigned &min_refinement_level, unsigned &max_refinement_level)
Get max/min refinement levels in mesh.
std::map< unsigned, Vector< Node * > > External_haloed_node_pt
Map of vectors holding the pointers to the external haloed nodes.
void add_root_halo_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add root halo element whose non-halo counterpart is held on processor p to this Mesh.
unsigned nexternal_halo_node()
Total number of external halo nodes in this Mesh.
std::string & label()
String used (e.g.) for labeling output files.
bool Output_halo_elements
Bool for output of halo elements.
A general Finite Element class.
virtual void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Write values of the i-th scalar field at the plot points. Broken virtual. Needs to be implemented for...
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as ...
void get_halo_node_stats(double &av_number, unsigned &max_number, unsigned &min_number)
Get halo node stats for this distributed mesh: Average/max/min number of halo nodes over all processo...
virtual void set_mesh_level_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Function that can be used to set any additional timestepper data stored at the Mesh (as opposed to no...
int non_halo_proc_ID()
ID of processor ID that holds non-halo counterpart of halo node; negative if not a halo...
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
Target checked_dynamic_cast(Source *x)
Runtime checked dynamic cast. This is the safe but slightly slower cast. Use it in any of these cases...
bool is_halo() const
Is this element a halo?
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned nmaster() const
Return the number of master nodes.
unsigned self_test()
Self-test: Check elements and nodes. Return 0 for OK.
unsigned nodal_dimension() const
Return number of nodal dimension in mesh.
Vector< GeneralisedElement * > haloed_element_pt(const unsigned &p)
Return vector of haloed elements in this Mesh whose haloing counterpart is held on processor p...
void output_paraview(std::ofstream &file_out, const unsigned &nplot) const
Paraview output – this outputs the coordinates at the plot points (for parameter nplot) to specified...
virtual void dump(std::ofstream &dump_file, const bool &use_old_ordering=true) const
Dump the data in the mesh into a file for restart.
void set_elemental_internal_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Set the timestepper associated with the internal data stored within elements in the meah...
bool is_hanging() const
Test whether the node is geometrically hanging.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
unsigned nroot_haloed_element()
Total number of root haloed elements in this Mesh.
void output_external_haloed_elements(std::ostream &outfile, const unsigned &n_plot=5)
Output all external haloed elements.
bool Lookup_for_elements_next_boundary_is_setup
bool Doc_comprehensive_timings
Global boolean to switch on comprehensive timing – can probably be declared const false when develop...
void get_efficiency_of_mesh_distribution(double &av_efficiency, double &max_efficiency, double &min_efficiency)
Get efficiency of mesh distribution: In an ideal distribution without halo overhead, each processor would only hold its own elements. Efficieny per processor = (number of non-halo elements)/ (total number of elements).
void get_haloed_node_stats(double &av_number, unsigned &max_number, unsigned &min_number)
Get haloed node stats for this distributed mesh: Average/max/min number of haloed nodes over all proc...
double region_attribute(const unsigned &i)
Return the attribute associated with region i.
void read(std::ifstream &restart_file)
Read nodal positions (variable and fixed) and associated data from file for restart.
unsigned & number()
Number used (e.g.) for labeling output files.
void write_pvd_information(std::ofstream &pvd_file, const std::string &output_filename, const double &time)
Add name of output file and associated continuous time to pvd file.
void remove_boundary_node(const unsigned &b, Node *const &node_pt)
void set_obsolete()
Mark node as obsolete.
unsigned long nelement() const
Return number of elements in the mesh.
void output(std::ostream &outfile)
Output for all elements.
void assign_initial_values_impulsive()
Assign initial values for an impulsive start.
void add_node_pt(Node *const &node_pt)
Add a (pointer to a) node to the mesh.
void output_fct_paraview(std::ofstream &file_out, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
Output in paraview format into specified file. Breaks up each element into sub-elements for plotting ...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
virtual void remove_from_boundary(const unsigned &b)
Broken interface for removing the node from the mesh boundary b Here to provide error reporting...
virtual void write_paraview_type(std::ofstream &file_out, const unsigned &nplot) const
Return the paraview element type. Broken virtual. Needs to be implemented for each new geometric elem...
virtual void write_paraview_offsets(std::ofstream &file_out, const unsigned &nplot, unsigned &offset_sum) const
Return the offsets for the paraview sub-elements. Broken virtual. Needs to be implemented for each ne...
bool must_be_kept_as_halo() const
Test whether the element must be kept as a halo element.
void set_consistent_pinned_positions(Node *const &node_pt)
Set consistent values of the derivatives and current value when the Nodes position is pinned...
void flush_element_storage()
Flush storage for elements (only) by emptying the vectors that store the pointers to them...
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
void calculate_predictions()
Calculate predictions for all Data and positions associated with the mesh, usually used in adaptive t...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
double & xi(const unsigned &i)
Reference to i-th Lagrangian position.
unsigned add_external_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Add external haloed node whose halo (external) counterpart is held on processor p to the storage sche...
A class that contains the information required by Nodes that are located on Mesh boundaries. A BoundaryNode of a particular type is obtained by combining a given Node with this class. By differentiating between Nodes and BoundaryNodes we avoid a lot of un-necessary storage in the bulk Nodes.
bool Keep_all_elements_as_halos
bool to indicate whether to keep all elements in a mesh as halos or not
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
double & xi_gen(const unsigned &k, const unsigned &i)
Reference to the generalised Lagrangian position. `Type': k; 'Coordinate direction: i...
void check_inverted_elements(bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
Check for inverted elements and report outcome in boolean variable. This visits all elements at their...
void null_external_halo_node(const unsigned &p, Node *nod_pt)
Null out specified external halo node (used when deleting duplicates)
unsigned nhalo_node()
Total number of halo nodes in this Mesh.
void read(std::ifstream &restart_file)
Read nodal position and associated data from file for restart.
std::map< unsigned, Vector< GeneralisedElement * > > Root_haloed_element_pt
Map of vectors holding the pointers to the root haloed elements.
std::map< unsigned, Vector< GeneralisedElement * > > External_haloed_element_pt
Map of vectors holding the pointers to the external haloed elements.
void set_nonhalo()
Label the node as not being a halo.
std::ostream *& stream_pt()
Access function for the stream pointer.
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Compute the geometric shape functions and also first derivatives w.r.t. global coordinates at local c...
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
void copy(SolidNode *orig_node_pt)
Copy nodal positions and associated data from specified node object.
Base class for tree-based refineable meshes.
Node *& external_halo_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th external halo node in this Mesh whose non-halo external counterpart is held on...
unsigned nexternal_haloed_element()
Total number of external haloed elements in this Mesh.
virtual unsigned nsub_elements_paraview(const unsigned &nplot) const
Return the number of local sub-elements for paraview plot with parameter nplot. Broken virtual; can b...
virtual void create_shared_boundaries(OomphCommunicator *comm_pt, const Vector< unsigned > &element_domain, const Vector< GeneralisedElement *> &backed_up_el_pt, const Vector< FiniteElement *> &backed_up_f_el_pt, std::map< Data *, std::set< unsigned > > &processors_associated_with_data, const bool &overrule_keep_as_halo_element_status)
Creates the shared boundaries, only used in unstructured meshes In this case with the "TriangleMesh" ...
unsigned nboundary() const
Return number of boundaries.
virtual void classify_halo_and_haloed_nodes(DocInfo &doc_info, const bool &report_stats)
Classify the halo and haloed nodes in the mesh. Virtual so it can be overloaded to perform additional...
unsigned nexternal_haloed_node()
Total number of external haloed nodes in this Mesh.
static bool Suppress_output_while_checking_for_inverted_elements
Static boolean to suppress output while checking for inverted elements.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
Tree * tree_pt()
Access function: Pointer to quadtree representation of this element.
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...
Vector< Node * > prune_dead_nodes()
Prune nodes. Nodes that have been marked as obsolete are removed from the mesh (and its boundary-node...
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
virtual void setup_tree_forest()=0
Set up the tree forest associated with the Mesh (if any)
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...
void position(Vector< double > &pos) const
Compute Vector of nodal positions either directly or via hanging node representation.
void check_jacobian(const double &jacobian) const
Helper function used to check for singular or negative Jacobians in the transform from local to globa...
void output_boundaries(std::ostream &outfile)
Output the nodes on the boundaries (into separate tecplot zones)
void set_nodal_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Set the timestepper associated with the nodal data in the mesh.
virtual void write_paraview_output_offset_information(std::ofstream &file_out, const unsigned &nplot, unsigned &counter) const
Fill in the offset information for paraview plot. Broken virtual. Needs to be implemented for each ne...
void add_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Add haloed node whose halo counterpart is held on processor p to the storage scheme for haloed nodes...
void remove_null_pointers_from_external_halo_node_storage()
Consolidate external halo node storage by removing nulled out pointes in external halo and haloed sch...
unsigned nregion()
Return the number of regions specified by attributes.
void prune_halo_elements_and_nodes(Vector< GeneralisedElement *> &deleted_element_pt, const bool &report_stats=false)
(Irreversibly) prune halo(ed) elements and nodes, usually after another round of refinement, to get rid of excessively wide halo layers. Note that the current mesh will be now regarded as the base mesh and no unrefinement relative to it will be possible once this function has been called.
virtual void get_node_reordering(Vector< Node *> &reordering, const bool &use_old_ordering=true) const
Get a reordering of the nodes in the order in which they appear in elements – can be overloaded for ...
virtual std::string scalar_name_paraview(const unsigned &i) const
Name of the i-th scalar field. Default implementation returns V1 for the first one, V2 for the second etc. Can (should!) be overloaded with more meaningful names in specific elements.
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
double & x_gen(const unsigned &k, const unsigned &i)
Reference to the generalised position x(k,i).
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
Node *& external_haloed_node_pt(const unsigned &p, const unsigned &j)
Access fct to the j-th external haloed node in this Mesh whose halo external counterpart is held on p...
void get_father_at_refinement_level(unsigned &refinement_level, RefineableElement *&father_at_reflevel_pt)
Return a pointer to the "father" element at the specified refinement level.
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output an exact solution over the element.
void read(std::ifstream &restart_file)
Read data object from a file.
unsigned refinement_level() const
Return the Refinement level.
double lagrangian_position(const unsigned &i) const
Return lagrangian coordinate either directly or via hanging node representation.
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
void check_halo_schemes(DocInfo &doc_info, double &max_permitted_error_for_halo_check)
Check halo and shared schemes on the mesh.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
double timer()
returns the time in seconds after some point in past
unsigned nlagrangian_type() const
Number of types of Lagrangian coordinates used to interpolate the Lagrangian coordinates within the e...
void dump(std::ostream &dump_file) const
Dump the data object to a file.
unsigned nhaloed_node()
Total number of haloed nodes in this Mesh.
std::map< unsigned, Vector< Node * > > Halo_node_pt
Map of vectors holding the pointers to the halo nodes.
Class that contains data for hanging nodes.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
GeneralisedTimestepper used to store the arclength derivatives and pervious solutions required in con...
void doc_mesh_distribution(DocInfo &doc_info)
Doc the mesh distribution, to be processed with tecplot macros.
bool Resize_halo_nodes_not_required
Set this to true to suppress resizing of halo nodes (at your own risk!)
unsigned long nnode() const
Return number of nodes in the mesh.
unsigned ntstorage() const
Return total number of doubles stored per value to record time history of each value (one for steady ...
std::map< unsigned, Vector< Node * > > External_halo_node_pt
Map of vectors holding the pointers to the external halo nodes.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
void merge_meshes(const Vector< Mesh *> &sub_mesh_pt)
Merge meshes. Note: This simply merges the meshes' elements and nodes (ignoring duplicates; no bounda...
void copy(Node *orig_node_pt)
Copy all nodal data from specified Node object.
void set_halo(const unsigned &non_halo_proc_ID)
Label the node as halo and specify processor that holds non-halo counterpart.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
virtual void node_update(const bool &update_all_solid_nodes=false)
Update nodal positions in response to changes in the domain shape. Uses the FiniteElement::get_x(...) function for FiniteElements and doesn't do anything for other element types. If a MacroElement pointer has been set for a FiniteElement, the MacroElement representation is used to update the nodal positions; if not get_x(...) uses the FE interpolation and thus leaves the nodal positions unchanged. Virtual, so it can be overloaded by specific meshes, such as AlgebraicMeshes or SpineMeshes. Generally, this function updates the position of all nodes in response to changes in the boundary position. However, we ignore all SolidNodes since their position is computed as part of the solution – unless the bool flag is set to true. Such calls are typically made when the initial mesh is created and/or after a mesh has been refined repeatedly before the start of the computation.
unsigned ninternal_data() const
Return the number of internal data objects.
A Class for nodes that deform elastically (i.e. position is an unknown in the problem). The idea is that the Eulerian positions are stored in a Data object and the Lagrangian coordinates are stored in addition. The pointer that addresses the Eulerian positions is set to the pointer to Value in the Data object. Hence, SolidNode uses knowledge of the internal structure of Data and must be a friend of the Data class. In order to allow a mesh to deform via an elastic-style equation in deforming-domain problems, the positions are stored separately from the values, so that elastic problems may be combined with any other type of problem.
unsigned nroot_halo_element()
Total number of root halo elements in this Mesh.
void stick_all_tree_nodes_into_vector(Vector< Tree * > &)
Traverse and stick pointers to all "nodes" into Vector.
Vector< Vector< Node * > > Boundary_node_pt
Vector of Vector of pointers to nodes on the boundaries: Boundary_node_pt(b,n). Note that this is pri...
void synchronise_shared_nodes(const bool &report_stats)
Synchronise shared node lookup schemes to cater for the the case where: (1) a certain node on the cur...
void resize(const unsigned &n_value)
Resize the number of equations.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
void set_consistent_pinned_values_for_continuation(ContinuationStorageScheme *const &continuation_stepper_pt)
Set consistent values for pinned data in continuation.
void output_external_halo_elements(std::ostream &outfile, const unsigned &n_plot=5)
Output all external halo elements.
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...
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
void set_consistent_pinned_values(Data *const &data_pt)
Set consistent values of the derivatives and current value when the data is pinned. This must be done by the "timestepper" because only it knows the local storage scheme.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
unsigned check_for_repeated_nodes(const double &epsilon=1.0e-12)
Check for repeated nodes within a given spatial tolerance. Return (0/1) for (pass/fail).
bool does_pointer_correspond_to_mesh_data(double *const ¶meter_pt)
Does the double pointer correspond to any mesh data.
void get_all_halo_data(std::map< unsigned, double *> &map_of_halo_data)
Get all the halo data stored in the mesh and add pointers to the data to the map, indexed by global e...
virtual void setup_boundary_element_info()
Interface for function that is used to setup the boundary information (Empty virtual function – impl...
static SolidICProblem Solid_IC_problem
Static problem that can be used to assign initial conditions on a given solid mesh (need to define th...
void add_element_pt(GeneralisedElement *const &element_pt)
Add a (pointer to) an element to the mesh.
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 ...
bool node_global_position_comparison(Node *nd1_pt, Node *nd2_pt)
bool is_halo() const
Is this Data a halo?
unsigned elemental_dimension() const
Return number of elemental dimension in mesh.
virtual void scalar_value_fct_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
Write values of the i-th scalar field at the plot points. Broken virtual. Needs to be implemented for...
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
void describe_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the dofs of the Mesh. The ostream specifies the output stream to which the descr...
RefineableElement * object_pt() const
Return the pointer to the object (RefineableElement) represented by the tree.
unsigned long assign_global_eqn_numbers(Vector< double *> &Dof_pt)
Assign the global equation numbers in the Data stored at the nodes and also internal element Data...
void add_internal_value_pt_to_map(std::map< unsigned, double *> &map_of_value_pt)
Add pointers to the internal data values to map indexed by the global equation number.
void flush_element_and_node_storage()
Flush storage for elements and nodes by emptying the vectors that store the pointers to them...
unsigned nlagrangian() const
Return number of lagrangian coordinates.
virtual void add_to_boundary(const unsigned &b)
Broken interface for adding the node to the mesh boundary b Essentially here for error reporting...
std::map< unsigned, unsigned > *& index_of_first_value_assigned_by_face_element_pt()
Return pointer to the map giving the index of the first face element value.
void set_non_obsolete()
Mark node as non-obsolete.
void stick_leaves_into_vector(Vector< Tree * > &)
Traverse tree and stick pointers to leaf "nodes" (only) into Vector.
bool is_leaf()
Return true if the tree is a leaf node.
unsigned nnode() const
Return the number of nodes.
unsigned hang_code()
Code that encapsulates the hanging status of the node (incl. the geometric hanging status) as ...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
void delete_all_external_storage()
Wipe the storage for all externally-based elements.
OomphCommunicator * Comm_pt
Pointer to communicator – set to NULL if mesh is not distributed.
void set_lagrangian_nodal_coordinates()
Make the current configuration the undeformed one by setting the nodal Lagrangian coordinates to thei...
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...
bool is_obsolete()
Test whether node is obsolete.
unsigned uniform_refinement_level_when_pruned() const
Level to which the mesh was uniformly refined when it was pruned (const version)
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation...
IC problem for an elastic body discretised on a given (sub)-mesh. We switch the elements' residuals a...
TreeRoot *& root_pt()
Return pointer to root of the tree.
void remove_boundary_nodes()
Clear all pointers to boundary nodes.
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...
void output_paraview(std::ofstream &file_out, const unsigned &nplot) const
Output in paraview format into specified file. Breaks up each element into sub-elements for plotting ...
void setup_shared_node_scheme()
Setup shared node scheme.
void flush_object()
Flush the object represented by the tree.
virtual void read(std::ifstream &restart_file)
Read solution from restart file.
void write_pvd_header(std::ofstream &pvd_file)
Write the pvd file header.
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...