33 #ifndef OOMPH_MULTI_DOMAIN_CC 34 #define OOMPH_MULTI_DOMAIN_CC 38 #include <oomph-lib-config.h> 77 template<
class BULK_ELEMENT,
unsigned DIM>
81 Mesh*
const &bulk_mesh_pt,
83 const unsigned& interaction)
86 unsigned n_mesh=boundary_in_bulk_mesh.size();
90 if (boundary_in_bulk_mesh.size()!=face_mesh_pt.size())
92 std::ostringstream error_message;
94 <<
"Sizes of vector of boundary ids in bulk mesh (" 95 << boundary_in_bulk_mesh.size() <<
") and vector of pointers\n" 96 <<
"to FaceElements (" << face_mesh_pt.size() <<
" doesn't match.\n";
99 OOMPH_CURRENT_FUNCTION,
100 OOMPH_EXCEPTION_LOCATION);
110 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
112 bulk_face_mesh_pt[i_mesh] =
new Mesh;
113 bulk_mesh_pt->template build_face_mesh
115 bulk_face_mesh_pt[i_mesh]);
120 unsigned n_face_element = bulk_face_mesh_pt[i_mesh]->nelement();
121 for(
unsigned e=0;
e<n_face_element;
e++)
126 (bulk_face_mesh_pt[i_mesh]->element_pt(
e));
142 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
148 for (
unsigned i=0;
i<DIM;
i++)
152 for (
unsigned i=0;
i<DIM-1;
i++)
166 std::sort(bulk_face_mesh_pt[i_mesh]->element_pt().begin(),
167 bulk_face_mesh_pt[i_mesh]->element_pt().end(),
178 (problem_pt,face_mesh_pt,bulk_mesh_pt,
179 bulk_face_mesh_pt,interaction);
183 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
185 unsigned n_face_element = bulk_face_mesh_pt[i_mesh]->nelement();
191 for(
unsigned e=n_face_element;
e>0;
e--)
193 delete bulk_face_mesh_pt[i_mesh]->element_pt(
e-1);
194 bulk_face_mesh_pt[i_mesh]->element_pt(
e-1) = 0;
197 bulk_face_mesh_pt[i_mesh]->flush_element_and_node_storage();
200 delete bulk_face_mesh_pt[i_mesh];
215 template<
class BULK_ELEMENT,
unsigned DIM>
218 const unsigned& boundary_in_bulk_mesh,
219 Mesh*
const& bulk_mesh_pt,
220 Mesh*
const& face_mesh_pt,
221 const unsigned& interaction)
225 boundary_in_bulk_mesh_vect[0]=boundary_in_bulk_mesh;
227 face_mesh_pt_vect[0]=face_mesh_pt;
230 setup_bulk_elements_adjacent_to_face_mesh<BULK_ELEMENT,DIM>(
231 problem_pt, boundary_in_bulk_mesh_vect, bulk_mesh_pt,
232 face_mesh_pt_vect,interaction);
250 template<
class ELEMENT_0,
class ELEMENT_1>
253 const unsigned& first_interaction,
const unsigned& second_interaction)
260 setup_multi_domain_interaction<ELEMENT_1>
261 (problem_pt,first_mesh_pt,second_mesh_pt,first_interaction);
263 setup_multi_domain_interaction<ELEMENT_0>
264 (problem_pt,second_mesh_pt,first_mesh_pt,second_interaction);
284 template<
class EXT_ELEMENT>
287 const unsigned& interaction_index)
298 std::ostringstream error_stream;
299 error_stream <<
"The elements within the two interacting meshes have a\n" 300 <<
"dimension not equal to 1, 2 or 3.\n" 301 <<
"The multi-domain method will not work in this case.\n" 302 <<
"The dimension is: " <<
Dim <<
"\n";
305 OOMPH_CURRENT_FUNCTION,
306 OOMPH_EXCEPTION_LOCATION);
310 aux_setup_multi_domain_interaction<EXT_ELEMENT,EXT_ELEMENT>
311 (problem_pt,mesh_pt,external_mesh_pt,interaction_index);
341 template<
class EXT_ELEMENT,
class FACE_ELEMENT_GEOM_OBJECT>
344 Mesh*
const &external_face_mesh_pt,
const unsigned& interaction_index)
355 std::ostringstream error_stream;
356 error_stream <<
"The elements within the two interacting meshes have a\n" 357 <<
"dimension not equal to 1 or 2.\n" 358 <<
"The multi-domain method will not work in this case.\n" 359 <<
"The dimension is: " <<
Dim <<
"\n";
362 OOMPH_CURRENT_FUNCTION,
363 OOMPH_EXCEPTION_LOCATION);
368 <EXT_ELEMENT,FACE_ELEMENT_GEOM_OBJECT>
369 (problem_pt,mesh_pt,external_mesh_pt,
370 interaction_index,external_face_mesh_pt);
402 template<
class EXT_ELEMENT,
class FACE_ELEMENT_GEOM_OBJECT>
406 const unsigned& interaction_index)
410 unsigned n_mesh=mesh_pt.size();
413 if (external_face_mesh_pt.size()!=n_mesh)
415 std::ostringstream error_stream;
416 error_stream <<
"Sizes of external_face_mesh_pt [ " 417 << external_face_mesh_pt.size() <<
" ] and " 418 <<
"mesh_pt [ " << n_mesh <<
" ] don't match.\n";
421 OOMPH_CURRENT_FUNCTION,
422 OOMPH_EXCEPTION_LOCATION);
427 if (n_mesh==0)
return;
439 unsigned old_dim=
Dim;
440 for (
unsigned i=1;
i<n_mesh;
i++)
447 std::ostringstream error_stream;
449 <<
"Inconsistency: Mesh " << i <<
" has Dim=" <<
Dim 450 <<
"while mesh 0 has Dim="<< old_dim << std::endl;
453 OOMPH_CURRENT_FUNCTION,
454 OOMPH_EXCEPTION_LOCATION);
461 std::ostringstream error_stream;
462 error_stream <<
"The elements within the two interacting meshes have a\n" 463 <<
"dimension not equal to 1 or 2.\n" 464 <<
"The multi-domain method will not work in this case.\n" 465 <<
"The dimension is: " <<
Dim <<
"\n";
468 OOMPH_CURRENT_FUNCTION,
469 OOMPH_EXCEPTION_LOCATION);
474 <EXT_ELEMENT,FACE_ELEMENT_GEOM_OBJECT>
475 (problem_pt,mesh_pt,external_mesh_pt,
476 interaction_index,external_face_mesh_pt);
494 template<
class EXT_ELEMENT,
class GEOM_OBJECT>
497 const unsigned& interaction_index,
Mesh*
const &external_face_mesh_pt)
501 mesh_pt_vector[0]=mesh_pt;
503 external_face_mesh_pt_vector[0]=external_face_mesh_pt;
506 aux_setup_multi_domain_interaction<EXT_ELEMENT,GEOM_OBJECT>
507 (problem_pt, mesh_pt_vector,
508 external_mesh_pt, interaction_index,
509 external_face_mesh_pt_vector);
531 template<
class EXT_ELEMENT,
class GEOM_OBJECT>
534 Mesh*
const &external_mesh_pt,
const unsigned& interaction_index,
538 unsigned n_mesh=mesh_pt.size();
541 if (external_face_mesh_pt.size()!=n_mesh)
543 std::ostringstream error_stream;
544 error_stream <<
"Sizes of external_face_mesh_pt [ " 545 << external_face_mesh_pt.size() <<
" ] and " 546 <<
"mesh_pt [ " << n_mesh <<
" ] don't match.\n";
549 OOMPH_CURRENT_FUNCTION,
550 OOMPH_EXCEPTION_LOCATION);
555 if (n_mesh==0)
return;
566 if (external_mesh_pt->
nelement()!=0)
568 ext_el_pt_0 = external_mesh_pt->
element_pt(0);
572 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
576 if (mesh_pt[i_mesh]->nelement()!=0)
578 el_pt_0 = mesh_pt[i_mesh]->element_pt(0);
582 if(dynamic_cast<SpectralElement*>(el_pt_0)!=0
583 || dynamic_cast<SpectralElement*>(ext_el_pt_0)!=0)
586 "Multi-domain setup does not work with spectral elements.",
587 OOMPH_CURRENT_FUNCTION,
588 OOMPH_EXCEPTION_LOCATION);
592 if(dynamic_cast<PRefineableElement*>(el_pt_0)!=0
593 || dynamic_cast<PRefineableElement*>(ext_el_pt_0)!=0)
596 "Multi-domain setup does not work with hp-refineable elements.",
597 OOMPH_CURRENT_FUNCTION,
598 OOMPH_EXCEPTION_LOCATION);
613 double t_start=0.0;
double t_end=0.0;
double t_local=0.0;
614 double t_set=0.0;
double t_locate=0.0;
double t_spiral_start=0.0;
616 double t_loop_start=0.0;
617 double t_sendrecv=0.0;
618 double t_missing=0.0;
619 double t_send_info=0.0;
double t_create_halo=0.0;
628 unsigned n_zeta_not_found=0;
636 unsigned el_dim_lag = 0;
641 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
649 std::ostringstream error_stream;
651 <<
"Sorry I currently can't deal with non-bulk external elements\n" 652 <<
"in multi-domain setup for multiple meshes.\n" 653 <<
"The functionality should be easy to implement now that you\n" 654 <<
"have a test case. If you're not willinig to do this, call\n" 655 <<
"the multi-domain setup mesh-by-mesh instead (though this can\n" 656 <<
"be costly in parallel because of global comms. \n";
659 OOMPH_CURRENT_FUNCTION,
660 OOMPH_EXCEPTION_LOCATION);
669 mesh_geom_obj_pt[i_mesh]=
674 unsigned old_el_dim_lag=el_dim_lag;
677 el_dim_lag = mesh_geom_obj_pt[i_mesh]->nlagrangian();
682 if (el_dim_lag!=old_el_dim_lag)
684 std::ostringstream error_stream;
685 error_stream <<
"Lagrangian dimensions of elements don't match \n " 686 <<
"between meshes: " << el_dim_lag <<
" " 687 << old_el_dim_lag <<
"\n";
690 OOMPH_CURRENT_FUNCTION,
691 OOMPH_EXCEPTION_LOCATION);
699 double t_setup_lookups=0.0;
703 oomph_info <<
"CPU for creation of MeshAsGeomObjects and bin structure: " 704 << t_set-t_start << std::endl;
715 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
717 e_count+=mesh_pt[i_mesh]->nelement();
725 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
728 unsigned n_element=mesh_pt[i_mesh]->nelement();
729 for (
unsigned e=0;
e<n_element;
e++)
735 mesh_pt[i_mesh]->element_pt(
e));
751 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
757 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
772 <<
"CPU for setup of lookup schemes for located elements/coords: " 773 << t-t_setup_lookups << std::endl;
778 unsigned n_max_level=0;
781 unsigned max_level_reached=1;
786 unsigned max_n_sample_points_of_sample_point_containers = 0;
789 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
792 if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version()==
797 sample_point_container_pt());
800 last_sample_point_to_actually_lookup_during_locate_zeta() =
802 initial_last_sample_point_to_actually_lookup_during_locate_zeta();
804 first_sample_point_to_actually_lookup_during_locate_zeta() = 0;
806 unsigned nsp=bin_array_pt->
807 total_number_of_sample_points_computed_recursively();
808 if (nsp>max_n_sample_points_of_sample_point_containers)
810 max_n_sample_points_of_sample_point_containers=nsp;
819 unsigned local_max_n_sample_points_of_sample_point_containers=
820 max_n_sample_points_of_sample_point_containers;
823 MPI_Allreduce(&local_max_n_sample_points_of_sample_point_containers,
824 &max_n_sample_points_of_sample_point_containers,1,
825 MPI_UNSIGNED,MPI_MAX,
831 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version()==
836 sample_point_container_pt());
852 #ifdef OOMPH_HAS_CGAL 854 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version()==
859 sample_point_container_pt());
861 last_sample_point_to_actually_lookup_during_locate_zeta() =
863 initial_last_sample_point_to_actually_lookup_during_locate_zeta();
865 first_sample_point_to_actually_lookup_during_locate_zeta() = 0;
867 unsigned nsp=bin_array_pt->
868 total_number_of_sample_points_computed_recursively();
869 if (nsp>max_n_sample_points_of_sample_point_containers)
871 max_n_sample_points_of_sample_point_containers=nsp;
880 unsigned local_max_n_sample_points_of_sample_point_containers=
881 max_n_sample_points_of_sample_point_containers;
884 MPI_Allreduce(&local_max_n_sample_points_of_sample_point_containers,
885 &max_n_sample_points_of_sample_point_containers,1,
886 MPI_UNSIGNED,MPI_MAX,
902 unsigned i_level = 0;
903 bool has_not_reached_max_level_of_search=
true;
904 while (has_not_reached_max_level_of_search)
922 unsigned count_locates = 0;
924 for (
unsigned e=0;
e<n_ext_loc;
e++)
927 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
938 percentage_coords_located_locally.push_back(
939 100.0 *
double(count_locates) /
double(tot_int));
944 percentage_coords_located_locally.push_back(100.0);
964 <<
"CPU for local location of zeta coordinate [spiral level " 966 << t_local - t_spiral_start << std::endl
967 <<
"Number of missing zetas: " << n_zeta_not_found
976 unsigned count_local_zetas=n_zeta_not_found;
977 MPI_Allreduce(&count_local_zetas,&n_zeta_not_found,1,
978 MPI_UNSIGNED,MPI_SUM,
987 double t_sendrecv_min= DBL_MAX;
988 double t_sendrecv_max=-DBL_MAX;
989 double t_sendrecv_tot=0.0;
991 double t_missing_min= DBL_MAX;
992 double t_missing_max=-DBL_MAX;
993 double t_missing_tot=0.0;
995 double t_send_info_min= DBL_MAX;
996 double t_send_info_max=-DBL_MAX;
997 double t_send_info_tot=0.0;
999 double t_create_halo_min= DBL_MAX;
1000 double t_create_halo_max=-DBL_MAX;
1001 double t_create_halo_tot=0.0;
1008 unsigned ring_count=0;
1009 for (
int iproc=1;iproc<n_proc;iproc++)
1028 t_sendrecv_max=std::max(t_sendrecv_max,t_sendrecv-t_loop_start);
1029 t_sendrecv_min=std::min(t_sendrecv_min,t_sendrecv-t_loop_start);
1030 t_sendrecv_tot+=(t_sendrecv-t_loop_start);
1035 (iproc,external_mesh_pt,problem_pt,mesh_geom_obj_pt);
1040 t_missing_max=std::max(t_missing_max,t_missing-t_sendrecv);
1041 t_missing_min=std::min(t_missing_min,t_missing-t_sendrecv);
1042 t_missing_tot+=(t_missing-t_sendrecv);
1052 t_send_info_max=std::max(t_send_info_max,t_send_info-t_missing);
1053 t_send_info_min=std::min(t_send_info_min,t_send_info-t_missing);
1054 t_send_info_tot+=(t_send_info-t_missing);
1058 create_external_halo_elements<EXT_ELEMENT>
1059 (iproc,mesh_pt,external_mesh_pt,problem_pt,interaction_index);
1064 t_create_halo_max=std::max(t_create_halo_max,
1065 t_create_halo-t_send_info);
1066 t_create_halo_min=std::min(t_create_halo_min,
1067 t_create_halo-t_send_info);
1068 t_create_halo_tot+=(t_create_halo-t_send_info);
1080 #ifdef OOMPH_HAS_MPI 1081 if (problem_pt->communicator_pt()->nproc() > 1)
1083 unsigned count_local_zetas=n_zeta_not_found;
1084 MPI_Allreduce(&count_local_zetas,&n_zeta_not_found,1,
1085 MPI_UNSIGNED,MPI_SUM,
1086 problem_pt->communicator_pt()->mpi_comm());
1091 if (n_zeta_not_found==0)
1097 <<
"BREAK N-1: CPU for entrire spiral [spiral level " 1099 << t_local-t_spiral_start << std::endl;
1110 <<
"Ring-based search continued until iteration " 1111 << ring_count <<
" out of a maximum of " 1114 <<
"Total, av, max, min CPU for send/recv of remaining zeta coordinates: " 1115 << t_sendrecv_tot <<
" " 1116 << t_sendrecv_tot/double(ring_count) <<
" " 1117 << t_sendrecv_max <<
" " 1118 << t_sendrecv_min <<
"\n";
1120 <<
"Total, av, max, min CPU for location of missing zeta coordinates : " 1121 << t_missing_tot <<
" " 1122 << t_missing_tot/double(ring_count) <<
" " 1123 << t_missing_max <<
" " 1124 << t_missing_min <<
"\n";
1126 <<
"Total, av, max, min CPU for send/recv of new element info : " 1127 << t_send_info_tot <<
" " 1128 << t_send_info_tot/double(ring_count) <<
" " 1129 << t_send_info_max <<
" " 1130 << t_send_info_min <<
"\n";
1132 <<
"Total, av, max, min CPU for local creation of external halo objects: " 1133 << t_create_halo_tot <<
" " 1134 << t_create_halo_tot/double(ring_count) <<
" " 1135 << t_create_halo_max <<
" " 1136 << t_create_halo_min <<
"\n";
1146 unsigned count_locates=0;
1148 for (
unsigned e=0;
e<n_ext_loc;
e++)
1151 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
1163 percentage_coords_located_elsewhere.push_back(
1164 100.0*
double(count_locates)/
double(tot_int));
1169 percentage_coords_located_locally.push_back(100.0);
1184 #ifdef OOMPH_HAS_MPI 1187 unsigned count_local_zetas=n_zeta_not_found;
1188 MPI_Allreduce(&count_local_zetas,&n_zeta_not_found,1,
1189 MPI_UNSIGNED,MPI_SUM,
1194 max_level_reached=i_level+1;
1198 if (n_zeta_not_found==0)
1204 <<
"BREAK N: CPU for entrire spiral [spiral level " 1206 << t_local-t_spiral_start << std::endl;
1215 <<
"CPU for entrire spiral [spiral level " 1217 << t_local-t_spiral_start << std::endl;
1222 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
1224 if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version()==
1230 sample_point_container_pt());
1232 first_sample_point_to_actually_lookup_during_locate_zeta() =
1234 last_sample_point_to_actually_lookup_during_locate_zeta();
1236 last_sample_point_to_actually_lookup_during_locate_zeta() *=
1238 multiplier_for_max_sample_point_to_actually_lookup_during_locate_zeta();
1240 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version()==
1245 sample_point_container_pt());
1250 #ifdef OOMPH_HAS_CGAL 1251 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version()==
1256 sample_point_container_pt());
1258 first_sample_point_to_actually_lookup_during_locate_zeta() =
1260 last_sample_point_to_actually_lookup_during_locate_zeta();
1262 last_sample_point_to_actually_lookup_during_locate_zeta() *=
1264 multiplier_for_max_sample_point_to_actually_lookup_during_locate_zeta();
1270 if (mesh_geom_obj_pt[0]->sample_point_container_version()==
1275 sample_point_container_pt());
1278 first_sample_point_to_actually_lookup_during_locate_zeta()
1279 <= max_n_sample_points_of_sample_point_containers)
1281 has_not_reached_max_level_of_search=
true;
1285 has_not_reached_max_level_of_search=
false;
1288 else if (mesh_geom_obj_pt[0]->sample_point_container_version()==
1293 sample_point_container_pt());
1297 has_not_reached_max_level_of_search=
true;
1301 has_not_reached_max_level_of_search=
false;
1304 #ifdef OOMPH_HAS_CGAL 1305 else if (mesh_geom_obj_pt[0]->sample_point_container_version()==
1310 sample_point_container_pt());
1313 first_sample_point_to_actually_lookup_during_locate_zeta()
1314 <= max_n_sample_points_of_sample_point_containers)
1316 has_not_reached_max_level_of_search=
true;
1320 has_not_reached_max_level_of_search=
false;
1329 if (n_zeta_not_found!=0)
1335 std::ostringstream error_stream;
1337 <<
"Multi_domain_functions::locate_zeta_for_local_coordinates()" 1340 #ifdef OOMPH_HAS_MPI 1343 error_stream <<
" on proc: " 1349 <<
"\n\n\nThis is most likely to arise because the two meshes\n" 1350 <<
"that are to be matched don't overlap perfectly or\n" 1351 <<
"because the elements are distorted and too small a \n" 1352 <<
"number of sampling points has been used when setting\n" 1353 <<
"up the bin structure.\n\n" 1354 <<
"You should try to increase the value of \n" 1355 <<
"the number of sample points defined in \n\n" 1356 <<
" SamplePointContainerParameters::Default_nsample_points_generated_per_element" 1357 <<
"\n\n from its current value of " 1360 <<
"NOTE: You can suppress this error and \"accept failure\"" 1361 <<
" by setting the public boolean \n\n" 1362 <<
" Multi_domain_functions::Accept_failed_locate_zeta_in_setup_multi_domain_interaction\n\n" 1363 <<
" to true. In this case, the pointers to external elements\n" 1364 <<
" that couldn't be located will remain null\n";
1366 std::ostringstream modifier;
1367 #ifdef OOMPH_HAS_MPI 1375 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
1381 modifier <<
"_mesh" << i_mesh;
1384 std::ofstream outfile;
1386 sprintf(filename,
"missing_coords_mesh%s.dat",modifier.str().c_str());
1387 outfile.open(filename);
1388 unsigned nel=mesh_pt[i_mesh]->nelement();
1389 for (
unsigned e=0;
e<nel;
e++)
1391 mesh_pt[i_mesh]->finite_element_pt(
e)->
1396 sprintf(filename,
"missing_coords_ext_mesh%s.dat",
1397 modifier.str().c_str());
1398 outfile.open(filename);
1400 for (
unsigned e=0;
e<nel;
e++)
1408 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
1409 if (bin_array_pt!=0)
1411 sprintf(filename,
"missing_coords_bin%s.dat",modifier.str().c_str());
1412 outfile.open(filename);
1417 sprintf(filename,
"missing_coords%s.dat",modifier.str().c_str());
1418 outfile.open(filename);
1420 error_stream <<
"Number of unlocated elements " << n << std::endl;
1421 for (
unsigned e=0;
e<n;
e++)
1427 <<
"Failure to locate in halo element! " 1428 <<
"Why are we searching there?" 1431 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
1435 error_stream <<
"Failure at element/intpt: " 1436 <<
e <<
" " << ipt << std::endl;
1441 mesh_pt[i_mesh]->element_pt(
e));
1443 unsigned n_dim_el=el_pt->
dim();
1445 for (
unsigned i=0;
i<n_dim_el;
i++)
1452 for (
unsigned i=0;
i<n_dim;
i++)
1454 error_stream << x[
i] <<
" ";
1455 outfile<< x[
i] <<
" ";
1457 error_stream << std::endl;
1458 outfile << std::endl;
1466 <<
"Mesh and external mesh documented in missing_coords_mesh*.dat\n" 1467 <<
"and missing_coords_ext_mesh*.dat, respectively. Missing \n" 1468 <<
"coordinates in missing_coords*.dat\n";
1470 (error_stream.str(),
1471 OOMPH_CURRENT_FUNCTION,
1472 OOMPH_EXCEPTION_LOCATION);
1478 <<
"NOTE: Haven't found " << n_zeta_not_found
1479 <<
" external elements in \n" 1480 <<
"Multi_domain_functions::aux_setup_multi_domain_interaction(...)\n" 1481 <<
"but this deemed to be acceptable because \n" 1482 <<
"Multi_domain_functions::Accept_failed_locate_zeta_in_setup_multi_domain_interaction\n" 1493 <<
"Total CPU for location and creation of all external elements: " 1494 << t_locate-t_start << std::endl;
1498 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
1500 delete mesh_geom_obj_pt[i_mesh];
1507 #ifdef OOMPH_HAS_MPI 1513 bool comm_was_required=
false;
1514 oomph_info <<
"-------------------------------------------" << std::endl;
1515 oomph_info <<
"- Cumulative percentage of locate success -" << std::endl;
1516 oomph_info <<
"--- Spiral -- Found local -- Found else ---" << std::endl;
1517 for (
unsigned level=0; level<max_level_reached; level++)
1520 << percentage_coords_located_locally[level] <<
" -- " 1521 << percentage_coords_located_elsewhere[level] <<
" ---" 1525 if (percentage_coords_located_elsewhere[level]>
1526 percentage_coords_located_locally[level])
1528 comm_was_required=
true;
1531 oomph_info <<
"-------------------------------------------" << std::endl;
1543 oomph_info <<
"ASSESSMENT OF NEED FOR PARALLEL SEARCH: \n";
1544 oomph_info <<
"=======================================\n";
1546 if (comm_was_required)
1549 <<
"- Ring-based parallel search did successfully locate zetas on proc " 1550 << my_rank << std::endl;
1555 if (max_level_reached>1)
1558 <<
"- Ring-based parallel search did NOT locate zetas on proc" 1559 << my_rank << std::endl;
1564 <<
"- No ring-based parallel search was performed on proc" 1565 << my_rank << std::endl;
1571 unsigned overall_status=0;
1572 MPI_Allreduce(&status,&overall_status,1,
1573 MPI_UNSIGNED,MPI_MAX,
1577 if (overall_status==1)
1579 oomph_info <<
"- Ring-based, parallel search did succesfully\n";
1580 oomph_info <<
" locate zetas on at least one other proc, so it\n";
1586 if (max_level_reached>1)
1588 oomph_info <<
"- Ring-based, parallel search did NOT locate zetas\n";
1589 oomph_info <<
" on ANY other procs, i.e it was useless.\n";
1590 oomph_info <<
" --> We should really have done more local search\n";
1591 oomph_info <<
" by reducing number of bins, or doing more spirals\n";
1592 oomph_info <<
" in one go before initiating parallel search.\n";
1597 oomph_info <<
"- No ring-based, parallel search was performed\n";
1606 oomph_info <<
"------------------------------------------" << std::endl;
1608 <<
" elements, and " << std::endl
1610 <<
" external halo elements, " 1612 <<
" external haloed elements" 1616 oomph_info <<
"------------------------------------------" << std::endl;
1618 <<
" nodes, and " << std::endl
1620 <<
" external halo nodes, " 1622 <<
" external haloed nodes" 1624 oomph_info <<
"------------------------------------------" << std::endl;
1632 for (
int iproc=0;iproc<n_proc;iproc++)
1634 oomph_info <<
"----------------------------------------" << std::endl;
1635 oomph_info <<
"With process " << iproc <<
" there are " 1637 <<
" root halo elements, and " 1639 <<
" root haloed elements" << std::endl
1642 <<
" external halo elements, and " 1644 <<
" external haloed elements." << std::endl;
1646 oomph_info <<
"----------------------------------------" << std::endl;
1647 oomph_info <<
"With process " << iproc <<
" there are " 1649 <<
" halo nodes, and " 1651 <<
" haloed nodes" << std::endl
1654 <<
" external halo nodes, and " 1656 <<
" external haloed nodes." << std::endl;
1658 oomph_info <<
"-----------------------------------------" << std::endl
1668 oomph_info <<
"CPU for (one way) aux_setup_multi_domain_interaction: " 1669 << t_end-t_start << std::endl;
1674 #ifdef OOMPH_HAS_MPI 1681 template<
class EXT_ELEMENT>
1684 Problem* problem_pt,
const unsigned& interaction_index)
1687 int my_rank=comm_pt->my_rank();
1695 unsigned zeta_counter=0;
1699 unsigned counter_for_located_coord=0;
1705 unsigned n_mesh=mesh_pt.size();
1706 for (
unsigned i_mesh=0;i_mesh<n_mesh;i_mesh++)
1711 unsigned n_element=mesh_pt[i_mesh]->nelement();
1712 for (
unsigned e=0;
e<n_element;
e++)
1727 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
1765 add_external_halo_element_pt(loc_p, new_el_pt);
1771 int n_cont_inter_values=-1;
1772 if (dynamic_cast<RefineableElement*>(new_el_pt)!=0)
1775 (new_el_pt)->ncont_interpolated_values();
1779 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 1782 <<
" Using macro element node update " 1794 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 1797 <<
" Number of macro element " 1801 unsigned macro_el_num=
1805 macro_element_pt(macro_el_num));
1814 unsigned el_dim=q_el_pt->
dim();
1815 for (
unsigned i_dim=0;i_dim<el_dim;i_dim++)
1825 std::ostringstream error_stream;
1826 error_stream <<
"Using MacroElement node update\n" 1827 <<
"in a case with non-QElements\n" 1828 <<
"has not yet been implemented.\n";
1830 (error_stream.str(),
1831 OOMPH_CURRENT_FUNCTION,
1832 OOMPH_EXCEPTION_LOCATION);
1838 unsigned n_node=f_el_pt->
nnode();
1839 for (
unsigned j=0;j<n_node;j++)
1844 add_external_halo_node_to_storage<EXT_ELEMENT>
1845 (new_nod_pt,external_mesh_pt,loc_p,j,f_el_pt,
1846 n_cont_inter_values,problem_pt);
1851 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 1854 <<
" Index of existing external halo element " 1859 unsigned external_halo_el_index=
1864 external_halo_element_pt
1866 external_halo_el_index));
1872 "External halo element is not a FiniteElement\n",
1873 OOMPH_CURRENT_FUNCTION,
1874 OOMPH_EXCEPTION_LOCATION);
1882 unsigned el_dim=f_el_pt->
dim();
1884 for (
unsigned i=0;
i<el_dim;
i++)
1888 counter_for_located_coord++;
1894 external_element_local_coord(interaction_index,ipt)=s_located;
1923 template<
class EXT_ELEMENT>
1925 (
Node* &new_nod_pt,
Mesh*
const &external_mesh_pt,
unsigned& loc_p,
1927 int& n_cont_inter_values,
1932 node_index,new_el_pt,
1933 n_cont_inter_values,problem_pt);
1936 recursively_add_masters_of_external_halo_node_to_storage<EXT_ELEMENT>
1937 (new_nod_pt, external_mesh_pt, loc_p,
1938 node_index, new_el_pt,
1939 n_cont_inter_values,
1948 template<
class EXT_ELEMENT>
1951 (
Node* &new_nod_pt,
Mesh*
const &external_mesh_pt,
unsigned& loc_p,
1953 int& n_cont_inter_values,
1956 for (
int i_cont=-1;i_cont<n_cont_inter_values;i_cont++)
1958 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 1961 <<
" Boolean to indicate that continuously interpolated variable i_cont " 1962 << i_cont <<
" is hanging " 1968 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 1971 <<
" Number of master nodes " 1980 for (
unsigned m=0;m<n_master;m++)
1982 Node* master_nod_pt=0;
1984 add_external_halo_master_node_helper<EXT_ELEMENT>
1985 (master_nod_pt,new_nod_pt,external_mesh_pt,loc_p,
1986 n_cont_inter_values,problem_pt);
1994 recursively_add_masters_of_external_halo_node_to_storage<EXT_ELEMENT>
1995 (master_nod_pt, external_mesh_pt, loc_p,
1996 node_index, new_el_pt,
1997 n_cont_inter_values,
2009 template<
class EXT_ELEMENT>
2011 (
Node* &new_master_nod_pt,
Node* &new_nod_pt,
Mesh*
const &external_mesh_pt,
2012 unsigned& loc_p,
int& ncont_inter_values,
Problem* problem_pt)
2016 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2019 <<
" Boolean to trigger construction of new external halo master node " 2026 construct_new_external_halo_master_node_helper<EXT_ELEMENT>
2027 (new_master_nod_pt,new_nod_pt,loc_p,external_mesh_pt,problem_pt);
2031 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2034 <<
" index of existing external halo master node " 2048 template<
class EXT_ELEMENT>
2050 (
Node* &new_master_nod_pt,
Node* &nod_pt,
unsigned& loc_p,
2051 Mesh*
const &external_mesh_pt,
Problem* problem_pt)
2055 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2058 <<
" ndim for external halo master node " 2063 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2066 <<
" nposition type for external halo master node " 2072 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2075 <<
" nvalue for external halo master node " 2085 unsigned n_lag_type;
2086 if (solid_nod_pt!=0)
2088 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2091 <<
" nlagrdim for external halo master solid node " 2096 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2099 <<
" nlagrtype for external halo master solid node " 2113 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2116 <<
" Boolean: need timestepper " 2122 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2125 <<
" Index minus one of timestepper " 2146 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2149 <<
" Boolean for algebraic boundary node " 2158 if (time_stepper_pt!=0)
2161 (time_stepper_pt,n_dim,n_position_type,n_value);
2166 (n_dim,n_position_type,n_value);
2170 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2172 <<
" Number of boundaries the algebraic master node is on: " 2177 for (
unsigned i=0;
i<nb;
i++)
2180 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2182 <<
" Algebraic master node is on boundary " 2193 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2196 <<
"Number of additional values created by face element " 2197 <<
"for master node " 2211 if (bnew_master_nod_pt==0)
2214 "Failed to cast new node to boundary node\n",
2215 OOMPH_CURRENT_FUNCTION,
2216 OOMPH_EXCEPTION_LOCATION);
2219 if(bnew_master_nod_pt->
2220 index_of_first_value_assigned_by_face_element_pt()==0)
2222 bnew_master_nod_pt->
2223 index_of_first_value_assigned_by_face_element_pt()=
2224 new std::map<unsigned, unsigned>;
2229 std::map<unsigned, unsigned>* map_pt=
2233 for (
unsigned i=0;
i<n_entry;
i++)
2237 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2239 <<
" Key of map entry for master node" 2246 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2248 <<
" Value of map entry for master node" 2256 (*map_pt)[first]=second;
2264 if (time_stepper_pt!=0)
2267 (time_stepper_pt,n_dim,n_position_type,n_value);
2272 (n_dim,n_position_type,n_value);
2283 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2286 <<
" algebraic node update id for master node " 2297 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2300 <<
" algebraic node number of ref values for master node " 2309 ref_value.resize(n_ref_val);
2310 for (
unsigned i_ref=0;i_ref<n_ref_val;i_ref++)
2319 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2322 <<
" algebraic node number of geom objects for master node " 2333 geom_object_pt.resize(n_geom_obj);
2334 for (
unsigned i_geom=0;i_geom<n_geom_obj;i_geom++)
2336 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2339 <<
" algebraic node: " << i_geom <<
"-th out of " 2340 << n_geom_obj <<
"-th geom index " 2358 (update_id,alg_mesh_pt,geom_object_pt,ref_value);
2363 else if (macro_nod_pt!=0)
2368 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2370 <<
" Boolean for master algebraic node is boundary node " 2377 if (time_stepper_pt!=0)
2380 (time_stepper_pt,n_dim,n_position_type,n_value);
2385 (n_dim,n_position_type,n_value);
2390 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2393 <<
" Number of boundaries the macro element master node is on: " 2398 for (
unsigned i=0;
i<nb;
i++)
2401 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2403 <<
" Macro element master node is on boundary " 2413 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2416 <<
" Number of additional values created by face element " 2417 <<
"for macro element master node " 2431 if (bnew_master_nod_pt==0)
2434 "Failed to cast new node to boundary node\n",
2435 OOMPH_CURRENT_FUNCTION,
2436 OOMPH_EXCEPTION_LOCATION);
2439 if(bnew_master_nod_pt->
2440 index_of_first_value_assigned_by_face_element_pt()==0)
2442 bnew_master_nod_pt->
2443 index_of_first_value_assigned_by_face_element_pt()=
2444 new std::map<unsigned, unsigned>;
2449 std::map<unsigned, unsigned>* map_pt=
2453 for (
unsigned i=0;
i<n_entry;
i++)
2457 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2459 <<
" Key of map entry for macro element master node" 2466 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2468 <<
" Value of map entry for macro element master node" 2476 (*map_pt)[first]=second;
2484 if (time_stepper_pt!=0)
2487 (time_stepper_pt,n_dim,n_position_type,n_value);
2492 (n_dim,n_position_type,n_value);
2501 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2503 <<
" Bool: need new external halo element " 2513 loc_p,new_node_update_el_pt);
2516 new_node_update_f_el_pt =
2520 int n_cont_inter_values;
2521 if (dynamic_cast<RefineableElement*>(new_node_update_f_el_pt)!=0)
2524 (new_node_update_f_el_pt)->ncont_interpolated_values();
2528 n_cont_inter_values=-1;
2530 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2532 <<
" Bool: we have a macro element mesh " 2544 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2546 <<
" Number of macro element " 2550 unsigned macro_el_num=
2561 unsigned el_dim=q_el_pt->
dim();
2562 for (
unsigned i_dim=0;i_dim<el_dim;i_dim++)
2572 std::ostringstream error_stream;
2573 error_stream <<
"You are using a MacroElement node update\n" 2574 <<
"in a case with non-QElements. This has not\n" 2575 <<
"yet been implemented.\n";
2577 (error_stream.str(),
2578 OOMPH_CURRENT_FUNCTION,
2579 OOMPH_EXCEPTION_LOCATION);
2583 unsigned n_node=new_node_update_f_el_pt->
nnode();
2584 for (
unsigned j=0;j<n_node;j++)
2587 add_external_halo_node_to_storage<EXT_ELEMENT>
2588 (new_nod_pt,external_mesh_pt,loc_p,j,new_node_update_f_el_pt,
2589 n_cont_inter_values,problem_pt);
2595 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2597 <<
" Number of already existing external halo element " 2624 new_node_update_f_el_pt;
2627 unsigned local_node_index;
2628 unsigned n_node=new_node_update_f_el_pt->
nnode();
2629 for (
unsigned j=0;j<n_node;j++)
2631 if (macro_master_nod_pt==new_node_update_f_el_pt->
node_pt(j))
2640 (local_node_index,s_in_macro_node_update_element);
2643 (new_node_update_f_el_pt,s_in_macro_node_update_element,
2644 geom_object_vector_pt);
2646 else if (solid_nod_pt!=0)
2651 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2653 <<
" Bool master is a boundary (solid) node " 2660 if (time_stepper_pt!=0)
2663 (time_stepper_pt,n_lag_dim,n_lag_type,n_dim,n_position_type,n_value);
2668 (n_lag_dim,n_lag_type,n_dim,n_position_type,n_value);
2673 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2676 <<
" Number of boundaries the solid master node is on: " 2681 for (
unsigned i=0;
i<nb;
i++)
2684 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2686 <<
" Solid master node is on boundary " 2696 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2699 <<
" Number of additional values created by face element " 2700 <<
"for solid master node " 2714 if (bnew_master_nod_pt==0)
2717 "Failed to cast new node to boundary node\n",
2718 OOMPH_CURRENT_FUNCTION,
2719 OOMPH_EXCEPTION_LOCATION);
2722 if(bnew_master_nod_pt->
2723 index_of_first_value_assigned_by_face_element_pt()==0)
2725 bnew_master_nod_pt->
2726 index_of_first_value_assigned_by_face_element_pt()=
2727 new std::map<unsigned, unsigned>;
2732 std::map<unsigned, unsigned>* map_pt=
2736 for (
unsigned i=0;
i<n_entry;
i++)
2740 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2742 <<
" Key of map entry for solid master node" 2749 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2751 <<
" Value of map entry for solid master node" 2759 (*map_pt)[first]=second;
2767 if (time_stepper_pt!=0)
2770 (time_stepper_pt,n_lag_dim,n_lag_type,n_dim,n_position_type,n_value);
2775 (n_lag_dim,n_lag_type,n_dim,n_position_type,n_value);
2786 for (
unsigned i_val=0;i_val<n_solid_val;i_val++)
2788 for (
unsigned t=0;
t<n_prev;
t++)
2798 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2800 <<
" Bool node is on boundary " 2810 if (time_stepper_pt!=0)
2813 (time_stepper_pt,n_dim,n_position_type,n_value);
2818 (n_dim,n_position_type,n_value);
2822 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2824 <<
" Number of boundaries the master node is on: " 2829 for (
unsigned i=0;
i<nb;
i++)
2832 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2834 <<
" Master node is on boundary " 2845 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2848 <<
" Number of additional values created by face element " 2849 <<
"for master node " 2863 if (bnew_master_nod_pt==0)
2866 "Failed to cast new node to boundary node\n",
2867 OOMPH_CURRENT_FUNCTION,
2868 OOMPH_EXCEPTION_LOCATION);
2871 if(bnew_master_nod_pt->
2872 index_of_first_value_assigned_by_face_element_pt()==0)
2874 bnew_master_nod_pt->
2875 index_of_first_value_assigned_by_face_element_pt()=
2876 new std::map<unsigned, unsigned>;
2881 std::map<unsigned, unsigned>* map_pt=
2885 for (
unsigned i=0;
i<n_entry;
i++)
2889 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2891 <<
" Key of map entry for master node" 2898 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION 2900 <<
" Value of map entry for master node" 2908 (*map_pt)[first]=second;
2915 if (time_stepper_pt!=0)
2917 new_master_nod_pt=
new Node 2918 (time_stepper_pt,n_dim,n_position_type,n_value);
2922 new_master_nod_pt=
new Node(n_dim,n_position_type,n_value);
2933 for (
unsigned i_val=0;i_val<n_value;i_val++)
2935 for (
unsigned t=0;
t<n_prev;
t++)
2943 unsigned n_nod_dim=new_master_nod_pt->
ndim();
2944 for (
unsigned idim=0;idim<n_nod_dim;idim++)
2946 for (
unsigned t=0;
t<n_prev;
t++)
void initialise_external_element_storage()
Initialise storage for pointers to external elements and their local coordinates. This must be called...
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction") ...
A Generalised Element class.
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual) ...
void setup_bulk_elements_adjacent_to_face_mesh(Problem *problem_pt, Vector< unsigned > &boundary_in_bulk_mesh, Mesh *const &bulk_mesh_pt, Vector< Mesh *> &face_mesh_pt, const unsigned &interaction=0)
Identify the FaceElements (stored in the mesh pointed to by face_mesh_pt) that are adjacent to the bu...
unsigned nexternal_halo_element()
Total number of external halo elements in this Mesh.
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
void setup_multi_domain_interaction(Problem *problem_pt, Mesh *const &mesh_pt, Mesh *const &external_mesh_pt, const unsigned &interaction_index=0)
Function to set up the one-way multi-domain interaction for problems where the meshes pointed to by m...
void add_external_halo_node_pt(const unsigned &p, Node *&nod_pt)
Add external halo node whose non-halo (external) counterpart is held on processor p to the storage sc...
void aux_setup_multi_domain_interaction(Problem *problem_pt, Mesh *const &mesh_pt, Mesh *const &external_mesh_pt, const unsigned &interaction_index, Mesh *const &external_face_mesh_pt=0)
Auxiliary helper function.
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing...
static unsigned Default_nsample_points_generated_per_element
Default for "measure of" number of sample points per element.
virtual void update_node_update(AlgebraicNode *&node_pt)=0
Update the node update info for given node, following mesh adaptation. Must be implemented for every ...
void send_and_receive_located_info(int &iproc, Mesh *const &external_mesh_pt, Problem *problem_pt)
Helper function to send back any located information.
unsigned Counter_for_flat_packed_unsigneds
Counter used when processing vector of flat-packed unsigneds – this is really "private" data...
void add_node_update_info(const int &id, AlgebraicMesh *mesh_pt, const Vector< GeomObject *> &geom_object_pt, const Vector< double > &ref_value, const bool &called_from_constructor=false)
Add algebraic update information for node: What's the ID of the mesh update function (typically used ...
void get_dim_helper(Problem *problem_pt, Mesh *const &mesh_pt, Mesh *const &external_mesh_pt)
Helper function that computes the dimension of the elements within each of the specified meshes (and ...
GeneralisedElement *& external_halo_element_pt(const unsigned &p, const unsigned &e)
Access fct to the e-th external halo element in this Mesh whose non-halo counterpart is held on proce...
void recursively_add_masters_of_external_halo_node_to_storage(Node *&new_nod_pt, Mesh *const &external_mesh_pt, unsigned &loc_p, unsigned &node_index, FiniteElement *const &new_el_pt, int &n_cont_inter_values, Problem *problem_pt)
Recursively add masters of external halo nodes (and their masters, etc) based on information received...
unsigned nexternal_halo_node()
Total number of external halo nodes in this Mesh.
A general Finite Element class.
RefineableBinArray class.
bool Accept_failed_locate_zeta_in_setup_multi_domain_interaction
Boolean to indicate that failure in setup multi domain functions is acceptable; defaults to false...
bool Doc_full_stats
Boolean to indicate whether to output further info during setup_multi_domain_interaction() routines...
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s. Overloaded to get information from bulk...
CGAL-based SamplePointContainer.
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
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 nvalue() const
Return number of values stored in data object (incl pinned ones).
std::ofstream Doc_boundary_coordinate_file
Output file to document the boundary coordinate along the mesh boundary of the bulk mesh during call ...
unsigned nroot_haloed_element()
Total number of root haloed elements in this Mesh.
void set_master_node_pt(const unsigned &i, Node *const &master_node_pt, const double &weight)
Set the pointer to the i-th master node and its weight.
void set_boundary_number_in_bulk_mesh(const unsigned &b)
Set function for the boundary number in bulk mesh.
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
Vector< unsigned > Flat_packed_unsigneds
Vector of flat-packed unsigneds to be communicated with other processors – this is really "private" ...
GeomObject * geom_object_list_pt(const unsigned &i)
Access function to the ith GeomObject.
virtual unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction") ...
unsigned Dim
Dimension of zeta tuples (set by get_dim_helper) – needed because we store the scalar coordinates in...
unsigned long nelement() const
Return number of elements in the mesh.
bool Doc_timings
Boolean to indicate whether to doc timings or not.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Base class for Qelements.
virtual void set_macro_elem_pt(MacroElement *macro_elem_pt)
Set pointer to macro element – can be overloaded in derived elements to perform additional tasks...
double & s_macro_ur(const unsigned &i)
Access fct to the i-th coordinate of the element's "upper right" vertex in the associated MacroElemen...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
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.
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
void add_external_halo_node_helper(Node *&new_nod_pt, Mesh *const &mesh_pt, unsigned &loc_p, unsigned &node_index, FiniteElement *const &new_el_pt, int &n_cont_inter_values, unsigned &counter_for_recv_unsigneds, Vector< unsigned > &recv_unsigneds, unsigned &counter_for_recv_doubles, Vector< double > &recv_doubles)
Helper functiono to add external halo node that is not a master.
unsigned nhalo_node()
Total number of halo nodes in this Mesh.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Vector< double > Flat_packed_located_coordinates
Vector of flat-packed local coordinates for zeta tuples that have been located.
unsigned & current_max_spiral_level()
Access function to current max. spiral level.
void construct_new_external_halo_master_node_helper(Node *&new_master_nod_pt, Node *&nod_pt, unsigned &loc_p, Mesh *const &external_mesh_pt, Problem *problem_pt)
Helper function which constructs a new external halo master node with the information sent from the h...
Base class for all bin arrays.
unsigned max_bin_dimension() const
Max. bin dimension (number of bins in coordinate directions)
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
A template Class for BoundaryNodes; that is Nodes that MAY live on the boundary of a Mesh...
void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
Calculate the interpolated value of zeta, the intrinsic coordinate of the element when viewed as a co...
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.
unsigned nexternal_haloed_node()
Total number of external haloed nodes in this Mesh.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
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...
Domain *& macro_domain_pt()
Broken assignment operator.
void clean_up()
Helper function that clears all the intermediate information used during the external storage creatio...
virtual void write_tecplot_zone_footer(std::ostream &outfile, const unsigned &nplot) const
Add tecplot zone "footer" to output stream (when plotting nplot points in each "coordinate direction"...
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
unsigned n_spiral_chunk() const
Number of spirals to be searched in one go const version.
TimeStepper *& time_stepper_pt()
Access function for the pointer to the first (presumably only) timestepper.
void send_and_receive_missing_zetas(Problem *problem_pt)
Helper function to send any "missing" zeta coordinates to the next process and receive any coordinate...
FiniteElement *& node_update_element_pt()
Pointer to finite element that performs the update by referring to its macro-element representation (...
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 nhaloed_node()
Total number of haloed nodes in this Mesh.
Vector< double > Flat_packed_doubles
Vector of flat-packed doubles to be communicated with other processors.
Class that contains data for hanging nodes.
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
unsigned long nnode() const
Return number of nodes in the mesh.
bool Use_bulk_element_as_external
Boolean to indicate when to use the bulk element as the external element. Defaults to false...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
void add_external_halo_master_node_helper(Node *&new_master_nod_pt, Node *&new_nod_pt, Mesh *const &external_mesh_pt, unsigned &loc_p, int &n_cont_inter_values, Problem *problem_pt)
Helper function to add external halo node that is a master.
void set_node_update_info(FiniteElement *node_update_element_pt, const Vector< double > &s_in_node_update_element, const Vector< GeomObject *> &geom_object_pt)
Set node update information for node: Pass the pointer to the element that performs the update operat...
void set_hanging_pt(HangInfo *const &hang_pt, const int &i)
Set the hanging data for the i-th value. (hang_pt=0 to make non-hanging)
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
double & s_macro_ll(const unsigned &i)
Access fct to the i-th coordinate of the element's "lower left" vertex in the associated MacroElement...
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.
Vector< int > Proc_id_plus_one_of_external_element
Proc_id_plus_one_of_external_element[i] contains the processor id (plus one) of the processor on whic...
NonRefineableBinArray class.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
Vector< Vector< unsigned > > External_element_located
Lookup scheme for whether a local element's integration point has had an external element assigned to...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point...
bool Doc_stats
Boolean to indicate whether to output basic info during setup_multi_domain_interaction() routines...
A class to do comparison of the elements by lexicographic ordering, based on the boundary coordinates...
bool problem_has_been_distributed()
Access to Problem_has_been_distributed flag.
void create_external_halo_elements(int &iproc, const Vector< Mesh *> &mesh_pt, Mesh *const &external_mesh_pt, Problem *problem_pt, const unsigned &interaction_index)
Create external (halo) elements on the loop process based on the information received from each locat...
virtual void output_bins(std::ofstream &outfile)=0
Output bins (boundaries and number of sample points in them)
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.
unsigned & current_min_spiral_level()
Access function to current min. spiral level.
void add_external_halo_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add external halo element whose non-halo counterpart is held on processor p to this Mesh...
Vector< double > Flat_packed_zetas_not_found_locally
Vector of flat-packed zeta coordinates for which the external element could not be found during curre...
unsigned nnode() const
Return the number of nodes.
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.
void add_external_halo_node_to_storage(Node *&new_nod_pt, Mesh *const &external_mesh_pt, unsigned &loc_p, unsigned &node_index, FiniteElement *const &new_el_pt, int &n_cont_inter_values, Problem *problem_pt)
Helper function to add external halo nodes, including any masters, based on information received from...
Vector< unsigned > Located_element_status
Vector to indicate (to another processor) whether a located element (that will have to represented as...
Vector< GeomObject * > geom_object_vector_pt()
Access function to the vector of GeomObject.
void locate_zeta_for_missing_coordinates(int &iproc, Mesh *const &external_mesh_pt, Problem *problem_pt, Vector< MeshAsGeomObject *> &mesh_geom_obj_pt)
Locate zeta for current set of missing coordinates; vector-based version.
unsigned Counter_for_flat_packed_doubles
Counter used when processing vector of flat-packed doubles – this is really "private" data...
void locate_zeta_for_local_coordinates(const Vector< Mesh *> &mesh_pt, Mesh *const &external_mesh_pt, Vector< MeshAsGeomObject *> &mesh_geom_obj_pt, const unsigned &interaction_index)
Helper function to locate "local" zeta coordinates This is the vector-based version which operates si...
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
void setup_multi_domain_interactions(Problem *problem_pt, Mesh *const &first_mesh_pt, Mesh *const &second_mesh_pt, const unsigned &first_interaction=0, const unsigned &second_interaction=0)
Set up the two-way multi-domain interactions for the problem pointed to by problem_pt. Use this for cases where first_mesh_pt and second_mesh_pt occupy the same physical space and are populated by ELEMENT_0 and ELEMENT_1 respectively, and are combined to solve a single problem. The elements in two meshes interact both ways the elements in each mesh act as "external elements" for the elements in the "other" mesh. The interaction indices allow the specification of which interaction we're setting up in the two meshes. They default to zero, which is appropriate if there's only a single interaction.